From f773ec03ce334298742df7f3108fc0d402646d22 Mon Sep 17 00:00:00 2001 From: Marcel van Lohuizen Date: Thu, 5 May 2016 15:32:54 -0700 Subject: [PATCH] currency: add Query for matching units to regions Change-Id: I47068cb2adbe13c8f86d34a60978450e51a52561 Reviewed-on: https://go-review.googlesource.com/22834 Reviewed-by: Nigel Tao Run-TryBot: Marcel van Lohuizen TryBot-Result: Gobot Gobot --- currency/common.go | 24 +- currency/example_test.go | 27 +++ currency/gen.go | 41 ++++ currency/gen_common.go | 24 +- currency/query.go | 152 ++++++++++++ currency/query_test.go | 107 +++++++++ currency/tables.go | 504 ++++++++++++++++++++++++++++++++++++++- currency/tables_test.go | 23 ++ 8 files changed, 899 insertions(+), 3 deletions(-) create mode 100644 currency/example_test.go create mode 100644 currency/query.go create mode 100644 currency/query_test.go diff --git a/currency/common.go b/currency/common.go index 4a7d9a5..0c567f9 100644 --- a/currency/common.go +++ b/currency/common.go @@ -2,13 +2,19 @@ package currency -import "golang.org/x/text/language" +import ( + "time" + + "golang.org/x/text/language" +) // This file contains code common to gen.go and the package code. const ( cashShift = 3 roundMask = 0x7 + + nonTenderBit = 0x8000 ) // currencyInfo contains information about a currency. @@ -42,3 +48,19 @@ func regionToCode(r language.Region) uint16 { } return 0 } + +func toDate(t time.Time) uint32 { + y := t.Year() + if y == 1 { + return 0 + } + date := uint32(y) << 4 + date |= uint32(t.Month()) + date <<= 5 + date |= uint32(t.Day()) + return date +} + +func fromDate(date uint32) time.Time { + return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC) +} diff --git a/currency/example_test.go b/currency/example_test.go new file mode 100644 index 0000000..f7984aa --- /dev/null +++ b/currency/example_test.go @@ -0,0 +1,27 @@ +// 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 currency_test + +import ( + "fmt" + "time" + + "golang.org/x/text/currency" +) + +func ExampleQuery() { + t1799, _ := time.Parse("2006-01-02", "1799-01-01") + for it := currency.Query(currency.Date(t1799)); it.Next(); { + from := "" + if t, ok := it.From(); ok { + from = t.Format("2006-01-01") + } + fmt.Printf("%v is used in %v since: %v\n", it.Unit(), it.Region(), from) + } + // Output: + // GBP is used in GB since: 1694-07-07 + // GIP is used in GI since: 1713-01-01 + // USD is used in US since: 1792-01-01 +} diff --git a/currency/gen.go b/currency/gen.go index 276cfed..0952d41 100644 --- a/currency/gen.go +++ b/currency/gen.go @@ -16,6 +16,7 @@ import ( "sort" "strconv" "strings" + "time" "golang.org/x/text/internal" "golang.org/x/text/internal/gen" @@ -170,8 +171,48 @@ func (b *builder) genCurrencies(w *gen.CodeWriter, data *cldr.SupplementalData) w.WriteType(toCurrency{}) w.WriteVar("regionToCurrency", regionToCurrency) + + // Create a table that maps regions to currencies. + regionData := []regionInfo{} + + for _, reg := range data.CurrencyData.Region { + if len(reg.Iso3166) != 2 { + log.Fatalf("Unexpected group %q in region data", reg.Iso3166) + } + for _, cur := range reg.Currency { + from, _ := time.Parse("2006-01-02", cur.From) + to, _ := time.Parse("2006-01-02", cur.To) + code := uint16(b.currencies.Index([]byte(cur.Iso4217))) + if cur.Tender == "false" { + code |= nonTenderBit + } + regionData = append(regionData, regionInfo{ + region: regionToCode(language.MustParseRegion(reg.Iso3166)), + code: code, + from: toDate(from), + to: toDate(to), + }) + } + } + sort.Stable(byRegionCode(regionData)) + + w.WriteType(regionInfo{}) + w.WriteVar("regionData", regionData) } +type regionInfo struct { + region uint16 + code uint16 // 0x8000 not legal tender + from uint32 + to uint32 +} + +type byRegionCode []regionInfo + +func (a byRegionCode) Len() int { return len(a) } +func (a byRegionCode) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byRegionCode) Less(i, j int) bool { return a[i].region < a[j].region } + type toCurrency struct { region uint16 code uint16 diff --git a/currency/gen_common.go b/currency/gen_common.go index 8588953..e6748da 100644 --- a/currency/gen_common.go +++ b/currency/gen_common.go @@ -6,13 +6,19 @@ package main -import "golang.org/x/text/language" +import ( + "time" + + "golang.org/x/text/language" +) // This file contains code common to gen.go and the package code. const ( cashShift = 3 roundMask = 0x7 + + nonTenderBit = 0x8000 ) // currencyInfo contains information about a currency. @@ -46,3 +52,19 @@ func regionToCode(r language.Region) uint16 { } return 0 } + +func toDate(t time.Time) uint32 { + y := t.Year() + if y == 1 { + return 0 + } + date := uint32(y) << 4 + date |= uint32(t.Month()) + date <<= 5 + date |= uint32(t.Day()) + return date +} + +func fromDate(date uint32) time.Time { + return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC) +} diff --git a/currency/query.go b/currency/query.go new file mode 100644 index 0000000..7bf9430 --- /dev/null +++ b/currency/query.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. + +package currency + +import ( + "sort" + "time" + + "golang.org/x/text/language" +) + +// QueryIter represents a set of Units. The default set includes all Units that +// are currently in use as legal tender in any Region. +type QueryIter interface { + // Next returns true if there is a next element available. + // It must be called before any of the other methods are called. + Next() bool + + // Unit returns the unit of the current iteration. + Unit() Unit + + // Region returns the Region for the current iteration. + Region() language.Region + + // From returns the date from which the unit was used in the region. + // It returns false if this date is unknown. + From() (time.Time, bool) + + // To returns the date up till which the unit was used in the region. + // It returns false if this date is unknown or if the unit is still in use. + To() (time.Time, bool) + + // IsTender reports whether the unit is a legal tender in the region during + // the specified date range. + IsTender() bool +} + +// Query represents a set of Units. The default set includes all Units that are +// currently in use as legal tender in any Region. +func Query(options ...QueryOption) QueryIter { + it := &iter{ + end: len(regionData), + date: 0xFFFFFFFF, + } + for _, fn := range options { + fn(it) + } + return it +} + +// NonTender returns a new query that also includes matching Units that are not +// legal tender. +var NonTender QueryOption = nonTender + +func nonTender(i *iter) { + i.nonTender = true +} + +// Historical selects the units for all dates. +var Historical QueryOption = historical + +func historical(i *iter) { + i.date = hist +} + +// A QueryOption can be used to change the set of unit information returned by +// a query. +type QueryOption func(*iter) + +// Date queries the units that were in use at the given point in history. +func Date(t time.Time) QueryOption { + d := toDate(t) + return func(i *iter) { + i.date = d + } +} + +// Region limits the query to only return entries for the given region. +func Region(r language.Region) QueryOption { + p, end := len(regionData), len(regionData) + x := regionToCode(r) + i := sort.Search(len(regionData), func(i int) bool { + return regionData[i].region >= x + }) + if i < len(regionData) && regionData[i].region == x { + p = i + for i++; i < len(regionData) && regionData[i].region == x; i++ { + } + end = i + } + return func(i *iter) { + i.p, i.end = p, end + } +} + +const ( + hist = 0x00 + now = 0xFFFFFFFF +) + +type iter struct { + *regionInfo + p, end int + date uint32 + nonTender bool +} + +func (i *iter) Next() bool { + for ; i.p < i.end; i.p++ { + i.regionInfo = ®ionData[i.p] + if !i.nonTender && !i.IsTender() { + continue + } + if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) { + i.p++ + return true + } + } + return false +} + +func (r *regionInfo) Region() language.Region { + // TODO: this could be much faster. + var buf [2]byte + buf[0] = uint8(r.region >> 8) + buf[1] = uint8(r.region) + return language.MustParseRegion(string(buf[:])) +} + +func (r *regionInfo) Unit() Unit { + return Unit{r.code &^ nonTenderBit} +} + +func (r *regionInfo) IsTender() bool { + return r.code&nonTenderBit == 0 +} + +func (r *regionInfo) From() (time.Time, bool) { + if r.from == 0 { + return time.Time{}, false + } + return fromDate(r.from), true +} + +func (r *regionInfo) To() (time.Time, bool) { + if r.to == 0 { + return time.Time{}, false + } + return fromDate(r.to), true +} diff --git a/currency/query_test.go b/currency/query_test.go new file mode 100644 index 0000000..6caea9d --- /dev/null +++ b/currency/query_test.go @@ -0,0 +1,107 @@ +// 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 currency + +import ( + "testing" + "time" + + "golang.org/x/text/language" +) + +func TestQuery(t *testing.T) { + r := func(region string) language.Region { + return language.MustParseRegion(region) + } + t1800, _ := time.Parse("2006-01-02", "1800-01-01") + type result struct { + region language.Region + unit Unit + isTender bool + from, to string + } + testCases := []struct { + name string + opts []QueryOption + results []result + }{{ + name: "XA", + opts: []QueryOption{Region(r("XA"))}, + results: []result{}, + }, { + name: "AC", + opts: []QueryOption{Region(r("AC"))}, + results: []result{ + {r("AC"), MustParseISO("SHP"), true, "1976-01-01", ""}, + }, + }, { + name: "US", + opts: []QueryOption{Region(r("US"))}, + results: []result{ + {r("US"), MustParseISO("USD"), true, "1792-01-01", ""}, + }, + }, { + name: "US-hist", + opts: []QueryOption{Region(r("US")), Historical}, + results: []result{ + {r("US"), MustParseISO("USD"), true, "1792-01-01", ""}, + }, + }, { + name: "US-non-tender", + opts: []QueryOption{Region(r("US")), NonTender}, + results: []result{ + {r("US"), MustParseISO("USD"), true, "1792-01-01", ""}, + {r("US"), MustParseISO("USN"), false, "", ""}, + }, + }, { + name: "US-historical+non-tender", + opts: []QueryOption{Region(r("US")), Historical, NonTender}, + results: []result{ + {r("US"), MustParseISO("USD"), true, "1792-01-01", ""}, + {r("US"), MustParseISO("USN"), false, "", ""}, + {r("US"), MustParseISO("USS"), false, "", "2014-03-01"}, + }, + }, { + name: "1800", + opts: []QueryOption{Date(t1800)}, + results: []result{ + {r("CH"), MustParseISO("CHF"), true, "1799-03-17", ""}, + {r("GB"), MustParseISO("GBP"), true, "1694-07-27", ""}, + {r("GI"), MustParseISO("GIP"), true, "1713-01-01", ""}, + // The date for IE and PR seem wrong, so these may be updated at + // some point causing the tests to fail. + {r("IE"), MustParseISO("GBP"), true, "1800-01-01", "1922-01-01"}, + {r("PR"), MustParseISO("ESP"), true, "1800-01-01", "1898-12-10"}, + {r("US"), MustParseISO("USD"), true, "1792-01-01", ""}, + }, + }} + for _, tc := range testCases { + n := 0 + for it := Query(tc.opts...); it.Next(); n++ { + if n < len(tc.results) { + got := result{ + it.Region(), + it.Unit(), + it.IsTender(), + getTime(it.From()), + getTime(it.To()), + } + if got != tc.results[n] { + t.Errorf("%s:%d: got %v; want %v", tc.name, n, got, tc.results[n]) + } + } + } + if n != len(tc.results) { + t.Errorf("%s: unexpected number of results: got %d; want %d", tc.name, n, len(tc.results)) + } + } +} + +func getTime(t time.Time, ok bool) string { + if !ok { + return "" + } + return t.Format("2006-01-02") +} diff --git a/currency/tables.go b/currency/tables.go index b039ac3..64a8a0f 100644 --- a/currency/tables.go +++ b/currency/tables.go @@ -341,6 +341,508 @@ var regionToCurrency = []toCurrency{ // 255 elements 254: {region: 0x5a57, code: 0xf9}, } // Size: 1044 bytes +type regionInfo struct { + region uint16 + code uint16 + from uint32 + to uint32 +} + +var regionData = []regionInfo{ // 492 elements + 0: {region: 0x4143, code: 0xdb, from: 0xf7021, to: 0x0}, + 1: {region: 0x4144, code: 0x5c, from: 0xf9e21, to: 0x0}, + 2: {region: 0x4144, code: 0x5a, from: 0xea221, to: 0xfa45c}, + 3: {region: 0x4144, code: 0x60, from: 0xf5021, to: 0xfa451}, + 4: {region: 0x4144, code: 0x1, from: 0xf2021, to: 0xfa39f}, + 5: {region: 0x4145, code: 0x2, from: 0xf6ab3, to: 0x0}, + 6: {region: 0x4146, code: 0x4, from: 0xfa547, to: 0x0}, + 7: {region: 0x4146, code: 0x3, from: 0xf0e6e, to: 0xfa59f}, + 8: {region: 0x4147, code: 0x10d, from: 0xf5b46, to: 0x0}, + 9: {region: 0x4149, code: 0x10d, from: 0xf5b46, to: 0x0}, + 10: {region: 0x414c, code: 0x6, from: 0xf5b10, to: 0x0}, + 11: {region: 0x414c, code: 0x5, from: 0xf3561, to: 0xf5b10}, + 12: {region: 0x414d, code: 0x7, from: 0xf9376, to: 0x0}, + 13: {region: 0x414d, code: 0xd1, from: 0xf8f99, to: 0xf9376}, + 14: {region: 0x414d, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 15: {region: 0x414f, code: 0x9, from: 0xf9f8d, to: 0x0}, + 16: {region: 0x414f, code: 0xc, from: 0xf96e1, to: 0xfa041}, + 17: {region: 0x414f, code: 0xb, from: 0xf8d39, to: 0xfa041}, + 18: {region: 0x414f, code: 0xa, from: 0xf7228, to: 0xf8e61}, + 19: {region: 0x4151, code: 0x811a, from: 0x0, to: 0x0}, + 20: {region: 0x4152, code: 0x11, from: 0xf9021, to: 0x0}, + 21: {region: 0x4152, code: 0xd, from: 0xf82ce, to: 0xf9021}, + 22: {region: 0x4152, code: 0x10, from: 0xf7ec1, to: 0xf82ce}, + 23: {region: 0x4152, code: 0xe, from: 0xf6421, to: 0xf7ec1}, + 24: {region: 0x4152, code: 0xf, from: 0xeb365, to: 0xf6421}, + 25: {region: 0x4153, code: 0xf9, from: 0xee0f0, to: 0x0}, + 26: {region: 0x4154, code: 0x5c, from: 0xf9e21, to: 0x0}, + 27: {region: 0x4154, code: 0x12, from: 0xf3784, to: 0xfa45c}, + 28: {region: 0x4155, code: 0x13, from: 0xf5c4e, to: 0x0}, + 29: {region: 0x4157, code: 0x14, from: 0xf8421, to: 0x0}, + 30: {region: 0x4157, code: 0x8, from: 0xf28aa, to: 0xf8421}, + 31: {region: 0x4158, code: 0x5c, from: 0xf9e21, to: 0x0}, + 32: {region: 0x415a, code: 0x16, from: 0xfac21, to: 0x0}, + 33: {region: 0x415a, code: 0x15, from: 0xf9376, to: 0xfad9f}, + 34: {region: 0x415a, code: 0xd1, from: 0xf8f99, to: 0xf9421}, + 35: {region: 0x415a, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 36: {region: 0x4241, code: 0x18, from: 0xf9621, to: 0x0}, + 37: {region: 0x4241, code: 0x19, from: 0xf950f, to: 0xf9ae1}, + 38: {region: 0x4241, code: 0x17, from: 0xf90e1, to: 0xf950f}, + 39: {region: 0x4241, code: 0x120, from: 0xf90e1, to: 0xf9341}, + 40: {region: 0x4241, code: 0x11f, from: 0xf8c21, to: 0xf90e1}, + 41: {region: 0x4241, code: 0x11d, from: 0xf5c21, to: 0xf8c21}, + 42: {region: 0x4242, code: 0x1a, from: 0xf6b83, to: 0x0}, + 43: {region: 0x4242, code: 0x10d, from: 0xf5b46, to: 0xf6b83}, + 44: {region: 0x4244, code: 0x1b, from: 0xf6821, to: 0x0}, + 45: {region: 0x4244, code: 0xc6, from: 0xf3881, to: 0xf6821}, + 46: {region: 0x4244, code: 0x7b, from: 0xe5711, to: 0xf3881}, + 47: {region: 0x4245, code: 0x5c, from: 0xf9e21, to: 0x0}, + 48: {region: 0x4245, code: 0x1d, from: 0xe4e47, to: 0xfa45c}, + 49: {region: 0x4245, code: 0xbb, from: 0xe318f, to: 0xe4e47}, + 50: {region: 0x4245, code: 0x801e, from: 0xf6421, to: 0xf8c65}, + 51: {region: 0x4245, code: 0x801c, from: 0xf6421, to: 0xf8c65}, + 52: {region: 0x4246, code: 0x112, from: 0xf8104, to: 0x0}, + 53: {region: 0x4247, code: 0x21, from: 0xf9ee5, to: 0x0}, + 54: {region: 0x4247, code: 0x1f, from: 0xf5421, to: 0xf9ee5}, + 55: {region: 0x4247, code: 0x20, from: 0xf40ac, to: 0xf5421}, + 56: {region: 0x4247, code: 0x22, from: 0xeaee8, to: 0xf40ac}, + 57: {region: 0x4248, code: 0x23, from: 0xf5b50, to: 0x0}, + 58: {region: 0x4249, code: 0x24, from: 0xf58b3, to: 0x0}, + 59: {region: 0x424a, code: 0x112, from: 0xf6f7e, to: 0x0}, + 60: {region: 0x424c, code: 0x5c, from: 0xf9e21, to: 0x0}, + 61: {region: 0x424c, code: 0x60, from: 0xf5021, to: 0xfa451}, + 62: {region: 0x424d, code: 0x25, from: 0xf6446, to: 0x0}, + 63: {region: 0x424e, code: 0x26, from: 0xf5ecc, to: 0x0}, + 64: {region: 0x424e, code: 0xb3, from: 0xf5730, to: 0xf5ecc}, + 65: {region: 0x424f, code: 0x27, from: 0xf8621, to: 0x0}, + 66: {region: 0x424f, code: 0x29, from: 0xf5621, to: 0xf859f}, + 67: {region: 0x424f, code: 0x28, from: 0xe8ed7, to: 0xf5621}, + 68: {region: 0x424f, code: 0x802a, from: 0x0, to: 0x0}, + 69: {region: 0x4251, code: 0xf9, from: 0xfb621, to: 0x0}, + 70: {region: 0x4251, code: 0x8, from: 0xfb54a, to: 0xfb621}, + 71: {region: 0x4252, code: 0x2e, from: 0xf94e1, to: 0x0}, + 72: {region: 0x4252, code: 0x30, from: 0xf9301, to: 0xf94e1}, + 73: {region: 0x4252, code: 0x2d, from: 0xf8c70, to: 0xf9301}, + 74: {region: 0x4252, code: 0x2f, from: 0xf8a2f, to: 0xf8c70}, + 75: {region: 0x4252, code: 0x2c, from: 0xf845c, to: 0xf8a2f}, + 76: {region: 0x4252, code: 0x2b, from: 0xf5e4d, to: 0xf845c}, + 77: {region: 0x4252, code: 0x31, from: 0xf2d61, to: 0xf5e4d}, + 78: {region: 0x4253, code: 0x32, from: 0xf5cb9, to: 0x0}, + 79: {region: 0x4254, code: 0x33, from: 0xf6c90, to: 0x0}, + 80: {region: 0x4254, code: 0x7b, from: 0xee621, to: 0x0}, + 81: {region: 0x4255, code: 0x34, from: 0xf40e1, to: 0xf8ad2}, + 82: {region: 0x4256, code: 0xbc, from: 0xee2c7, to: 0x0}, + 83: {region: 0x4257, code: 0x35, from: 0xf7117, to: 0x0}, + 84: {region: 0x4257, code: 0x122, from: 0xf524e, to: 0xf7117}, + 85: {region: 0x4259, code: 0x37, from: 0xfa021, to: 0x0}, + 86: {region: 0x4259, code: 0x36, from: 0xf9501, to: 0xfa19f}, + 87: {region: 0x4259, code: 0xd1, from: 0xf8f99, to: 0xf9568}, + 88: {region: 0x4259, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 89: {region: 0x425a, code: 0x38, from: 0xf6c21, to: 0x0}, + 90: {region: 0x4341, code: 0x39, from: 0xe8421, to: 0x0}, + 91: {region: 0x4343, code: 0x13, from: 0xf5c4e, to: 0x0}, + 92: {region: 0x4344, code: 0x3a, from: 0xf9ce1, to: 0x0}, + 93: {region: 0x4344, code: 0x125, from: 0xf9361, to: 0xf9ce1}, + 94: {region: 0x4344, code: 0x126, from: 0xf675b, to: 0xf9361}, + 95: {region: 0x4346, code: 0x106, from: 0xf9221, to: 0x0}, + 96: {region: 0x4347, code: 0x106, from: 0xf9221, to: 0x0}, + 97: {region: 0x4348, code: 0x3c, from: 0xe0e71, to: 0x0}, + 98: {region: 0x4348, code: 0x803b, from: 0x0, to: 0x0}, + 99: {region: 0x4348, code: 0x803d, from: 0x0, to: 0x0}, + 100: {region: 0x4349, code: 0x112, from: 0xf4d84, to: 0x0}, + 101: {region: 0x434b, code: 0xbe, from: 0xf5eea, to: 0x0}, + 102: {region: 0x434c, code: 0x40, from: 0xf6f3d, to: 0x0}, + 103: {region: 0x434c, code: 0x3e, from: 0xf5021, to: 0xf6f3d}, + 104: {region: 0x434c, code: 0x803f, from: 0x0, to: 0x0}, + 105: {region: 0x434d, code: 0x106, from: 0xf6a81, to: 0x0}, + 106: {region: 0x434e, code: 0x42, from: 0xf4261, to: 0x0}, + 107: {region: 0x434e, code: 0x8041, from: 0xf7621, to: 0xf9d9f}, + 108: {region: 0x434f, code: 0x43, from: 0xee221, to: 0x0}, + 109: {region: 0x434f, code: 0x8044, from: 0x0, to: 0x0}, + 110: {region: 0x4350, code: 0x811a, from: 0x0, to: 0x0}, + 111: {region: 0x4352, code: 0x45, from: 0xed15a, to: 0x0}, + 112: {region: 0x4353, code: 0x46, from: 0xfa4af, to: 0xfacc3}, + 113: {region: 0x4353, code: 0x5c, from: 0xfa644, to: 0xfacc3}, + 114: {region: 0x4353, code: 0x11e, from: 0xf9438, to: 0xfa4af}, + 115: {region: 0x4355, code: 0x49, from: 0xe8621, to: 0x0}, + 116: {region: 0x4355, code: 0x48, from: 0xf9421, to: 0x0}, + 117: {region: 0x4355, code: 0xf9, from: 0xed621, to: 0xf4e21}, + 118: {region: 0x4356, code: 0x4a, from: 0xef421, to: 0x0}, + 119: {region: 0x4356, code: 0xc9, from: 0xeeeb6, to: 0xf6ee5}, + 120: {region: 0x4357, code: 0x8, from: 0xfb54a, to: 0x0}, + 121: {region: 0x4358, code: 0x13, from: 0xf5c4e, to: 0x0}, + 122: {region: 0x4359, code: 0x5c, from: 0xfb021, to: 0x0}, + 123: {region: 0x4359, code: 0x4b, from: 0xef52a, to: 0xfb03f}, + 124: {region: 0x435a, code: 0x4c, from: 0xf9221, to: 0x0}, + 125: {region: 0x435a, code: 0x47, from: 0xf42c1, to: 0xf9261}, + 126: {region: 0x4444, code: 0x4d, from: 0xf38f4, to: 0xf8d42}, + 127: {region: 0x4445, code: 0x5c, from: 0xf9e21, to: 0x0}, + 128: {region: 0x4445, code: 0x4e, from: 0xf38d4, to: 0xfa45c}, + 129: {region: 0x4447, code: 0xf9, from: 0xf5b68, to: 0x0}, + 130: {region: 0x444a, code: 0x4f, from: 0xf72db, to: 0x0}, + 131: {region: 0x444b, code: 0x50, from: 0xea2bb, to: 0x0}, + 132: {region: 0x444d, code: 0x10d, from: 0xf5b46, to: 0x0}, + 133: {region: 0x444f, code: 0x51, from: 0xf3741, to: 0x0}, + 134: {region: 0x444f, code: 0xf9, from: 0xee2d5, to: 0xf3741}, + 135: {region: 0x445a, code: 0x52, from: 0xf5881, to: 0x0}, + 136: {region: 0x4541, code: 0x5c, from: 0xf9e21, to: 0x0}, + 137: {region: 0x4543, code: 0xf9, from: 0xfa142, to: 0x0}, + 138: {region: 0x4543, code: 0x53, from: 0xeb881, to: 0xfa142}, + 139: {region: 0x4543, code: 0x8054, from: 0xf92b7, to: 0xfa029}, + 140: {region: 0x4545, code: 0x5c, from: 0xfb621, to: 0x0}, + 141: {region: 0x4545, code: 0x55, from: 0xf90d5, to: 0xfb59f}, + 142: {region: 0x4545, code: 0xe4, from: 0xf5221, to: 0xf90d4}, + 143: {region: 0x4547, code: 0x56, from: 0xebb6e, to: 0x0}, + 144: {region: 0x4548, code: 0x9c, from: 0xf705a, to: 0x0}, + 145: {region: 0x4552, code: 0x57, from: 0xf9b68, to: 0x0}, + 146: {region: 0x4552, code: 0x5b, from: 0xf92b8, to: 0xf9b68}, + 147: {region: 0x4553, code: 0x5c, from: 0xf9e21, to: 0x0}, + 148: {region: 0x4553, code: 0x5a, from: 0xe9953, to: 0xfa45c}, + 149: {region: 0x4553, code: 0x8058, from: 0xf7421, to: 0xf7b9f}, + 150: {region: 0x4553, code: 0x8059, from: 0xf6e21, to: 0xf959f}, + 151: {region: 0x4554, code: 0x5b, from: 0xf712f, to: 0x0}, + 152: {region: 0x4555, code: 0x5c, from: 0xf9e21, to: 0x0}, + 153: {region: 0x4555, code: 0x810f, from: 0xf7621, to: 0xf9d9f}, + 154: {region: 0x4649, code: 0x5c, from: 0xf9e21, to: 0x0}, + 155: {region: 0x4649, code: 0x5d, from: 0xf5621, to: 0xfa45c}, + 156: {region: 0x464a, code: 0x5e, from: 0xf622d, to: 0x0}, + 157: {region: 0x464b, code: 0x5f, from: 0xeda21, to: 0x0}, + 158: {region: 0x464d, code: 0xf9, from: 0xf3021, to: 0x0}, + 159: {region: 0x464d, code: 0x83, from: 0xef543, to: 0xf3021}, + 160: {region: 0x464f, code: 0x50, from: 0xf3821, to: 0x0}, + 161: {region: 0x4652, code: 0x5c, from: 0xf9e21, to: 0x0}, + 162: {region: 0x4652, code: 0x60, from: 0xf5021, to: 0xfa451}, + 163: {region: 0x4741, code: 0x106, from: 0xf9221, to: 0x0}, + 164: {region: 0x4742, code: 0x61, from: 0xd3cfb, to: 0x0}, + 165: {region: 0x4744, code: 0x10d, from: 0xf5e5b, to: 0x0}, + 166: {region: 0x4745, code: 0x63, from: 0xf9737, to: 0x0}, + 167: {region: 0x4745, code: 0x62, from: 0xf9285, to: 0xf9739}, + 168: {region: 0x4745, code: 0xd1, from: 0xf8f99, to: 0xf92cb}, + 169: {region: 0x4745, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 170: {region: 0x4746, code: 0x5c, from: 0xf9e21, to: 0x0}, + 171: {region: 0x4746, code: 0x60, from: 0xf5021, to: 0xfa451}, + 172: {region: 0x4747, code: 0x61, from: 0xe4c21, to: 0x0}, + 173: {region: 0x4748, code: 0x65, from: 0xfaee3, to: 0x0}, + 174: {region: 0x4748, code: 0x64, from: 0xf7669, to: 0xfaf9f}, + 175: {region: 0x4749, code: 0x66, from: 0xd6221, to: 0x0}, + 176: {region: 0x474c, code: 0x50, from: 0xea2bb, to: 0x0}, + 177: {region: 0x474d, code: 0x67, from: 0xf66e1, to: 0x0}, + 178: {region: 0x474e, code: 0x68, from: 0xf8426, to: 0x0}, + 179: {region: 0x474e, code: 0x69, from: 0xf6942, to: 0xf8426}, + 180: {region: 0x4750, code: 0x5c, from: 0xf9e21, to: 0x0}, + 181: {region: 0x4750, code: 0x60, from: 0xf5021, to: 0xfa451}, + 182: {region: 0x4751, code: 0x106, from: 0xf9221, to: 0x0}, + 183: {region: 0x4751, code: 0x6a, from: 0xf6ee7, to: 0xf84c1}, + 184: {region: 0x4752, code: 0x5c, from: 0xfa221, to: 0x0}, + 185: {region: 0x4752, code: 0x6b, from: 0xf44a1, to: 0xfa45c}, + 186: {region: 0x4753, code: 0x61, from: 0xee821, to: 0x0}, + 187: {region: 0x4754, code: 0x6c, from: 0xf0abb, to: 0x0}, + 188: {region: 0x4755, code: 0xf9, from: 0xf3115, to: 0x0}, + 189: {region: 0x4757, code: 0x112, from: 0xf9a7f, to: 0x0}, + 190: {region: 0x4757, code: 0x6e, from: 0xf705c, to: 0xf9a7f}, + 191: {region: 0x4757, code: 0x6d, from: 0xef421, to: 0xf705c}, + 192: {region: 0x4759, code: 0x6f, from: 0xf5cba, to: 0x0}, + 193: {region: 0x484b, code: 0x70, from: 0xece42, to: 0x0}, + 194: {region: 0x484d, code: 0x13, from: 0xf5e50, to: 0x0}, + 195: {region: 0x484e, code: 0x71, from: 0xf0c83, to: 0x0}, + 196: {region: 0x4852, code: 0x73, from: 0xf94be, to: 0x0}, + 197: {region: 0x4852, code: 0x72, from: 0xf8f97, to: 0xf9621}, + 198: {region: 0x4852, code: 0x11f, from: 0xf8c21, to: 0xf8f97}, + 199: {region: 0x4852, code: 0x11d, from: 0xf5c21, to: 0xf8c21}, + 200: {region: 0x4854, code: 0x74, from: 0xea11a, to: 0x0}, + 201: {region: 0x4854, code: 0xf9, from: 0xef621, to: 0x0}, + 202: {region: 0x4855, code: 0x75, from: 0xf34f7, to: 0x0}, + 203: {region: 0x4943, code: 0x5c, from: 0xf9e21, to: 0x0}, + 204: {region: 0x4944, code: 0x76, from: 0xf5b8d, to: 0x0}, + 205: {region: 0x4945, code: 0x5c, from: 0xf9e21, to: 0x0}, + 206: {region: 0x4945, code: 0x77, from: 0xf0421, to: 0xfa449}, + 207: {region: 0x4945, code: 0x61, from: 0xe1021, to: 0xf0421}, + 208: {region: 0x494c, code: 0x7a, from: 0xf8324, to: 0x0}, + 209: {region: 0x494c, code: 0x79, from: 0xf7856, to: 0xf8324}, + 210: {region: 0x494c, code: 0x78, from: 0xf3910, to: 0xf7856}, + 211: {region: 0x494d, code: 0x61, from: 0xe6023, to: 0x0}, + 212: {region: 0x494e, code: 0x7b, from: 0xe5711, to: 0x0}, + 213: {region: 0x494f, code: 0xf9, from: 0xf5b68, to: 0x0}, + 214: {region: 0x4951, code: 0x7c, from: 0xf1693, to: 0x0}, + 215: {region: 0x4951, code: 0x56, from: 0xf016b, to: 0xf1693}, + 216: {region: 0x4951, code: 0x7b, from: 0xf016b, to: 0xf1693}, + 217: {region: 0x4952, code: 0x7d, from: 0xf18ad, to: 0x0}, + 218: {region: 0x4953, code: 0x7f, from: 0xf7a21, to: 0x0}, + 219: {region: 0x4953, code: 0x7e, from: 0xefd81, to: 0xf7a21}, + 220: {region: 0x4953, code: 0x50, from: 0xea2bb, to: 0xefd81}, + 221: {region: 0x4954, code: 0x5c, from: 0xf9e21, to: 0x0}, + 222: {region: 0x4954, code: 0x80, from: 0xe8d18, to: 0xfa45c}, + 223: {region: 0x4a45, code: 0x61, from: 0xe5a21, to: 0x0}, + 224: {region: 0x4a4d, code: 0x81, from: 0xf6328, to: 0x0}, + 225: {region: 0x4a4f, code: 0x82, from: 0xf3ce1, to: 0x0}, + 226: {region: 0x4a50, code: 0x83, from: 0xe9ec1, to: 0x0}, + 227: {region: 0x4b45, code: 0x84, from: 0xf5d2e, to: 0x0}, + 228: {region: 0x4b47, code: 0x85, from: 0xf92aa, to: 0x0}, + 229: {region: 0x4b47, code: 0xd1, from: 0xf8f99, to: 0xf92aa}, + 230: {region: 0x4b47, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 231: {region: 0x4b48, code: 0x86, from: 0xf7874, to: 0x0}, + 232: {region: 0x4b49, code: 0x13, from: 0xf5c4e, to: 0x0}, + 233: {region: 0x4b4d, code: 0x87, from: 0xf6ee6, to: 0x0}, + 234: {region: 0x4b4e, code: 0x10d, from: 0xf5b46, to: 0x0}, + 235: {region: 0x4b50, code: 0x88, from: 0xf4e91, to: 0x0}, + 236: {region: 0x4b52, code: 0x8b, from: 0xf54ca, to: 0x0}, + 237: {region: 0x4b52, code: 0x89, from: 0xf424f, to: 0xf54ca}, + 238: {region: 0x4b52, code: 0x8a, from: 0xf330f, to: 0xf424f}, + 239: {region: 0x4b57, code: 0x8c, from: 0xf5281, to: 0x0}, + 240: {region: 0x4b59, code: 0x8d, from: 0xf6621, to: 0x0}, + 241: {region: 0x4b59, code: 0x81, from: 0xf6328, to: 0xf6621}, + 242: {region: 0x4b5a, code: 0x8e, from: 0xf9365, to: 0x0}, + 243: {region: 0x4c41, code: 0x8f, from: 0xf778a, to: 0x0}, + 244: {region: 0x4c42, code: 0x90, from: 0xf3842, to: 0x0}, + 245: {region: 0x4c43, code: 0x10d, from: 0xf5b46, to: 0x0}, + 246: {region: 0x4c49, code: 0x3c, from: 0xf0241, to: 0x0}, + 247: {region: 0x4c4b, code: 0x91, from: 0xf74b6, to: 0x0}, + 248: {region: 0x4c52, code: 0x92, from: 0xf3021, to: 0x0}, + 249: {region: 0x4c53, code: 0x122, from: 0xf524e, to: 0x0}, + 250: {region: 0x4c53, code: 0x93, from: 0xf7836, to: 0x0}, + 251: {region: 0x4c54, code: 0x5c, from: 0xfbe21, to: 0x0}, + 252: {region: 0x4c54, code: 0x94, from: 0xf92d9, to: 0xfbd9f}, + 253: {region: 0x4c54, code: 0x95, from: 0xf9141, to: 0xf92d9}, + 254: {region: 0x4c54, code: 0xe4, from: 0xf5221, to: 0xf9141}, + 255: {region: 0x4c55, code: 0x5c, from: 0xf9e21, to: 0x0}, + 256: {region: 0x4c55, code: 0x97, from: 0xf3124, to: 0xfa45c}, + 257: {region: 0x4c55, code: 0x8096, from: 0xf6421, to: 0xf8c65}, + 258: {region: 0x4c55, code: 0x8098, from: 0xf6421, to: 0xf8c65}, + 259: {region: 0x4c56, code: 0x5c, from: 0xfbc21, to: 0x0}, + 260: {region: 0x4c56, code: 0x99, from: 0xf92dc, to: 0xfbb9f}, + 261: {region: 0x4c56, code: 0x9a, from: 0xf90a7, to: 0xf9351}, + 262: {region: 0x4c56, code: 0xe4, from: 0xf5221, to: 0xf90f4}, + 263: {region: 0x4c59, code: 0x9b, from: 0xf6721, to: 0x0}, + 264: {region: 0x4d41, code: 0x9c, from: 0xf4f51, to: 0x0}, + 265: {region: 0x4d41, code: 0x9d, from: 0xeb221, to: 0xf4f51}, + 266: {region: 0x4d43, code: 0x5c, from: 0xf9e21, to: 0x0}, + 267: {region: 0x4d43, code: 0x60, from: 0xf5021, to: 0xfa451}, + 268: {region: 0x4d43, code: 0x9e, from: 0xf5021, to: 0xfa451}, + 269: {region: 0x4d44, code: 0xa0, from: 0xf937d, to: 0x0}, + 270: {region: 0x4d44, code: 0x9f, from: 0xf90c1, to: 0xf937d}, + 271: {region: 0x4d45, code: 0x5c, from: 0xfa421, to: 0x0}, + 272: {region: 0x4d45, code: 0x4e, from: 0xf9f42, to: 0xfa4af}, + 273: {region: 0x4d45, code: 0x11e, from: 0xf9438, to: 0xfa4af}, + 274: {region: 0x4d46, code: 0x5c, from: 0xf9e21, to: 0x0}, + 275: {region: 0x4d46, code: 0x60, from: 0xf5021, to: 0xfa451}, + 276: {region: 0x4d47, code: 0xa1, from: 0xf7f61, to: 0x0}, + 277: {region: 0x4d47, code: 0xa2, from: 0xf56e1, to: 0xfa99f}, + 278: {region: 0x4d48, code: 0xf9, from: 0xf3021, to: 0x0}, + 279: {region: 0x4d4b, code: 0xa3, from: 0xf92b4, to: 0x0}, + 280: {region: 0x4d4b, code: 0xa4, from: 0xf909a, to: 0xf92b4}, + 281: {region: 0x4d4c, code: 0x112, from: 0xf80c1, to: 0x0}, + 282: {region: 0x4d4c, code: 0xa5, from: 0xf54e2, to: 0xf811f}, + 283: {region: 0x4d4c, code: 0x112, from: 0xf4d78, to: 0xf54e2}, + 284: {region: 0x4d4d, code: 0xa6, from: 0xf8ad2, to: 0x0}, + 285: {region: 0x4d4d, code: 0x34, from: 0xf40e1, to: 0xf8ad2}, + 286: {region: 0x4d4e, code: 0xa7, from: 0xef661, to: 0x0}, + 287: {region: 0x4d4f, code: 0xa8, from: 0xeda21, to: 0x0}, + 288: {region: 0x4d50, code: 0xf9, from: 0xf3021, to: 0x0}, + 289: {region: 0x4d51, code: 0x5c, from: 0xf9e21, to: 0x0}, + 290: {region: 0x4d51, code: 0x60, from: 0xf5021, to: 0xfa451}, + 291: {region: 0x4d52, code: 0xa9, from: 0xf6add, to: 0x0}, + 292: {region: 0x4d52, code: 0x112, from: 0xf4d7c, to: 0xf6add}, + 293: {region: 0x4d53, code: 0x10d, from: 0xf5e5b, to: 0x0}, + 294: {region: 0x4d54, code: 0x5c, from: 0xfb021, to: 0x0}, + 295: {region: 0x4d54, code: 0xaa, from: 0xf60c7, to: 0xfb03f}, + 296: {region: 0x4d54, code: 0xab, from: 0xef50d, to: 0xf60c7}, + 297: {region: 0x4d55, code: 0xac, from: 0xf1c81, to: 0x0}, + 298: {region: 0x4d56, code: 0xae, from: 0xf7ae1, to: 0x0}, + 299: {region: 0x4d57, code: 0xaf, from: 0xf664f, to: 0x0}, + 300: {region: 0x4d58, code: 0xb0, from: 0xf9221, to: 0x0}, + 301: {region: 0x4d58, code: 0xb1, from: 0xe3c21, to: 0xf919f}, + 302: {region: 0x4d58, code: 0x80b2, from: 0x0, to: 0x0}, + 303: {region: 0x4d59, code: 0xb3, from: 0xf5730, to: 0x0}, + 304: {region: 0x4d5a, code: 0xb6, from: 0xface1, to: 0x0}, + 305: {region: 0x4d5a, code: 0xb5, from: 0xf78d0, to: 0xfad9f}, + 306: {region: 0x4d5a, code: 0xb4, from: 0xf6ed9, to: 0xf78d0}, + 307: {region: 0x4e41, code: 0xb7, from: 0xf9221, to: 0x0}, + 308: {region: 0x4e41, code: 0x122, from: 0xf524e, to: 0x0}, + 309: {region: 0x4e43, code: 0x114, from: 0xf8221, to: 0x0}, + 310: {region: 0x4e45, code: 0x112, from: 0xf4d93, to: 0x0}, + 311: {region: 0x4e46, code: 0x13, from: 0xf5c4e, to: 0x0}, + 312: {region: 0x4e47, code: 0xb8, from: 0xf6a21, to: 0x0}, + 313: {region: 0x4e49, code: 0xba, from: 0xf8e9e, to: 0x0}, + 314: {region: 0x4e49, code: 0xb9, from: 0xf884f, to: 0xf8e9e}, + 315: {region: 0x4e4c, code: 0x5c, from: 0xf9e21, to: 0x0}, + 316: {region: 0x4e4c, code: 0xbb, from: 0xe2a21, to: 0xfa45c}, + 317: {region: 0x4e4f, code: 0xbc, from: 0xee2c7, to: 0x0}, + 318: {region: 0x4e4f, code: 0xd9, from: 0xea2bb, to: 0xee2c7}, + 319: {region: 0x4e50, code: 0xbd, from: 0xf1a21, to: 0x0}, + 320: {region: 0x4e50, code: 0x7b, from: 0xe9c21, to: 0xf5d51}, + 321: {region: 0x4e52, code: 0x13, from: 0xf5c4e, to: 0x0}, + 322: {region: 0x4e55, code: 0xbe, from: 0xf5eea, to: 0x0}, + 323: {region: 0x4e5a, code: 0xbe, from: 0xf5eea, to: 0x0}, + 324: {region: 0x4f4d, code: 0xbf, from: 0xf696b, to: 0x0}, + 325: {region: 0x5041, code: 0xc0, from: 0xedf64, to: 0x0}, + 326: {region: 0x5041, code: 0xf9, from: 0xedf72, to: 0x0}, + 327: {region: 0x5045, code: 0xc2, from: 0xf8ee1, to: 0x0}, + 328: {region: 0x5045, code: 0xc1, from: 0xf8241, to: 0xf8ee1}, + 329: {region: 0x5045, code: 0xc3, from: 0xe8e4e, to: 0xf8241}, + 330: {region: 0x5046, code: 0x114, from: 0xf339a, to: 0x0}, + 331: {region: 0x5047, code: 0xc4, from: 0xf6f30, to: 0x0}, + 332: {region: 0x5047, code: 0x13, from: 0xf5c4e, to: 0xf6f30}, + 333: {region: 0x5048, code: 0xc5, from: 0xf34e4, to: 0x0}, + 334: {region: 0x504b, code: 0xc6, from: 0xf3881, to: 0x0}, + 335: {region: 0x504b, code: 0x7b, from: 0xe5711, to: 0xf370f}, + 336: {region: 0x504c, code: 0xc7, from: 0xf9621, to: 0x0}, + 337: {region: 0x504c, code: 0xc8, from: 0xf3d5c, to: 0xf959f}, + 338: {region: 0x504d, code: 0x5c, from: 0xf9e21, to: 0x0}, + 339: {region: 0x504d, code: 0x60, from: 0xf6995, to: 0xfa451}, + 340: {region: 0x504e, code: 0xbe, from: 0xf622d, to: 0x0}, + 341: {region: 0x5052, code: 0xf9, from: 0xed58a, to: 0x0}, + 342: {region: 0x5052, code: 0x5a, from: 0xe1021, to: 0xed58a}, + 343: {region: 0x5053, code: 0x7a, from: 0xf8324, to: 0x0}, + 344: {region: 0x5053, code: 0x82, from: 0xf984c, to: 0x0}, + 345: {region: 0x5053, code: 0x78, from: 0xf5ec1, to: 0xf7856}, + 346: {region: 0x5053, code: 0x82, from: 0xf3ce1, to: 0xf5ec1}, + 347: {region: 0x5054, code: 0x5c, from: 0xf9e21, to: 0x0}, + 348: {region: 0x5054, code: 0xc9, from: 0xeeeb6, to: 0xfa45c}, + 349: {region: 0x5057, code: 0xf9, from: 0xf3021, to: 0x0}, + 350: {region: 0x5059, code: 0xca, from: 0xf2f61, to: 0x0}, + 351: {region: 0x5141, code: 0xcb, from: 0xf6ab3, to: 0x0}, + 352: {region: 0x5245, code: 0x5c, from: 0xf9e21, to: 0x0}, + 353: {region: 0x5245, code: 0x60, from: 0xf6e21, to: 0xfa451}, + 354: {region: 0x524f, code: 0xce, from: 0xfaae1, to: 0x0}, + 355: {region: 0x524f, code: 0xcd, from: 0xf403c, to: 0xfad9f}, + 356: {region: 0x5253, code: 0xcf, from: 0xfad59, to: 0x0}, + 357: {region: 0x5253, code: 0x46, from: 0xfa4af, to: 0xfad59}, + 358: {region: 0x5253, code: 0x11e, from: 0xf9438, to: 0xfa4af}, + 359: {region: 0x5255, code: 0xd0, from: 0xf9e21, to: 0x0}, + 360: {region: 0x5255, code: 0xd1, from: 0xf8f99, to: 0xf9d9f}, + 361: {region: 0x5257, code: 0xd2, from: 0xf58b3, to: 0x0}, + 362: {region: 0x5341, code: 0xd3, from: 0xf4156, to: 0x0}, + 363: {region: 0x5342, code: 0xd4, from: 0xf7358, to: 0x0}, + 364: {region: 0x5342, code: 0x13, from: 0xf5c4e, to: 0xf74de}, + 365: {region: 0x5343, code: 0xd5, from: 0xedf61, to: 0x0}, + 366: {region: 0x5344, code: 0xd7, from: 0xfae2a, to: 0x0}, + 367: {region: 0x5344, code: 0xd6, from: 0xf90c8, to: 0xfaede}, + 368: {region: 0x5344, code: 0xd8, from: 0xf4a88, to: 0xf9cc1}, + 369: {region: 0x5344, code: 0x56, from: 0xec233, to: 0xf4c21}, + 370: {region: 0x5344, code: 0x61, from: 0xec233, to: 0xf4c21}, + 371: {region: 0x5345, code: 0xd9, from: 0xea2bb, to: 0x0}, + 372: {region: 0x5347, code: 0xda, from: 0xf5ecc, to: 0x0}, + 373: {region: 0x5347, code: 0xb3, from: 0xf5730, to: 0xf5ecc}, + 374: {region: 0x5348, code: 0xdb, from: 0xefa4f, to: 0x0}, + 375: {region: 0x5349, code: 0x5c, from: 0xfae21, to: 0x0}, + 376: {region: 0x5349, code: 0xdc, from: 0xf9147, to: 0xfae2e}, + 377: {region: 0x534a, code: 0xbc, from: 0xee2c7, to: 0x0}, + 378: {region: 0x534b, code: 0x5c, from: 0xfb221, to: 0x0}, + 379: {region: 0x534b, code: 0xdd, from: 0xf919f, to: 0xfb221}, + 380: {region: 0x534b, code: 0x47, from: 0xf42c1, to: 0xf919f}, + 381: {region: 0x534c, code: 0xde, from: 0xf5904, to: 0x0}, + 382: {region: 0x534c, code: 0x61, from: 0xe217e, to: 0xf5c44}, + 383: {region: 0x534d, code: 0x5c, from: 0xf9e21, to: 0x0}, + 384: {region: 0x534d, code: 0x80, from: 0xe9397, to: 0xfa25c}, + 385: {region: 0x534e, code: 0x112, from: 0xf4e84, to: 0x0}, + 386: {region: 0x534f, code: 0xdf, from: 0xf50e1, to: 0x0}, + 387: {region: 0x5352, code: 0xe0, from: 0xfa821, to: 0x0}, + 388: {region: 0x5352, code: 0xe1, from: 0xf28aa, to: 0xfa79f}, + 389: {region: 0x5352, code: 0xbb, from: 0xe2f74, to: 0xf28aa}, + 390: {region: 0x5353, code: 0xe2, from: 0xfb6f2, to: 0x0}, + 391: {region: 0x5353, code: 0xd7, from: 0xfae2a, to: 0xfb721}, + 392: {region: 0x5354, code: 0xe3, from: 0xf7328, to: 0x0}, + 393: {region: 0x5355, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 394: {region: 0x5356, code: 0xf9, from: 0xfa221, to: 0x0}, + 395: {region: 0x5356, code: 0xe5, from: 0xeff6b, to: 0xfa221}, + 396: {region: 0x5358, code: 0x8, from: 0xfb54a, to: 0x0}, + 397: {region: 0x5359, code: 0xe6, from: 0xf3821, to: 0x0}, + 398: {region: 0x535a, code: 0xe7, from: 0xf6d26, to: 0x0}, + 399: {region: 0x5441, code: 0x61, from: 0xf242c, to: 0x0}, + 400: {region: 0x5443, code: 0xf9, from: 0xf6328, to: 0x0}, + 401: {region: 0x5444, code: 0x106, from: 0xf9221, to: 0x0}, + 402: {region: 0x5446, code: 0x5c, from: 0xf9e21, to: 0x0}, + 403: {region: 0x5446, code: 0x60, from: 0xf4e21, to: 0xfa451}, + 404: {region: 0x5447, code: 0x112, from: 0xf4d7c, to: 0x0}, + 405: {region: 0x5448, code: 0xe8, from: 0xf108f, to: 0x0}, + 406: {region: 0x544a, code: 0xea, from: 0xfa15a, to: 0x0}, + 407: {region: 0x544a, code: 0xe9, from: 0xf96aa, to: 0xfa159}, + 408: {region: 0x544a, code: 0xd1, from: 0xf8f99, to: 0xf96aa}, + 409: {region: 0x544b, code: 0xbe, from: 0xf5eea, to: 0x0}, + 410: {region: 0x544c, code: 0xf9, from: 0xf9f54, to: 0x0}, + 411: {region: 0x544c, code: 0xef, from: 0xf4e22, to: 0xfa4b4}, + 412: {region: 0x544c, code: 0x76, from: 0xf6f87, to: 0xfa4b4}, + 413: {region: 0x544d, code: 0xec, from: 0xfb221, to: 0x0}, + 414: {region: 0x544d, code: 0xeb, from: 0xf9361, to: 0xfb221}, + 415: {region: 0x544d, code: 0xd1, from: 0xf8f99, to: 0xf9361}, + 416: {region: 0x544d, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 417: {region: 0x544e, code: 0xed, from: 0xf4d61, to: 0x0}, + 418: {region: 0x544f, code: 0xee, from: 0xf5c4e, to: 0x0}, + 419: {region: 0x5450, code: 0xef, from: 0xf4e22, to: 0xfa4b4}, + 420: {region: 0x5450, code: 0x76, from: 0xf6f87, to: 0xfa4b4}, + 421: {region: 0x5452, code: 0xf1, from: 0xfaa21, to: 0x0}, + 422: {region: 0x5452, code: 0xf0, from: 0xf0561, to: 0xfab9f}, + 423: {region: 0x5454, code: 0xf2, from: 0xf5821, to: 0x0}, + 424: {region: 0x5456, code: 0x13, from: 0xf5c4e, to: 0x0}, + 425: {region: 0x5457, code: 0xf3, from: 0xf3acf, to: 0x0}, + 426: {region: 0x545a, code: 0xf4, from: 0xf5cce, to: 0x0}, + 427: {region: 0x5541, code: 0xf5, from: 0xf9922, to: 0x0}, + 428: {region: 0x5541, code: 0xf6, from: 0xf916d, to: 0xf9351}, + 429: {region: 0x5541, code: 0xd1, from: 0xf8f99, to: 0xf916d}, + 430: {region: 0x5541, code: 0xe4, from: 0xf5221, to: 0xf8f99}, + 431: {region: 0x5547, code: 0xf8, from: 0xf86af, to: 0x0}, + 432: {region: 0x5547, code: 0xf7, from: 0xf5d0f, to: 0xf86af}, + 433: {region: 0x554d, code: 0xf9, from: 0xf3021, to: 0x0}, + 434: {region: 0x5553, code: 0xf9, from: 0xe0021, to: 0x0}, + 435: {region: 0x5553, code: 0x80fa, from: 0x0, to: 0x0}, + 436: {region: 0x5553, code: 0x80fb, from: 0x0, to: 0xfbc61}, + 437: {region: 0x5559, code: 0xfe, from: 0xf9261, to: 0x0}, + 438: {region: 0x5559, code: 0xfd, from: 0xf6ee1, to: 0xf9261}, + 439: {region: 0x5559, code: 0x80fc, from: 0x0, to: 0x0}, + 440: {region: 0x555a, code: 0xff, from: 0xf94e1, to: 0x0}, + 441: {region: 0x5641, code: 0x5c, from: 0xf9e21, to: 0x0}, + 442: {region: 0x5641, code: 0x80, from: 0xe9d53, to: 0xfa45c}, + 443: {region: 0x5643, code: 0x10d, from: 0xf5b46, to: 0x0}, + 444: {region: 0x5645, code: 0x101, from: 0xfb021, to: 0x0}, + 445: {region: 0x5645, code: 0x100, from: 0xe9eab, to: 0xfb0de}, + 446: {region: 0x5647, code: 0xf9, from: 0xe5221, to: 0x0}, + 447: {region: 0x5647, code: 0x61, from: 0xe5221, to: 0xf4e21}, + 448: {region: 0x5649, code: 0xf9, from: 0xe5a21, to: 0x0}, + 449: {region: 0x564e, code: 0x102, from: 0xf832e, to: 0x0}, + 450: {region: 0x564e, code: 0x103, from: 0xf74a3, to: 0xf832e}, + 451: {region: 0x5655, code: 0x104, from: 0xf7a21, to: 0x0}, + 452: {region: 0x5746, code: 0x114, from: 0xf52fe, to: 0x0}, + 453: {region: 0x5753, code: 0x105, from: 0xf5eea, to: 0x0}, + 454: {region: 0x584b, code: 0x5c, from: 0xfa421, to: 0x0}, + 455: {region: 0x584b, code: 0x4e, from: 0xf9f21, to: 0xfa469}, + 456: {region: 0x584b, code: 0x11e, from: 0xf9438, to: 0xf9f3e}, + 457: {region: 0x5944, code: 0x11b, from: 0xf5a81, to: 0xf9821}, + 458: {region: 0x5945, code: 0x11c, from: 0xf8cb6, to: 0x0}, + 459: {region: 0x5954, code: 0x5c, from: 0xf9e21, to: 0x0}, + 460: {region: 0x5954, code: 0x60, from: 0xf7057, to: 0xfa451}, + 461: {region: 0x5954, code: 0x87, from: 0xf6e21, to: 0xf7057}, + 462: {region: 0x5955, code: 0x11e, from: 0xf9438, to: 0xfa4af}, + 463: {region: 0x5955, code: 0x11f, from: 0xf8c21, to: 0xf90f8}, + 464: {region: 0x5955, code: 0x11d, from: 0xf5c21, to: 0xf8c21}, + 465: {region: 0x5a41, code: 0x122, from: 0xf524e, to: 0x0}, + 466: {region: 0x5a41, code: 0x8121, from: 0xf8321, to: 0xf966d}, + 467: {region: 0x5a4d, code: 0x124, from: 0xfba21, to: 0x0}, + 468: {region: 0x5a4d, code: 0x123, from: 0xf6030, to: 0xfba21}, + 469: {region: 0x5a52, code: 0x125, from: 0xf9361, to: 0xf9cff}, + 470: {region: 0x5a52, code: 0x126, from: 0xf675b, to: 0xf9361}, + 471: {region: 0x5a57, code: 0xf9, from: 0xfb28c, to: 0x0}, + 472: {region: 0x5a57, code: 0x128, from: 0xfb242, to: 0xfb28c}, + 473: {region: 0x5a57, code: 0x129, from: 0xfb101, to: 0xfb242}, + 474: {region: 0x5a57, code: 0x127, from: 0xf7892, to: 0xfb101}, + 475: {region: 0x5a57, code: 0xcc, from: 0xf6451, to: 0xf7892}, + 476: {region: 0x5a5a, code: 0x8107, from: 0x0, to: 0x0}, + 477: {region: 0x5a5a, code: 0x8108, from: 0x0, to: 0x0}, + 478: {region: 0x5a5a, code: 0x8109, from: 0x0, to: 0x0}, + 479: {region: 0x5a5a, code: 0x810a, from: 0x0, to: 0x0}, + 480: {region: 0x5a5a, code: 0x810b, from: 0x0, to: 0x0}, + 481: {region: 0x5a5a, code: 0x810c, from: 0x0, to: 0x0}, + 482: {region: 0x5a5a, code: 0x810e, from: 0x0, to: 0x0}, + 483: {region: 0x5a5a, code: 0x8110, from: 0xf1421, to: 0xfa681}, + 484: {region: 0x5a5a, code: 0x8111, from: 0x0, to: 0xfbb7e}, + 485: {region: 0x5a5a, code: 0x8113, from: 0x0, to: 0x0}, + 486: {region: 0x5a5a, code: 0x8115, from: 0x0, to: 0x0}, + 487: {region: 0x5a5a, code: 0x8116, from: 0x0, to: 0xf9f7e}, + 488: {region: 0x5a5a, code: 0x8117, from: 0x0, to: 0x0}, + 489: {region: 0x5a5a, code: 0x8118, from: 0x0, to: 0x0}, + 490: {region: 0x5a5a, code: 0x8119, from: 0x0, to: 0x0}, + 491: {region: 0x5a5a, code: 0x811a, from: 0x0, to: 0x0}, +} // Size: 5928 bytes + // symbols holds symbol data of the form , where n is the length of // the symbol string str. var symbols string = "" + // Size: 1462 bytes @@ -1964,4 +2466,4 @@ var narrowSymIndex = []curToIndex{ // 375 elements 374: {cur: 0xf3, idx: 0xbf}, } // Size: 1524 bytes -// Total table size 12210 bytes (11KiB); checksum: 74846C68 +// Total table size 18138 bytes (17KiB); checksum: 976D06A2 diff --git a/currency/tables_test.go b/currency/tables_test.go index e39738c..779f500 100644 --- a/currency/tables_test.go +++ b/currency/tables_test.go @@ -4,6 +4,7 @@ import ( "flag" "strings" "testing" + "time" "golang.org/x/text/internal/gen" "golang.org/x/text/internal/testtext" @@ -67,4 +68,26 @@ func TestTables(t *testing.T) { } } } + + for _, reg := range data.Supplemental().CurrencyData.Region { + i := 0 + for ; regionData[i].Region().String() != reg.Iso3166; i++ { + } + it := Query(Historical, NonTender, Region(language.MustParseRegion(reg.Iso3166))) + for _, cur := range reg.Currency { + from, _ := time.Parse("2006-01-02", cur.From) + to, _ := time.Parse("2006-01-02", cur.To) + + it.Next() + for j, r := range []QueryIter{&iter{regionInfo: ®ionData[i]}, it} { + if got, _ := r.From(); from != got { + t.Errorf("%d:%s:%s:from: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, from) + } + if got, _ := r.To(); to != got { + t.Errorf("%d:%s:%s:to: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, to) + } + } + i++ + } + } }