diff --git a/.cargo/config.toml.in b/.cargo/config.toml.in index 802439bbdec1..dda2b8e2d7c3 100644 --- a/.cargo/config.toml.in +++ b/.cargo/config.toml.in @@ -70,9 +70,9 @@ git = "https://github.com/jfkthame/mapped_hyph.git" rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b" replace-with = "vendored-sources" -[source."git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285"] +[source."git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424"] git = "https://github.com/mozilla/application-services" -rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" replace-with = "vendored-sources" [source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"] diff --git a/Cargo.lock b/Cargo.lock index 065f1584b96b..046efbe96967 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -973,12 +973,11 @@ dependencies = [ [[package]] name = "context_id" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "chrono", "error-support", "lazy_static", - "log", "parking_lot", "serde", "serde_json", @@ -1913,8 +1912,9 @@ dependencies = [ [[package]] name = "error-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ + "env_logger", "error-support-macros", "lazy_static", "log", @@ -1925,7 +1925,7 @@ dependencies = [ [[package]] name = "error-support-macros" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "proc-macro2", "quote", @@ -2044,7 +2044,7 @@ dependencies = [ [[package]] name = "firefox-versioning" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "serde_json", "thiserror 1.999.999", @@ -3385,7 +3385,7 @@ dependencies = [ [[package]] name = "interrupt-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "lazy_static", "parking_lot", @@ -5108,7 +5108,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "payload-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "serde", "serde_derive", @@ -5615,13 +5615,12 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "relevancy" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "base64 0.21.999", "error-support", "interrupt-support", - "log", "md-5", "parking_lot", "rand", @@ -5640,14 +5639,13 @@ dependencies = [ [[package]] name = "remote_settings" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "camino", "error-support", "firefox-versioning", "jexl-eval", - "log", "parking_lot", "regex", "rusqlite 0.33.0", @@ -5933,7 +5931,7 @@ dependencies = [ [[package]] name = "search" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "error-support", "firefox-versioning", @@ -6225,11 +6223,11 @@ dependencies = [ [[package]] name = "sql-support" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ + "error-support", "interrupt-support", "lazy_static", - "log", "parking_lot", "rusqlite 0.33.0", "tempfile", @@ -6431,14 +6429,13 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "suggest" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "chrono", "error-support", "extend", "interrupt-support", - "log", "once_cell", "parking_lot", "remote_settings", @@ -6448,6 +6445,8 @@ dependencies = [ "serde_json", "sql-support", "thiserror 1.999.999", + "unicase", + "unicode-normalization", "uniffi", "url", "viaduct", @@ -6483,7 +6482,7 @@ dependencies = [ [[package]] name = "sync-guid" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "base64 0.21.999", "rand", @@ -6494,13 +6493,12 @@ dependencies = [ [[package]] name = "sync15" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "error-support", "interrupt-support", "lazy_static", - "log", "payload-support", "serde", "serde_derive", @@ -6534,13 +6532,12 @@ dependencies = [ [[package]] name = "tabs" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "error-support", "interrupt-support", "lazy_static", - "log", "payload-support", "rusqlite 0.33.0", "serde", @@ -6694,6 +6691,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "to_shmem" version = "0.1.0" @@ -6878,7 +6890,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "types" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "rusqlite 0.33.0", "serde", @@ -6953,6 +6965,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.999" @@ -7281,10 +7302,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "viaduct" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ + "error-support", "ffi-support", - "log", "once_cell", "parking_lot", "prost", @@ -7450,14 +7471,13 @@ dependencies = [ [[package]] name = "webext-storage" version = "0.1.0" -source = "git+https://github.com/mozilla/application-services?rev=fa8a72a77f88bc8b3743b50d76fb85cb37a38285#fa8a72a77f88bc8b3743b50d76fb85cb37a38285" +source = "git+https://github.com/mozilla/application-services?rev=8986582d377eac7b64bddec8aa9c5ce06b161424#8986582d377eac7b64bddec8aa9c5ce06b161424" dependencies = [ "anyhow", "error-support", "ffi-support", "interrupt-support", "lazy_static", - "log", "parking_lot", "rusqlite 0.33.0", "serde", diff --git a/Cargo.toml b/Cargo.toml index 339fc9faee5f..baa76d912ed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -265,15 +265,15 @@ wr_malloc_size_of = { path = "gfx/wr/wr_malloc_size_of" } objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" } # application-services overrides to make updating them all simpler. -context_id = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -relevancy = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -search = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -sql-support = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -suggest = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -sync15 = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -tabs = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -viaduct = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } -webext-storage = { git = "https://github.com/mozilla/application-services", rev = "fa8a72a77f88bc8b3743b50d76fb85cb37a38285" } +context_id = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +relevancy = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +search = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +sql-support = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +suggest = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +sync15 = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +tabs = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +viaduct = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } +webext-storage = { git = "https://github.com/mozilla/application-services", rev = "8986582d377eac7b64bddec8aa9c5ce06b161424" } allocator-api2 = { path = "third_party/rust/allocator-api2" } diff --git a/browser/components/urlbar/private/GeolocationUtils.sys.mjs b/browser/components/urlbar/private/GeolocationUtils.sys.mjs index 5e6a4ebce429..1b017564c7c9 100644 --- a/browser/components/urlbar/private/GeolocationUtils.sys.mjs +++ b/browser/components/urlbar/private/GeolocationUtils.sys.mjs @@ -99,10 +99,12 @@ class _GeolocationUtils { * `locationFromItem(item)` and it should return an object with the * following properties, all optional: * - * {number} latitude - * The location's latitude in decimal coordinates. - * {number} longitude - * The location's longitude in decimal coordinates. + * {String|number} latitude + * The location's latitude in decimal coordinates as either a string or + * float. + * {String|number} longitude + * The location's longitude in decimal coordinates as either a string or + * float. * {string} country * The location's two-digit ISO country code. Case doesn't matter. * {string} region @@ -158,9 +160,9 @@ class _GeolocationUtils { * `geo` does not include a location or coordinates, null is returned. */ #bestByDistance(geo, items, locationFromItem) { - let geoLat = geo.location?.latitude; - let geoLong = geo.location?.longitude; - if (typeof geoLat != "number" || typeof geoLong != "number") { + let geoLat = parseFloat(geo.location?.latitude); + let geoLong = parseFloat(geo.location?.longitude); + if (isNaN(geoLat) || isNaN(geoLong)) { return null; } @@ -174,15 +176,17 @@ class _GeolocationUtils { let dMin = Infinity; for (let item of items) { let location = locationFromItem(item); - if ( - typeof location.latitude != "number" || - typeof location.longitude != "number" - ) { + if (!location) { continue; } - let [itemLat, itemLong] = [location.latitude, location.longitude].map( - toRadians - ); + + let locationLat = parseFloat(location.latitude); + let locationLong = parseFloat(location.longitude); + if (isNaN(locationLat) || isNaN(locationLong)) { + continue; + } + + let [itemLat, itemLong] = [locationLat, locationLong].map(toRadians); let d = EARTH_RADIUS_KM * Math.acos( @@ -244,7 +248,7 @@ class _GeolocationUtils { let bestRegionTuple; for (let item of items) { let location = locationFromItem(item); - if (location.country?.toLowerCase() == geoCountry) { + if (location?.country?.toLowerCase() == geoCountry) { if ( !bestCountryTuple || hasLargerPopulation(location, bestCountryTuple.location) diff --git a/browser/components/urlbar/private/WeatherSuggestions.sys.mjs b/browser/components/urlbar/private/WeatherSuggestions.sys.mjs index fee851a404d6..3318c55a6ef0 100644 --- a/browser/components/urlbar/private/WeatherSuggestions.sys.mjs +++ b/browser/components/urlbar/private/WeatherSuggestions.sys.mjs @@ -197,7 +197,15 @@ export class WeatherSuggestions extends SuggestProvider { if (suggestions.length <= 1) { return suggestions; } - let suggestion = await lazy.GeolocationUtils.best(suggestions); + + let suggestion = await lazy.GeolocationUtils.best(suggestions, s => ({ + latitude: s.city?.latitude, + longitude: s.city?.longitude, + country: s.city?.countryCode, + region: s.city?.adminDivisionCodes.get(1), + population: s.city?.population, + })); + return [suggestion]; } @@ -215,9 +223,16 @@ export class WeatherSuggestions extends SuggestProvider { // Set up location params to pass to Merino. We need to null-check each // suggestion property because `MerinoClient` will stringify null values. let otherParams = {}; - for (let key of ["city", "region", "country"]) { - if (suggestion[key]) { - otherParams[key] = suggestion[key]; + if (suggestion.city) { + if (suggestion.city.name) { + otherParams.city = suggestion.city.name; + } + if (suggestion.city.countryCode) { + otherParams.country = suggestion.city.countryCode; + } + let admin1Code = suggestion.city.adminDivisionCodes.get(1); + if (admin1Code) { + otherParams.region = admin1Code; } } diff --git a/browser/components/urlbar/private/YelpSuggestions.sys.mjs b/browser/components/urlbar/private/YelpSuggestions.sys.mjs index 46394866a455..eeef8493b120 100644 --- a/browser/components/urlbar/private/YelpSuggestions.sys.mjs +++ b/browser/components/urlbar/private/YelpSuggestions.sys.mjs @@ -11,8 +11,6 @@ ChromeUtils.defineESModuleGetters(lazy, { "resource:///modules/urlbar/private/GeolocationUtils.sys.mjs", GeonameMatchType: "moz-src:///toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs", - GeonameType: - "moz-src:///toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs", QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs", UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs", UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs", @@ -495,8 +493,7 @@ export class YelpSuggestions extends SuggestProvider { regionMatches = await lazy.QuickSuggest.rustBackend.fetchGeonames( region, false, // prefix matching - lazy.GeonameType.REGION, - null + null // geonames filter array ); if (!regionMatches.length) { // The user typed something we thought was a region but isn't, so assume @@ -509,7 +506,6 @@ export class YelpSuggestions extends SuggestProvider { let cityMatches = await lazy.QuickSuggest.rustBackend.fetchGeonames( city, true, // prefix matching - lazy.GeonameType.CITY, regionMatches?.map(m => m.geoname) ); // Discard prefix matches on any names that aren't full names, i.e., on @@ -530,7 +526,10 @@ export class YelpSuggestions extends SuggestProvider { cityMatches, locationFromGeonameMatch ); - return { city: best.geoname.name, region: best.geoname.admin1Code }; + return { + city: best.geoname.name, + region: best.geoname.adminDivisionCodes.get(1), + }; } // We didn't detect a city in the query but we detected a region, so try to @@ -574,7 +573,7 @@ function locationFromGeonameMatch(match) { latitude: match.geoname.latitude, longitude: match.geoname.longitude, country: match.geoname.countryCode, - region: match.geoname.admin1Code, + region: match.geoname.adminDivisionCodes.get(1), population: match.geoname.population, }; } diff --git a/browser/components/urlbar/tests/quicksuggest/MerinoTestUtils.sys.mjs b/browser/components/urlbar/tests/quicksuggest/MerinoTestUtils.sys.mjs index 7cbd763449e9..b7b2ccf4fafe 100644 --- a/browser/components/urlbar/tests/quicksuggest/MerinoTestUtils.sys.mjs +++ b/browser/components/urlbar/tests/quicksuggest/MerinoTestUtils.sys.mjs @@ -564,10 +564,6 @@ class MockMerinoServer { "MockMerinoServer received request with query string: " + JSON.stringify(httpRequest.queryString) ); - this.info( - "MockMerinoServer replying with response: " + - JSON.stringify(this.response) - ); // Add the request to the list of received requests. this.#requests.push(httpRequest); @@ -581,6 +577,10 @@ class MockMerinoServer { let response = this.#requestHandler?.(httpRequest) || this.response; + this.info( + "MockMerinoServer replying with response: " + JSON.stringify(response) + ); + let finishResponse = () => { let status = response.status || 200; httpResponse.setStatusLine("", status, status); diff --git a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs index 812577aeda2f..cefeb32c9739 100644 --- a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs +++ b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs @@ -658,32 +658,24 @@ class _QuickSuggestTestUtils { min_keyword_length = undefined, score = 0.29, } = {}) { - let [maxLen, maxWordCount] = keywords.reduce( - ([len, wordCount], kw) => [ - Math.max(len, kw.length), - Math.max(wordCount, kw.split(/\s+/).filter(s => !!s).length), - ], - [0, 0] - ); return { type: "weather", attachment: { keywords, min_keyword_length, score, - max_keyword_length: maxLen, - max_keyword_word_count: maxWordCount, }, }; } /** - * Returns a remote settings geonames record populated with some cities. + * Returns remote settings records containing geonames populated with some + * cities. * - * @returns {object} - * A geonames record for storing in remote settings. + * @returns {Array} + * One or more geonames records for storing in remote settings. */ - geonamesRecord() { + geonamesRecords() { let geonames = [ // Waterloo, AL { @@ -693,11 +685,9 @@ class _QuickSuggestTestUtils { longitude: "-88.0642", feature_class: "P", feature_code: "PPL", - country_code: "US", - admin1_code: "AL", + country: "US", + admin1: "AL", population: 200, - alternate_names: ["waterloo"], - alternate_names_2: [{ name: "waterloo" }], }, // AL { @@ -707,14 +697,9 @@ class _QuickSuggestTestUtils { longitude: "-86.75026", feature_class: "A", feature_code: "ADM1", - country_code: "US", - admin1_code: "AL", + country: "US", + admin1: "AL", population: 4530315, - alternate_names: ["al", "alabama"], - alternate_names_2: [ - { name: "alabama" }, - { name: "al", iso_language: "abbr" }, - ], }, // Waterloo, IA { @@ -724,11 +709,9 @@ class _QuickSuggestTestUtils { longitude: "-92.34296", feature_class: "P", feature_code: "PPLA2", - country_code: "US", - admin1_code: "IA", + country: "US", + admin1: "IA", population: 68460, - alternate_names: ["waterloo"], - alternate_names_2: [{ name: "waterloo" }], }, // IA { @@ -738,14 +721,9 @@ class _QuickSuggestTestUtils { longitude: "-93.50049", feature_class: "A", feature_code: "ADM1", - country_code: "US", - admin1_code: "IA", + country: "US", + admin1: "IA", population: 2955010, - alternate_names: ["ia", "iowa"], - alternate_names_2: [ - { name: "iowa" }, - { name: "ia", iso_language: "abbr" }, - ], }, // Made-up cities with the same name in the US and CA. The CA city has a // larger population. @@ -756,11 +734,9 @@ class _QuickSuggestTestUtils { longitude: "-97.92977", feature_class: "P", feature_code: "PPL", - country_code: "US", - admin1_code: "IA", + country: "US", + admin1: "IA", population: 1, - alternate_names: ["us ca city"], - alternate_names_2: [{ name: "us ca city" }], }, { id: 101, @@ -769,11 +745,9 @@ class _QuickSuggestTestUtils { longitude: "-73.58781", feature_class: "P", feature_code: "PPL", - country_code: "CA", - admin1_code: "08", + country: "CA", + admin1: "08", population: 2, - alternate_names: ["us ca city"], - alternate_names_2: [{ name: "us ca city" }], }, // Made-up cities that are only ~1.5 km apart. { @@ -783,11 +757,9 @@ class _QuickSuggestTestUtils { longitude: "-84.39", feature_class: "P", feature_code: "PPL", - country_code: "US", - admin1_code: "GA", + country: "US", + admin1: "GA", population: 1, - alternate_names: ["twin city a"], - alternate_names_2: [{ name: "twin city a" }], }, { id: 103, @@ -796,11 +768,9 @@ class _QuickSuggestTestUtils { longitude: "-84.4", feature_class: "P", feature_code: "PPL", - country_code: "US", - admin1_code: "GA", + country: "US", + admin1: "GA", population: 2, - alternate_names: ["twin city b"], - alternate_names_2: [{ name: "twin city b" }], }, { id: 1850147, @@ -809,33 +779,42 @@ class _QuickSuggestTestUtils { longitude: "139.69171", feature_class: "P", feature_code: "PPLC", - country_code: "JP", - admin1_code: "Tokyo-to", + country: "JP", + admin1: "Tokyo-to", population: 8336599, - alternate_names: ["tokyo"], - alternate_names_2: [{ name: "tokyo" }], }, ]; - let [maxLen, maxWordCount] = geonames.reduce( - ([len, wordCount], geoname) => [ - Math.max(len, ...geoname.alternate_names.map(n => n.length)), - Math.max( - wordCount, - ...geoname.alternate_names.map( - n => n.split(/\s+/).filter(s => !!s).length - ) - ), - ], - [0, 0] - ); - return { - type: "geonames", - attachment: { - geonames, - max_alternate_name_length: maxLen, - max_alternate_name_word_count: maxWordCount, + + return [ + { + type: "geonames-2", + attachment: geonames, }, - }; + ]; + } + + /** + * Returns remote settings records containing geonames alternates (alternate + * names) populated with some names. + * + * @returns {Array} + * One or more geonames alternates records for storing in remote settings. + */ + geonamesAlternatesRecords() { + return [ + { + type: "geonames-alternates", + attachment: [ + { + language: "abbr", + alternates_by_geoname_id: [ + [2, ["AL"]], + [4, ["IA"]], + ], + }, + ], + }, + ]; } /** diff --git a/browser/components/urlbar/tests/quicksuggest/RemoteSettingsServer.sys.mjs b/browser/components/urlbar/tests/quicksuggest/RemoteSettingsServer.sys.mjs index e88c4db3fcca..99831e3e555d 100644 --- a/browser/components/urlbar/tests/quicksuggest/RemoteSettingsServer.sys.mjs +++ b/browser/components/urlbar/tests/quicksuggest/RemoteSettingsServer.sys.mjs @@ -497,14 +497,17 @@ export class RemoteSettingsServer { async #addAttachment({ bucket, collection, record }) { let { attachment } = record; - let bytes; - if (attachment instanceof Array) { - bytes = Uint8Array.from(attachment); - } else { - let encoder = new TextEncoder(); - bytes = encoder.encode(JSON.stringify(attachment)); + let mimetype = + record.attachmentMimetype ?? "application/json; charset=UTF-8"; + if (!mimetype.startsWith("application/json")) { + throw new Error( + "Mimetype not handled, please add code for it! " + mimetype + ); } + let encoder = new TextEncoder(); + let bytes = encoder.encode(JSON.stringify(attachment)); + let hashBuffer = await crypto.subtle.digest("SHA-256", bytes); let hashBytes = new Uint8Array(hashBuffer); let toHex = b => b.toString(16).padStart(2, "0"); @@ -521,7 +524,7 @@ export class RemoteSettingsServer { record.attachment = { hash, filename, - mimetype: record.attachmentMimetype ?? "application/json; charset=UTF-8", + mimetype, size: bytes.length, location: `attachments/${bucket}/${collection}/${filename}`, }; diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_fakespot.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_fakespot.js index 4f2403443598..911c46e7a100 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_fakespot.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_fakespot.js @@ -9,18 +9,6 @@ requestLongerTimeout(5); const REMOTE_SETTINGS_RECORDS = [ - { - type: "icon", - id: "icon-fakespot-amazon", - attachmentMimetype: "image/png", - attachment: [1, 2, 3], - }, - { - type: "icon", - id: "icon-fakespot-bestbuy", - attachmentMimetype: "image/svg+xml", - attachment: [4, 5, 6], - }, { collection: "fakespot-suggest-products", type: "fakespot-suggestions", @@ -576,52 +564,3 @@ add_task(async function ratingAndTotalReviewsLabel() { await UrlbarTestUtils.promisePopupClose(window); } }); - -// Test the icons. -add_task(async function icons() { - const testData = [ - { - input: "png image", - expectedIcon: REMOTE_SETTINGS_RECORDS.find( - r => r.id == "icon-fakespot-amazon" - ), - }, - { - input: "svg image", - expectedIcon: REMOTE_SETTINGS_RECORDS.find( - r => r.id == "icon-fakespot-bestbuy" - ), - }, - { input: "no image", expectedIcon: null }, - ]; - - for (const { input, expectedIcon } of testData) { - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: input, - }); - Assert.equal(UrlbarTestUtils.getResultCount(window), 2); - - const { element } = await UrlbarTestUtils.getDetailsOfResultAt(window, 1); - const src = element.row.querySelector( - ".urlbarView-dynamic-fakespot-icon" - ).src; - - if (!expectedIcon) { - Assert.equal(src, ""); - return; - } - - const content = await fetch(src); - const blob = await content.blob(); - const bytes = await blob.bytes(); - - Assert.equal(blob.type, expectedIcon.attachmentMimetype); - Assert.equal( - new TextDecoder().decode(bytes), - JSON.stringify(expectedIcon.attachment) - ); - - await UrlbarTestUtils.promisePopupClose(window); - } -}); diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js index a9649b2b86a8..cef9d4efac80 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js @@ -19,7 +19,8 @@ const REMOTE_SETTINGS_RECORDS = [ score: 0.5, }, }, - QuickSuggestTestUtils.geonamesRecord(), + ...QuickSuggestTestUtils.geonamesRecords(), + ...QuickSuggestTestUtils.geonamesAlternatesRecords(), ]; add_setup(async function () { diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp.js b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp.js index 25d18672282b..3e6e56259864 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp.js @@ -22,7 +22,8 @@ const REMOTE_SETTINGS_RECORDS = [ score: 0.5, }, }, - QuickSuggestTestUtils.geonamesRecord(), + ...QuickSuggestTestUtils.geonamesRecords(), + ...QuickSuggestTestUtils.geonamesAlternatesRecords(), ]; const TOKYO_RESULT = { diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp_ml.js b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp_ml.js index ec52fa4ff131..f4eb86fac403 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp_ml.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_yelp_ml.js @@ -25,7 +25,8 @@ const REMOTE_SETTINGS_RECORDS = [ score: 0.5, }, }, - QuickSuggestTestUtils.geonamesRecord(), + ...QuickSuggestTestUtils.geonamesRecords(), + ...QuickSuggestTestUtils.geonamesAlternatesRecords(), ]; const WATERLOO_RESULT = { @@ -383,7 +384,8 @@ add_task(async function cache_fromRust() { // Rust suggestion is not present in remote settings. add_task(async function cache_defaultValues() { await QuickSuggestTestUtils.setRemoteSettingsRecords([ - QuickSuggestTestUtils.geonamesRecord(), + ...QuickSuggestTestUtils.geonamesRecords(), + ...QuickSuggestTestUtils.geonamesAlternatesRecords(), ]); await doCacheTest({ // This value is hardcoded in `YelpSuggestions` as the default. diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js b/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js index 0ea22041fc53..fb9428c3442c 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js @@ -28,7 +28,8 @@ add_setup(async () => { ], remoteSettingsRecords: [ QuickSuggestTestUtils.weatherRecord(), - QuickSuggestTestUtils.geonamesRecord(), + ...QuickSuggestTestUtils.geonamesRecords(), + ...QuickSuggestTestUtils.geonamesAlternatesRecords(), ], }); diff --git a/docs/rust-components/api/js/suggest.md b/docs/rust-components/api/js/suggest.md index 470c195e80c7..7431f3905124 100644 --- a/docs/rust-components/api/js/suggest.md +++ b/docs/rust-components/api/js/suggest.md @@ -8,6 +8,10 @@ :members: :exclude-members: SuggestStoreBuilder ``` +```{js:autoclass} RustSuggest.sys.AlternateNames + :members: + :exclude-members: AlternateNames +``` ```{js:autoclass} RustSuggest.sys.FtsMatchInfo :members: :exclude-members: FtsMatchInfo @@ -16,6 +20,10 @@ :members: :exclude-members: Geoname ``` +```{js:autoclass} RustSuggest.sys.GeonameAlternates + :members: + :exclude-members: GeonameAlternates +``` ```{js:autoclass} RustSuggest.sys.GeonameMatch :members: :exclude-members: GeonameMatch diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index f578f78f9c4d..95f3a4bb7780 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -5372,6 +5372,11 @@ who = "Makoto Kato " criteria = "safe-to-deploy" delta = "0.7.4 -> 0.7.6" +[[audits.tinyvec_macros]] +who = "Drew Willcoxon " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.1.1" + [[audits.to_shmem]] who = "Emilio Cobos Álvarez " criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index a41c7704e8a8..185bba8eb7fc 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -696,6 +696,13 @@ user-id = 3618 user-login = "dtolnay" user-name = "David Tolnay" +[[publisher.unicode-normalization]] +version = "0.1.24" +when = "2024-09-17" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + [[publisher.unicode-width]] version = "0.2.0" when = "2024-09-19" @@ -1400,6 +1407,26 @@ criteria = "safe-to-deploy" delta = "3.5.0 -> 3.6.0" notes = "Dependency updates and new optimized trait implementations, but otherwise everything looks normal." +[[audits.bytecode-alliance.audits.tinyvec]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "1.6.0" +notes = """ +This crate, while it implements collections, does so without `std::*` APIs and +without `unsafe`. Skimming the crate everything looks reasonable and what one +would expect from idiomatic safe collections in Rust. +""" + +[[audits.bytecode-alliance.audits.tinyvec_macros]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.1.0" +notes = """ +This is a trivial crate which only contains a singular macro definition which is +intended to multiplex across the internal representation of a tinyvec, +presumably. This trivially doesn't contain anything bad. +""" + [[audits.bytecode-alliance.audits.unicase]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -2032,6 +2059,42 @@ Previously reviewed during security review and the audit is grandparented in. """ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.tinyvec]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.6.0 -> 1.6.1" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tinyvec]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.6.1 -> 1.7.0" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tinyvec]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.7.0 -> 1.8.0" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tinyvec]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.8.0 -> 1.8.1" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tinyvec]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.8.1 -> 1.9.0" +notes = """ +Larger delta, but no unsafe code introduced. Deltas for: +- borsh (Binary Object Representation Serializer for Hashing) serialization/deserialization support behind the `borsh` feature. +- trait implementations to interoperate with the generic-array crate +- miscellaneous helper functions and support code, e.g. `into_vec()`. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.tokio-stream]] who = "David Koloski " criteria = "safe-to-deploy" diff --git a/third_party/rust/context_id/.cargo-checksum.json b/third_party/rust/context_id/.cargo-checksum.json index b9be97cbb26b..e9ff303bab5e 100644 --- a/third_party/rust/context_id/.cargo-checksum.json +++ b/third_party/rust/context_id/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"6a4710d72aec46571c411e76c2c4fd62097e887fc90cc62bf44c454fef618d62","README.md":"478bd3dcd41863df0975c96fd38e34334d8146799bf1a16204bab2cc12dcffd2","src/callback.rs":"13305f4665e62abb4de08d9486295a60afd327b6c839d7ef314312d96dc098dc","src/error.rs":"969ba252410f2adff0ff91ec7eeaf52ffb9e91925eb9db0529f56c09872f78f8","src/lib.rs":"199c109f3a4bab8441ba46e7513602bf732c9b381477867d717dcab24b0983bf","src/mars.rs":"4909fc4f8b397d32144878d6ec64c414b7d724ed2532513f165c768cfe5b983f"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"c4a478ab37cdb8bea8392dfbe9fbc2e1a534259c7be22b864b8aad86381d8718","README.md":"478bd3dcd41863df0975c96fd38e34334d8146799bf1a16204bab2cc12dcffd2","src/callback.rs":"13305f4665e62abb4de08d9486295a60afd327b6c839d7ef314312d96dc098dc","src/error.rs":"969ba252410f2adff0ff91ec7eeaf52ffb9e91925eb9db0529f56c09872f78f8","src/lib.rs":"8bd9e98e0e194cea4b2fdd0393709113785db63ccdbc0e9518fa55c21f8bb13d","src/mars.rs":"4909fc4f8b397d32144878d6ec64c414b7d724ed2532513f165c768cfe5b983f"},"package":null} \ No newline at end of file diff --git a/third_party/rust/context_id/Cargo.toml b/third_party/rust/context_id/Cargo.toml index 59ade26e2a7a..9d49b7bec9ca 100644 --- a/third_party/rust/context_id/Cargo.toml +++ b/third_party/rust/context_id/Cargo.toml @@ -28,7 +28,6 @@ path = "src/lib.rs" [dependencies] chrono = "0.4" -log = "0.4" parking_lot = "0.12" serde = "1" serde_json = "1" diff --git a/third_party/rust/context_id/src/lib.rs b/third_party/rust/context_id/src/lib.rs index d6fcc04e066d..20b7bfaa6470 100644 --- a/third_party/rust/context_id/src/lib.rs +++ b/third_party/rust/context_id/src/lib.rs @@ -7,8 +7,7 @@ mod error; pub use error::{ApiError, ApiResult, Error, Result}; use chrono::{DateTime, Duration, Utc}; -use error_support::handle_error; -use log::error; +use error_support::{error, handle_error}; use parking_lot::{Mutex, RwLock}; use uuid::Uuid; diff --git a/third_party/rust/error-support/.cargo-checksum.json b/third_party/rust/error-support/.cargo-checksum.json index 68490842bd95..a2005fb1fcdd 100644 --- a/third_party/rust/error-support/.cargo-checksum.json +++ b/third_party/rust/error-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"c64762e3ad81f92bf69f4fd17efc4b01b21e75b9bdde8ca94078500b6651c867","README.md":"69ccc6e378995b9d490d64e23b42ea1d7a9e3232e3dae6fabf1f955786a49931","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"8f8e5711913ffd1b515ec60028529768990df51001e6125d4b83c948b41c4466","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"1e41747d06a0d032c9601df85dd6e95001e432ae95a75dcca859355cbadef3b0","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"f4af35d5fb5bf0ebef6dc6595edac6351e1dae2bff989c18810480fae2202168","uniffi.toml":"af91bcd8e7b1fa3f475a5e556979ff23c57b338395e0b65abc1cb1a0ee823e23"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"9ec1b1341ec8901768963a8c3286032d63cb574aa7ea160f0c015451bfaed524","README.md":"d820e387ac36a98c8e554fcaba13b76eb935413b535019444f6d448240e4d07e","src/handling.rs":"4b1183afe0716653918515299bc877a4d461fe8d2bb114a8c25f303203a35fdb","src/lib.rs":"6fcf1ca74e077abddfb48a6472671e35d1a422fc9e80d885da2b4a66bc781983","src/macros.rs":"27366e0424e4d700605c34bd96295cd35fa41aed8b49f30e0b6e0c59b870fe73","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"eda5580fabe633bd4fe7ac69ea8056874e8adfc093a74942294edcfbaa48824f","uniffi.toml":"af91bcd8e7b1fa3f475a5e556979ff23c57b338395e0b65abc1cb1a0ee823e23"},"package":null} \ No newline at end of file diff --git a/third_party/rust/error-support/Cargo.toml b/third_party/rust/error-support/Cargo.toml index 83f152d4cfce..7706e64d06c1 100644 --- a/third_party/rust/error-support/Cargo.toml +++ b/third_party/rust/error-support/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" name = "error-support" version = "0.1.0" authors = ["Thom Chiovoloni "] -build = "build.rs" +build = false exclude = ["/android"] autolib = false autobins = false @@ -26,27 +26,48 @@ license = "MPL-2.0" [features] backtrace = ["dep:backtrace"] +testing = ["tracing-support/testing"] +tracing-logging = [ + "dep:tracing", + "dep:tracing-support", +] +tracing-reporting = [ + "dep:tracing", + "dep:tracing-support", +] [lib] name = "error_support" path = "src/lib.rs" -[dependencies] -log = "0.4" - [dependencies.backtrace] version = "0.3" optional = true +[dependencies.env_logger] +version = "0.10" +default-features = false + [dependencies.error-support-macros] path = "macros" [dependencies.lazy_static] version = "1.4" +[dependencies.log] +version = "0.4" + [dependencies.parking_lot] version = ">=0.11,<=0.12" +[dependencies.tracing] +version = "0.1" +optional = true + +[dependencies.tracing-support] +path = "../tracing" +optional = true + [dependencies.uniffi] version = "0.29.0" diff --git a/third_party/rust/error-support/README.md b/third_party/rust/error-support/README.md index c349ff457659..80fd74696378 100644 --- a/third_party/rust/error-support/README.md +++ b/third_party/rust/error-support/README.md @@ -86,3 +86,14 @@ a user's database in their errors, which would then appear in our error variants. However, we've never seen that in practice so we are comfortable including the `rusqlite` error message in our error reports, without attempting to sanitize them. + +# Logging support + +This crate also supplies macros for logging, like `trace!()`, `error!()` etc, +which act just like the same macros from the `log` and `tracing` crates. Using +these macros means you don't need to take additional dependencies, nor know exactly +what logging system is in-place - it will arrange to be the correct logging system +for the application the crate is being used in. + +Avoiding PII in logging is up to the crate doing the logging. In general, components +might log PII (eg, URLs etc) at trace level. diff --git a/third_party/rust/error-support/build.rs b/third_party/rust/error-support/build.rs deleted file mode 100644 index afa61ff66a56..000000000000 --- a/third_party/rust/error-support/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -fn main() { - uniffi::generate_scaffolding("./src/errorsupport.udl").unwrap(); -} diff --git a/third_party/rust/error-support/src/errorsupport.udl b/third_party/rust/error-support/src/errorsupport.udl deleted file mode 100644 index dcf3745865be..000000000000 --- a/third_party/rust/error-support/src/errorsupport.udl +++ /dev/null @@ -1,16 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -namespace errorsupport { - /// Set the global error reporter. This is typically done early in startup. - void set_application_error_reporter(ApplicationErrorReporter error_reporter); - /// Unset the global error reporter. This is typically done at shutdown for - /// platforms that want to cleanup references like Desktop. - void unset_application_error_reporter(); -}; - -callback interface ApplicationErrorReporter { - void report_error(string type_name, string message); - void report_breadcrumb(string message, string module, u32 line, u32 column); -}; diff --git a/third_party/rust/error-support/src/handling.rs b/third_party/rust/error-support/src/handling.rs index a2892229a3a6..b9fd702712df 100644 --- a/third_party/rust/error-support/src/handling.rs +++ b/third_party/rust/error-support/src/handling.rs @@ -8,7 +8,7 @@ #[derive(Debug, Default)] pub struct ErrorReporting { /// If Some(level), will write a log message at that level. - log_level: Option, + log_level: Option, /// If Some(report_class) will call the error reporter with details. report_class: Option, } @@ -35,7 +35,7 @@ impl ErrorHandling { } /// Add logging to an ErrorHandling instance - pub fn log(self, level: log::Level) -> Self { + pub fn log(self, level: crate::Level) -> Self { Self { err: self.err, reporting: ErrorReporting { @@ -60,12 +60,12 @@ impl ErrorHandling { /// log a warning pub fn log_warning(self) -> Self { - self.log(log::Level::Warn) + self.log(crate::Level::Warn) } /// log an info pub fn log_info(self) -> Self { - self.log(log::Level::Info) + self.log(crate::Level::Info) } /// Add reporting to an ErrorHandling instance and also log an Error @@ -73,7 +73,7 @@ impl ErrorHandling { Self { err: self.err, reporting: ErrorReporting { - log_level: Some(log::Level::Error), + log_level: Some(crate::Level::Error), report_class: Some(report_class.into()), }, } @@ -99,9 +99,17 @@ where let handling = e.get_error_handling(); let reporting = handling.reporting; if let Some(level) = reporting.log_level { - match &reporting.report_class { - Some(report_class) => log::log!(level, "{report_class}: {}", e.to_string()), - None => log::log!(level, "{}", e.to_string()), + // tracing dosn't seem to have anything close enough to `log::log`, so we have to match levels explicitly. + let message = match &reporting.report_class { + Some(report_class) => format!("{report_class}: {}", e), + None => format!("{}", e), + }; + match level { + crate::Level::Trace => crate::trace!("{}", message), + crate::Level::Debug => crate::debug!("{}", message), + crate::Level::Info => crate::info!("{}", message), + crate::Level::Warn => crate::warn!("{}", message), + crate::Level::Error => crate::error!("{}", message), } } if let Some(report_class) = reporting.report_class { diff --git a/third_party/rust/error-support/src/lib.rs b/third_party/rust/error-support/src/lib.rs index c898e2552dba..89ba14cd6dca 100644 --- a/third_party/rust/error-support/src/lib.rs +++ b/third_party/rust/error-support/src/lib.rs @@ -2,6 +2,34 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +// kinda abusing features here, but features "override" builtin support. +#[cfg(not(feature = "tracing-logging"))] +pub use log::{debug, error, info, trace, warn, Level}; + +#[cfg(feature = "tracing-logging")] +pub use tracing_support::{debug, error, info, trace, warn, Level}; + +#[cfg(all(feature = "testing", not(feature = "tracing-logging")))] +pub fn init_for_tests() { + let _ = env_logger::try_init(); +} + +#[cfg(all(feature = "testing", not(feature = "tracing-logging")))] +pub fn init_for_tests_with_level(level: Level) { + // There's gotta be a better way :( + let level_name = match level { + Level::Debug => "debug", + Level::Trace => "trace", + Level::Info => "info", + Level::Warn => "warn", + Level::Error => "error", + }; + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or(level_name)).init(); +} + +#[cfg(all(feature = "testing", feature = "tracing-logging"))] +pub use tracing_support::init_for_tests; + mod macros; #[cfg(feature = "backtrace")] @@ -39,13 +67,25 @@ pub mod backtrace { mod redact; pub use redact::*; +#[cfg(not(feature = "tracing-reporting"))] mod reporting; +#[cfg(not(feature = "tracing-reporting"))] pub use reporting::{ - report_breadcrumb, report_error_to_app, set_application_error_reporter, - unset_application_error_reporter, ApplicationErrorReporter, + set_application_error_reporter, unset_application_error_reporter, ApplicationErrorReporter, }; -// These are exposed specifically for tests -pub use reporting::{ArcReporterAdapter, TestErrorReporter}; + +#[cfg(feature = "tracing-reporting")] +mod reporting { + pub fn report_error_to_app(type_name: String, message: String) { + tracing::event!(target: "app-services-error-reporter::error", tracing::Level::ERROR, message, type_name); + } + + pub fn report_breadcrumb(message: String, module: String, line: u32, column: u32) { + tracing::event!(target: "app-services-error-reporter::breadcrumb", tracing::Level::INFO, message, module, line, column); + } +} + +pub use reporting::{report_breadcrumb, report_error_to_app}; pub use error_support_macros::handle_error; @@ -173,4 +213,4 @@ macro_rules! define_error { }; } -uniffi::include_scaffolding!("errorsupport"); +uniffi::setup_scaffolding!("errorsupport"); diff --git a/third_party/rust/error-support/src/macros.rs b/third_party/rust/error-support/src/macros.rs index 11bf6dbca519..e1714053e57e 100644 --- a/third_party/rust/error-support/src/macros.rs +++ b/third_party/rust/error-support/src/macros.rs @@ -20,7 +20,7 @@ macro_rules! report_error { ($type_name:expr, $($arg:tt)*) => { let message = std::format!($($arg)*); - ::log::warn!("report {}: {}", $type_name, message); + $crate::warn!("report {}: {}", $type_name, message); $crate::report_error_to_app($type_name.to_string(), message.to_string()); }; } @@ -50,7 +50,7 @@ macro_rules! breadcrumb { ($($arg:tt)*) => { { let message = std::format!($($arg)*); - ::log::info!("breadcrumb: {}", message); + $crate::info!("breadcrumb: {}", message); $crate::report_breadcrumb( message, std::module_path!().to_string(), diff --git a/third_party/rust/error-support/src/reporting.rs b/third_party/rust/error-support/src/reporting.rs index cea7375d8895..2da314be41a8 100644 --- a/third_party/rust/error-support/src/reporting.rs +++ b/third_party/rust/error-support/src/reporting.rs @@ -4,7 +4,6 @@ use parking_lot::RwLock; use std::sync::atomic::{AtomicU32, Ordering}; -use std::sync::{Arc, Mutex}; /// Counter for breadcrumb messages /// @@ -29,6 +28,7 @@ fn get_breadcrumb_counter_value() -> u32 { /// The application that's consuming application-services implements this via a UniFFI callback /// interface, then calls `set_application_error_reporter()` to setup a global /// ApplicationErrorReporter. +#[uniffi::export(callback_interface)] pub trait ApplicationErrorReporter: Sync + Send { /// Send an error report to a Sentry-like error reporting system /// @@ -50,10 +50,15 @@ lazy_static::lazy_static! { pub(crate) static ref APPLICATION_ERROR_REPORTER: RwLock> = RwLock::new(Box::new(DefaultApplicationErrorReporter)); } -pub fn set_application_error_reporter(reporter: Box) { - *APPLICATION_ERROR_REPORTER.write() = reporter; +/// Set the global error reporter. This is typically done early in startup. +#[uniffi::export] +pub fn set_application_error_reporter(error_reporter: Box) { + *APPLICATION_ERROR_REPORTER.write() = error_reporter; } +/// Unset the global error reporter. This is typically done at shutdown for +/// platforms that want to cleanup references like Desktop. +#[uniffi::export] pub fn unset_application_error_reporter() { *APPLICATION_ERROR_REPORTER.write() = Box::new(DefaultApplicationErrorReporter) } @@ -70,59 +75,3 @@ pub fn report_breadcrumb(message: String, module: String, line: u32, column: u32 .read() .report_breadcrumb(message, module, line, column); } - -// Test error reporter that captures reported errors -// You should use this when you want to validate that `report_error` actually reports what you -// epect and -#[derive(Default)] -pub struct TestErrorReporter { - errors: Mutex>, -} - -impl TestErrorReporter { - pub fn new() -> Self { - Self { - errors: Mutex::new(Vec::new()), - } - } - - pub fn get_errors(&self) -> Vec<(String, String)> { - self.errors.lock().unwrap().clone() - } -} - -impl ApplicationErrorReporter for TestErrorReporter { - fn report_error(&self, type_name: String, message: String) { - if let Ok(mut errors) = self.errors.lock() { - errors.push((type_name, message)); - } - } - - fn report_breadcrumb(&self, _message: String, _module: String, _line: u32, _column: u32) {} -} - -/// An adapter that implements `ApplicationErrorReporter` and -/// delegates all calls to an `Arc`. -/// -/// Because `set_application_error_reporter` requires a -/// `Box`, we can't directly pass -/// an `Arc`; this adapter solves the mismatch. -pub struct ArcReporterAdapter { - inner: Arc, -} - -impl ArcReporterAdapter { - pub fn new(inner: Arc) -> Self { - Self { inner } - } -} - -impl ApplicationErrorReporter for ArcReporterAdapter { - fn report_error(&self, type_name: String, message: String) { - self.inner.report_error(type_name, message) - } - - fn report_breadcrumb(&self, message: String, module: String, line: u32, column: u32) { - self.inner.report_breadcrumb(message, module, line, column) - } -} diff --git a/third_party/rust/relevancy/.cargo-checksum.json b/third_party/rust/relevancy/.cargo-checksum.json index bac2f04d9313..62535f20eca4 100644 --- a/third_party/rust/relevancy/.cargo-checksum.json +++ b/third_party/rust/relevancy/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"fa569d53ba068f1626419e3910775ad6b5fce69f17a41a342640cba42a57f291","src/bin/generate-test-data.rs":"7cc80b56929091d02675b9dd9bf4c657a95cda502656cf2ec8d91f56d7a393c7","src/db.rs":"d9dd44501ee3b19c696d8830d3036f7bfe0e8ad7751d5a057f5d8295ebf0bd4f","src/error.rs":"3a1308e65440769d9435fc95528d4ef42994c84d88e1da04ba058491dea387c4","src/ingest.rs":"04ae6d4c65a46fa96364fc39018502de172a4393bf42bd3ede2865313e7977e5","src/interest.rs":"e4369a1280867438bca12746f71288a03b4d5e180e156f4bc0335046012565f7","src/lib.rs":"8f7408a4bebb882441b697cc16356a8d02342f57ebada515e289ce813e9f5e24","src/ranker.rs":"e71414fe79ade26f3c79dceb5211af4f37984a9cded8c938dc1da8d8d28c2ad3","src/rs.rs":"e897443bd4d8d308effeae55a955d237d22e823b5d5abfb271a25b5796ebd419","src/schema.rs":"38ea82679da2729a571aad936f96469e732ec1c104d7c21fd869842f7a5f30a3","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"f75eb2eab3ddc2e4a687f2d6d42bbf15d465f421118e0082a8c7440c285c7d9a","src/bin/generate-test-data.rs":"7cc80b56929091d02675b9dd9bf4c657a95cda502656cf2ec8d91f56d7a393c7","src/db.rs":"d9dd44501ee3b19c696d8830d3036f7bfe0e8ad7751d5a057f5d8295ebf0bd4f","src/error.rs":"3a1308e65440769d9435fc95528d4ef42994c84d88e1da04ba058491dea387c4","src/ingest.rs":"194eefe22aa012d863675005548041495e71a0adc95f5e59d1124b8990de156c","src/interest.rs":"e4369a1280867438bca12746f71288a03b4d5e180e156f4bc0335046012565f7","src/lib.rs":"6caa17ba27774941fce73602357acaf279645a19cd70459636e507b247da255f","src/ranker.rs":"e71414fe79ade26f3c79dceb5211af4f37984a9cded8c938dc1da8d8d28c2ad3","src/rs.rs":"e897443bd4d8d308effeae55a955d237d22e823b5d5abfb271a25b5796ebd419","src/schema.rs":"38ea82679da2729a571aad936f96469e732ec1c104d7c21fd869842f7a5f30a3","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/relevancy/Cargo.toml b/third_party/rust/relevancy/Cargo.toml index 8673080e0c0b..cf3711b8bd62 100644 --- a/third_party/rust/relevancy/Cargo.toml +++ b/third_party/rust/relevancy/Cargo.toml @@ -37,7 +37,6 @@ path = "src/bin/generate-test-data.rs" [dependencies] anyhow = "1.0" base64 = "0.21.2" -log = "0.4" md-5 = "0.10" parking_lot = ">=0.11,<=0.12" rand = "0.8" diff --git a/third_party/rust/relevancy/src/ingest.rs b/third_party/rust/relevancy/src/ingest.rs index d0b0f60b16a7..98000d730cca 100644 --- a/third_party/rust/relevancy/src/ingest.rs +++ b/third_party/rust/relevancy/src/ingest.rs @@ -28,7 +28,7 @@ pub fn ensure_interest_data_populated( db.read_write(move |dao| insert_interest_data(data, dao))?; } Err(e) => { - log::warn!("error fetching interest data: {e}"); + crate::warn!("error fetching interest data: {e}"); return Err(Error::FetchInterestDataError); } } diff --git a/third_party/rust/relevancy/src/lib.rs b/third_party/rust/relevancy/src/lib.rs index 2eea8d64abd0..b279e940dcd4 100644 --- a/third_party/rust/relevancy/src/lib.rs +++ b/third_party/rust/relevancy/src/lib.rs @@ -27,6 +27,9 @@ use remote_settings::{RemoteSettingsClient, RemoteSettingsService}; pub use db::RelevancyDb; pub use error::{ApiResult, Error, RelevancyApiError, Result}; +// reexport logging helpers. +pub use error_support::{debug, error, info, trace, warn}; + pub use interest::{Interest, InterestVector}; pub use ranker::score; @@ -195,7 +198,7 @@ impl RelevancyStoreInner { let mut interest_vector = InterestVector::default(); for url in top_urls_by_frecency { let interest_count = self.db.read(|dao| dao.get_url_interest_vector(&url))?; - log::trace!("classified: {url} {}", interest_count.summary()); + crate::trace!("classified: {url} {}", interest_count.summary()); interest_vector = interest_vector + interest_count; } Ok(interest_vector) diff --git a/third_party/rust/remote_settings/.cargo-checksum.json b/third_party/rust/remote_settings/.cargo-checksum.json index e38f22f858f2..b73e37ac56f3 100644 --- a/third_party/rust/remote_settings/.cargo-checksum.json +++ b/third_party/rust/remote_settings/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"00d8e28963e324f906faf95b3891030103f4486b8491e8d8228b0778d3fa143f","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256":"fdadf15c6eae7933c3d254ae6311112e0bc8a422c38c758189dbe6a4d7f6b718","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256.meta.json":"6ed1e1c390a45360590e5a1e6d7823218e7b10860581646ddb5e368143aa72fc","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea":"b75ef04a805325e303c4195833cdd077d3d406f360b25b72502fc55880b9150b","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea.meta.json":"0d4cce0ed0dc6b2c46651bea32fc3cc2facfe8b341e1022b65f2cd2231f6b713","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410":"a7493c6a9d70d60acccf73f62dcbc127a580469570aee60b7482cd42cdb59f69","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410.meta.json":"d33a128c92b96af2e643158ed3b861d3726bd67a59907fed0795ab2210c82b96","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937":"7042293af6b04e421cb7b68dc599ac644b76939cdcf5970159e44f658dd6a0cc","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937.meta.json":"d6523508334a67b201326591606d7e225a04fc53fdce2c1b4d8afac1b41af6b0","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2":"64800e32b24b2c8c0582750e1657426d56abd74b65682e20e892f82710d120b6","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2.meta.json":"56fb61a078cc45abf7bc3b8fe89b60ef75f3b86ea61d63084749607c4662bbef","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b":"62d2faa3a8322b1f643aab6e045837500ebe3049c5cb140cb44c4dfc7290337a","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b.meta.json":"de134ed423a2bd92b4ad8cdf631aad6a83cc2c30f8df9ee251a435ee9f46f28f","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f":"3b88f3ef3cbfaed127d679ec7e44a44fe8dcad688feb89a70a1a9447c1460d15","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f.meta.json":"c35210da5afc11b3af156baf46c23fa523dafac7e8cb2738b4caef80ed48c72e","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c":"828c3ca82e9be483ae583e5a705dde57b24fd8431e192e3a2d0809871992afa5","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c.meta.json":"aa5483b5c65427c028a676b2fc13892f6fcaf602613183962744c43ca146d86a","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335":"723ac3228124926537d5a61284d60e198a52895195f9f69b967c578ef7a012ad","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335.meta.json":"d754b38d7e2f79e651d5fe110a7bb9855e0f7269e177be6d047453a36a52a4c5","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca":"16ea89d4baa39529d7a84d5152867a4c6ed6867198c4dfa1648b1f43ce6a3f6f","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca.meta.json":"7edb361a6610fdabb431a58bc170b7df3f179ca1fadebae6f2e98777b64b35c5","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36":"774f0a7a613c6c5bea642e3628fa7436851de79e7da9713ad0c96d5db7f44300","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36.meta.json":"194cb07dd29fd66121f05bbef38291e894291adcbc4c63c373b5f72f6f2e245e","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f":"a64f553b79fbb8c45734310dac401ad253ccd05aeabfa58bb5541daa6d8caf70","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f.meta.json":"6e56cf6a9470f575b283e40ed6a049e9dbffadcb59fa74a0f941b431c444d795","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b":"4f409c3ffc67cfa870b05e4089b6ffc3fc81448fa60afba447f0177cd1192b1e","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b.meta.json":"686c72d6cd220285d8b97af55474198027eab1b1af7ed89508c8935c9e00e7d4","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427":"c2718c5e416670426475dd8cc496f5464bf95224e8f8f0a72b695360ddc917c0","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427.meta.json":"a941fc27ca88b56eccbdec380ce2d3b911f4c62e4aba1f5399bc4498c6601d94","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c":"755b8939c63b1fcc9acd05cd33ffed675397516d37b5bd8f3a03875e25d3fb43","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c.meta.json":"25cafe7d629c6b006e15dee98987c26ef509f348ed0350a3ccf1f06838db86f3","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11.meta.json":"e6b95ca29bf3e750819cf890ae8e879ac506d54b918c3c0ab065adc16a131188","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791":"92da7ef030e1d3ed97235748156383e5d75fa6d2744bd124334ab47dc0b689a1","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791.meta.json":"21d1320d60c981b9c9248b9b186fc49f9d95046a817d7a3145f48465236087e8","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171":"189ed3031a2cefd3150c9e5b37bee1ffbc1f7850f7ac0621e4b8d262f2c1048c","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171.meta.json":"0a401871b82f1c1cbca91232fd643be1cc1a76c07a48830eaa2a47cdfafb1f14","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2":"9140bd1b30953f41bc758d2c0ecc873f5163e4f51126c278991eccd38589c541","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2.meta.json":"805d8ce33bac4611ce12d1f84ef431313555d76bf996264736e401ceb6dabe98","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1":"adb29f6fd95956401630d94967381ac473f57215d96a5bcf500a00e747731380","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1.meta.json":"27a6f994c2c7653a33d380ac13c4cfbc00f543a92f229426aa71d85b1f968357","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532":"02f54211387baa59e4246356dc7344e48f39a412f2e5993d7f403aa538df7276","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532.meta.json":"2df77daeeef5892fdb7fdeecffb804638bd0d2f7da5b9e617f01303d786dcd09","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d":"877fb3aca13d2a7c656df1f94df3fa052afbb40b65c99ba5382392ff5499016e","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d.meta.json":"d1c75915fdc86461e755cd08e670b01da41cd3d76688afe692f841733a9b7ee0","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41":"9cd3da38e3938549434d1c3cba6fed249ffa7d91d9a6d7ffb5f4184f527cac76","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41.meta.json":"8506d9438825f2dc34875e04e0212e22a2652c5c43aa93e4d184d59ec765316f","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05":"4f1bfbfec1441bd9a304ca7f3b8fd54130e94df185f7b28bb17c86ba517e13b7","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05.meta.json":"f7d37f9c8b87480539cd981f463790c99ed15b2ffc5e3ff4786dd11c25228df4","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66":"f895a965b68d02e7391cc4504d9be75e1ba7f9b50a1dd59af77bb44a7769c08c","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66.meta.json":"d782d80f8187cf8051be89c6b8a1ef4700e0b84dcda006843d1fd2f266c4419b","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a":"e9849089ffced59563896974afee0fceedac7fc8455bbeaa5bae230f54c933d9","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a.meta.json":"0e5a64c06ea0ae875e8e0fdc850feddf5a8714b8290293dcd100d455de32ace0","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27":"dd5cab3711f778677859e86000a127ed07a6175e8e58aecb0fba71b825ce76d7","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27.meta.json":"0a947797180fdaf031a9c2d2f841b88243c90ff85f0af873f99ddd770fc59e8b","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb":"0a653ea57472694ac05623d9b237e479232a0d65683d05f89661f996054e3276","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb.meta.json":"bb8a256f72b37166fea2ecd4c3a59f49615854a7210e6963f2571f8dcb3d3a3f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173":"31a793dad95b5ffd02d39ebf14fc40877596f418f5926247487265034181dc8f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173.meta.json":"8c744e9d2f218256e63f1b1a2193f2fc4a7b980e72464e8d57fbe150446f2efc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522":"5aad083bfcef256d433c1ffa571b814d16f61832bcd7565bf03909011f6a0bfc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522.meta.json":"4a8f0c4e4ee643faa2f8d8cc4ddb8f87d14c740e8c9252223f826181c0117741","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c":"ca8f102ac4f35189ebcb786d080843b603b234f89b8d8b1c0ef27a0ab7148182","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c.meta.json":"60a7975cd79156623b0ca58be4110d152e50b6e9caaaa211dad1cd37eabb0345","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88":"3376e14529ed2e96c7dc491b3bf11914d7c8ff47a068311b2432c086c2ae0f28","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88.meta.json":"3a94a78a846f312c85c0609971b153aaba9819e2b657f25e3b0648a3956933d1","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa":"71413ef23ac14ce2b7bb76f7f5d16b2df267239841a88ddab36b129481e00616","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa.meta.json":"2f16dd51ade97a327d4e5f14d689f822a5c9061b9b27810bbccbf2f406a5e56f","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e":"24daa27a3234d01b5add42e027b0a34000d0ab47c17fe3924c2ca267b7b61c19","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e.meta.json":"308d345dbcfd7583e5f7460d34caf3b63d01b747a6e060a2b0971bf00ed2b22c","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131":"912d20feefcba57d43bffff5e245b8c1e3865155ed686d8ad253bbab71116e83","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131.meta.json":"3ec071b0a2940cd8892a72bd28d44237aecfd20d88303661348257ddb98aee43","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb":"e988445d87afe0d285bea251705fc23eb70ac42426ab0d7a69d9276585c5573c","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb.meta.json":"273dd09cad2a62459cc062e3b39b835d55a06b10cb7d5149aad77dd55451821f","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb":"8dc2e75e6792b8374b20621fa2151ac24b4626e5c1f6a1abec4f912746441859","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb.meta.json":"21d2522ab4e47477e72da3a2d2223e50e55fef442e2ba736d56df1e09593d76f","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851":"27541cb376bdda829a6cf9cefd13da112728881e3daa4ac3c1178d4ce15f1e8b","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851.meta.json":"3aea5d0652172940ac33e32628dcc6a03b79fe686c6de752482c8e3ae5cd70eb","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451":"b0c6d1850265e3c946917232ca6c6ace3dad23347bfab4f81351eac569326d34","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451.meta.json":"5a723c8f04bffa33a69a7054d30a4816caf1a3924081c85e1d9770126f761a96","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361":"a1fd5d127a5f2590ddcd439b7a2abb3456b48217ea11daf0345b26e108f520e6","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361.meta.json":"5cb0ebdde367b9754ddf6cbd01150414d27977b2d4c5f65cd6bbb89989388f3b","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36":"33ca72f1eac56793d1fd811189cedef98004a067c85b1143083b564814a4b0db","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36.meta.json":"d97eca8063cc17b99c81c55d4ff121d765c793e006ed252fec5f9539bd0fc339","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e":"ca3cc8786977f6ffeb0546ff8f3bb2b7fd240d1956fbf86777dbf0e8bec9c03b","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e.meta.json":"45274d848d1f6d398563bb46a2bfa3eee40ff16a5dbf0bbc8904db442f80702c","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a":"6ba1f0fd1d12014cab32f74daab24dfa16fb26613ace20a1e595267621038a07","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a.meta.json":"107547059360c3658dcf187a546ffb52bb23fa385e1338151043bebe82bbf640","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810":"f8780adb4d7b28f2f881db4ca7b697d8fc916cd9fa834ccc445fe7d4b72a6cc7","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810.meta.json":"5401603c7abbc6ca5bdddb8f9cca7eee2e26e5721cc73f23d95f600d5421d431","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716":"5d53ef1866a08cc29011f5f2a9ce99bbf37cf42e80de7f0e8cc30d13337e8187","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716.meta.json":"4e8ea36e3d659eb22ac7c86498003ca8885bab9c40685bb8ca7796a8230201da","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4":"98dca7e24cad0a1be96ef2c323e9759beb63c72440756f887e2482d9ce8e8969","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4.meta.json":"1070966901fe9db82b71bfa74ddeedd4f23ab2ed1eddaf201634e06a604e6006","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8":"3426b5100a6bdb45f8039f0c71a6b68193750ba7bae5b36e5ed31b2b7f372cda","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8.meta.json":"3447cd050619c1d2e5859147ab894a43da75235a580219306d8629e28a7a3eb5","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b":"ca6e972004f62355c1ea97656bc2328e1643971bdecab9c6b563d45593b8122e","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b.meta.json":"c4e3c9e6426e6f35410c287eef95b3e2134e54409e462f02dd440876c06b1bb4","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98":"6b1b073183eb0012daea0dce351a94d395c8a0b531b610e56eac52b3d1d1da0e","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98.meta.json":"cceb55c68db8dddd23d064364a281e982069bfe2bb55eba7d282fffcec2aa89f","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd":"617dec5d635efb0a12d0de935c6999ef0249f4a63c62bdcb96551518bc3d1812","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd.meta.json":"06cf576ca882bd7c2d54c18329e21e5b1a9cb7732d4954b52cbfa52979a67765","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3":"d994f806b1e4225b50be5ab681b2cecf845cc216a19a432d878cea3cb815bafd","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3.meta.json":"67524e18799023a017c7d9db1b9ba5c9cc3090d20f8154449a8f44ba22719104","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d":"1bf68aca7bfc75ca8485c3dac9a1daa13c1a3eb480688c32262096af6076adfa","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d.meta.json":"4ab103bba0f8fde581c3950c6c08cfcf6786104d8cbcba240499308f26958d04","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf":"66612f999921d892645c8a2b37aa5dad17b134e7fdaed375a683baec7fc10697","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf.meta.json":"f985ffbde6cf6ef972b6798c9336922dcfa29ca9a31e3aa4fae1962e069bdb0c","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b":"c3e8300801c5c585662f14fd8e819d635efd9830783dc3c631212927866e9898","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b.meta.json":"f7fd846d6717131e75865f8f5ed562e88f40be3dcf1603f2660b425dedabc7d1","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3":"076352591c7077af4af5771918f80b5da9c6bf479327cc68390abdb158f3ec03","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3.meta.json":"229139bca53bc63bd59b8f261f36c11fbe76b2b45dfeac2580261cf290c41365","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21":"1474c93e49c209aca2a2df2acb61b64574805106bead6edebd67287de21920e0","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21.meta.json":"6fd72c11afb4249d0166d8d98c552ee02d73c0e07f0578bfd3d7e67d70bcaee3","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6":"601d72e7abde5ec864b3d8ca0031896f769107670b84c66053062481a56d8665","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6.meta.json":"f299a7d56c5552fc592c66073d3e1e1d16ce4a99e935dcc0cad7dafcad6b9e3b","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943":"150765e8e9b985ba5b820ac9b8e7623023d5a0e24f94663d5e9203d8d7598059","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943.meta.json":"c5cc89d5f24ef1fa40b1c47c2e97eaeb01439b8d3b186b9c2fe716c94ead30f2","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd":"5b2c34b3c4e8dd898b664dba6c3786e2ff9869eff55d673aa48361f11325ed07","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd.meta.json":"b757806fd1b922d81bbecab94c73d3db98cfc2aa2791a4d5137112f795a732ee","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9":"865d76c8175a8f11dedc93f0bc212242a97a8a76adac870e8249368cecc81402","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9.meta.json":"22594c8870cbabe5fc5d2637509235202502661b466e9e37c5878716f323a34f","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9":"97a68f0b948b68bbf389a9ef43e2fe6c31ff8dc7889c939fdfdea79378576c67","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9.meta.json":"1eccc999dcd377af84cf63ed60b7ef23d5d4b936a1e465d12349a5366b1b012d","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c":"247aa26993083705ce99a8e5612cdf262aca98cde86ba19afc964329ba95986a","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c.meta.json":"06fc893d29cf406519611da9d1993a13bd9134192940c12bf64536ea571db4f0","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785":"809697f48848e7c3638d5f3e0b224ea60b3800504e7bd8417854d55989b85196","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785.meta.json":"0d9baef39747776500e5b83e72cd9d901fc09ac08247368dd2117bb4ec011f54","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a":"c971ee33b8c0a57349669d957bf73070b0632b128c94748e845b57d5e15221a4","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a.meta.json":"8ec4f6a7826966f2ff82632ef527366db3452ebc40c90a557602111f0ea956c9","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5":"aa46b3d1ed8557e5bc7e71988cc6c46b00363b890d2a781973f9dc9073f8dd31","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5.meta.json":"a06682b589df8dd63b1f25c01630ead55a89217f72c0bc04b391829af3fef59f","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636":"91d17ba44192a6430ffdb447ff3a11533ef964628f67c13480cc9470212d3d65","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636.meta.json":"ce26ab2382a7a67a55688330dd74127b4a980610f4030bde8eaaa20b81306559","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc":"6da5620880159634213e197fafca1dde0272153be3e4590818533fab8d040770","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc.meta.json":"0c3c0eb832be884f25186395b8bf08cdbe0a6e2845b9e55e7cbea5d0f183ed7d","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d":"c4d88cfa5262f6d2cf76b167281d25821c9e1770684b739ed6ad3cf7277a121b","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d.meta.json":"a40c37a5150e3745849f67305fe2fe1e06ef1c3901f6dc604a8e3f6c94e7b624","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f":"3a9d06951c7c9d2c19cd00533a760b0f8755b1e2e718af81c710297d030fbe44","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f.meta.json":"3f353e083d7a885f6d59d36c9276a2d325686a533cf8c502cd41a10172e763ea","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136.meta.json":"740f77dcc93ece89fd55557baf399a4464373c81154b0a9758b8622f6c458253","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-icons.json":"76955459bdcd7ea46a67737309ed65c3497b9dd71c66a8f978aa3448001ad33b","dumps/main/search-config-v2.json":"299a8f3f0b9a7ba4330fc8bd8e1b2ce65804cdb452b86d7e40ec30a1bd02d6a2","dumps/main/search-telemetry-v2.json":"b0f3ba5c0b4d9051e87b84ebb90abf4477a56b1999c033deca3ce3c8e4a3f7f9","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"04e47a0d01215dc83ac234b4f740b63a53daa0431eba2b8a4702a95e18a95737","src/config.rs":"e042741248e7e501b4a97745bebb681006a45e0cc243225a05b9fca2f8126e82","src/context.rs":"43bab81026b6f1a2509d129e806fffd09ba80110d656798a02589985017a3c21","src/error.rs":"80aeb1093682acea7350f4876e1501d70c5daa822d26babace80d004e2a34bce","src/jexl_filter.rs":"48a9d960e05dae444421f7c4ceeb45eab656f03f1e7071215c8e8d39aab56b54","src/lib.rs":"5555139a8fcb77f91e67946ec4284e1e945a4de1f97b1b95112bca36b846a61a","src/macros.rs":"6b06d0ba42ee95235bfd71bac1a0eed02f60c894775ebee64165648b10e932c4","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"a02cd02f251b73e160c019f8144d2ad9b4a17da525c492b4450ecfa126241cb7","src/signatures.rs":"baa2dae76abd8166158fea4676e67e17c17b65af6968de52768350409dbd7092","src/storage.rs":"c33dd92914770e96d3d44dbb9e95f512ce54261710a42c7cf4a896be348c529e","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"10abc3f5ec54cd2795c91cd5e1793347b958269c8cf3c6b99fdbd0666cf228bf","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256":"fdadf15c6eae7933c3d254ae6311112e0bc8a422c38c758189dbe6a4d7f6b718","dumps/main/attachments/search-config-icons/001500a9-1a6c-3f5a-ba15-a5f5a075d256.meta.json":"6ed1e1c390a45360590e5a1e6d7823218e7b10860581646ddb5e368143aa72fc","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea":"b75ef04a805325e303c4195833cdd077d3d406f360b25b72502fc55880b9150b","dumps/main/attachments/search-config-icons/06cf7432-efd7-f244-927b-5e423005e1ea.meta.json":"0d4cce0ed0dc6b2c46651bea32fc3cc2facfe8b341e1022b65f2cd2231f6b713","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410":"a7493c6a9d70d60acccf73f62dcbc127a580469570aee60b7482cd42cdb59f69","dumps/main/attachments/search-config-icons/0a57b0cf-34f0-4d09-96e4-dbd6e3355410.meta.json":"d33a128c92b96af2e643158ed3b861d3726bd67a59907fed0795ab2210c82b96","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937":"7042293af6b04e421cb7b68dc599ac644b76939cdcf5970159e44f658dd6a0cc","dumps/main/attachments/search-config-icons/0d7668a8-c3f4-cfee-cbc8-536511528937.meta.json":"d6523508334a67b201326591606d7e225a04fc53fdce2c1b4d8afac1b41af6b0","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2":"64800e32b24b2c8c0582750e1657426d56abd74b65682e20e892f82710d120b6","dumps/main/attachments/search-config-icons/0eec5640-6fde-d6fe-322a-c72c6d5bd5a2.meta.json":"56fb61a078cc45abf7bc3b8fe89b60ef75f3b86ea61d63084749607c4662bbef","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b":"62d2faa3a8322b1f643aab6e045837500ebe3049c5cb140cb44c4dfc7290337a","dumps/main/attachments/search-config-icons/101ce01d-2691-b729-7f16-9d389803384b.meta.json":"de134ed423a2bd92b4ad8cdf631aad6a83cc2c30f8df9ee251a435ee9f46f28f","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f":"3b88f3ef3cbfaed127d679ec7e44a44fe8dcad688feb89a70a1a9447c1460d15","dumps/main/attachments/search-config-icons/177aba42-9bed-4078-e36b-580e8794cd7f.meta.json":"c35210da5afc11b3af156baf46c23fa523dafac7e8cb2738b4caef80ed48c72e","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c":"828c3ca82e9be483ae583e5a705dde57b24fd8431e192e3a2d0809871992afa5","dumps/main/attachments/search-config-icons/25de0352-aabb-d31f-15f7-bf9299fb004c.meta.json":"aa5483b5c65427c028a676b2fc13892f6fcaf602613183962744c43ca146d86a","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335":"723ac3228124926537d5a61284d60e198a52895195f9f69b967c578ef7a012ad","dumps/main/attachments/search-config-icons/2bbe48f4-d3b8-c9e0-86e3-a54c37ec3335.meta.json":"d754b38d7e2f79e651d5fe110a7bb9855e0f7269e177be6d047453a36a52a4c5","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca":"16ea89d4baa39529d7a84d5152867a4c6ed6867198c4dfa1648b1f43ce6a3f6f","dumps/main/attachments/search-config-icons/2e835b0e-9709-d1bb-9725-87f59f3445ca.meta.json":"7edb361a6610fdabb431a58bc170b7df3f179ca1fadebae6f2e98777b64b35c5","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36":"774f0a7a613c6c5bea642e3628fa7436851de79e7da9713ad0c96d5db7f44300","dumps/main/attachments/search-config-icons/2ecca3f8-c1ef-43cc-b053-886d1ae46c36.meta.json":"194cb07dd29fd66121f05bbef38291e894291adcbc4c63c373b5f72f6f2e245e","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f":"a64f553b79fbb8c45734310dac401ad253ccd05aeabfa58bb5541daa6d8caf70","dumps/main/attachments/search-config-icons/32d26d19-aeb0-5c01-32e8-f8970be9246f.meta.json":"6e56cf6a9470f575b283e40ed6a049e9dbffadcb59fa74a0f941b431c444d795","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b":"4f409c3ffc67cfa870b05e4089b6ffc3fc81448fa60afba447f0177cd1192b1e","dumps/main/attachments/search-config-icons/39d0b17d-c020-4890-932f-83c0f6ed130b.meta.json":"686c72d6cd220285d8b97af55474198027eab1b1af7ed89508c8935c9e00e7d4","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427":"c2718c5e416670426475dd8cc496f5464bf95224e8f8f0a72b695360ddc917c0","dumps/main/attachments/search-config-icons/41135a88-093d-4077-873b-9de1ae133427.meta.json":"a941fc27ca88b56eccbdec380ce2d3b911f4c62e4aba1f5399bc4498c6601d94","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c":"755b8939c63b1fcc9acd05cd33ffed675397516d37b5bd8f3a03875e25d3fb43","dumps/main/attachments/search-config-icons/41f0d805-3775-4988-8d8c-5ad8ccd86d1c.meta.json":"25cafe7d629c6b006e15dee98987c26ef509f348ed0350a3ccf1f06838db86f3","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11.meta.json":"e6b95ca29bf3e750819cf890ae8e879ac506d54b918c3c0ab065adc16a131188","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791":"92da7ef030e1d3ed97235748156383e5d75fa6d2744bd124334ab47dc0b689a1","dumps/main/attachments/search-config-icons/48c72361-cd67-412e-bd7f-f81a43c10791.meta.json":"21d1320d60c981b9c9248b9b186fc49f9d95046a817d7a3145f48465236087e8","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171":"189ed3031a2cefd3150c9e5b37bee1ffbc1f7850f7ac0621e4b8d262f2c1048c","dumps/main/attachments/search-config-icons/4e271681-3e0f-91ac-9750-03f665efc171.meta.json":"0a401871b82f1c1cbca91232fd643be1cc1a76c07a48830eaa2a47cdfafb1f14","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2":"9140bd1b30953f41bc758d2c0ecc873f5163e4f51126c278991eccd38589c541","dumps/main/attachments/search-config-icons/50f6171f-8e7a-b41b-862e-f97397038fb2.meta.json":"805d8ce33bac4611ce12d1f84ef431313555d76bf996264736e401ceb6dabe98","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1":"adb29f6fd95956401630d94967381ac473f57215d96a5bcf500a00e747731380","dumps/main/attachments/search-config-icons/5203dd03-2c55-4b53-9c60-58258d587be1.meta.json":"27a6f994c2c7653a33d380ac13c4cfbc00f543a92f229426aa71d85b1f968357","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532":"02f54211387baa59e4246356dc7344e48f39a412f2e5993d7f403aa538df7276","dumps/main/attachments/search-config-icons/5914932e-66ba-4126-8be5-d37beadd9532.meta.json":"2df77daeeef5892fdb7fdeecffb804638bd0d2f7da5b9e617f01303d786dcd09","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d":"877fb3aca13d2a7c656df1f94df3fa052afbb40b65c99ba5382392ff5499016e","dumps/main/attachments/search-config-icons/5ded611d-44b2-dc46-fd67-fb116888d75d.meta.json":"d1c75915fdc86461e755cd08e670b01da41cd3d76688afe692f841733a9b7ee0","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41":"9cd3da38e3938549434d1c3cba6fed249ffa7d91d9a6d7ffb5f4184f527cac76","dumps/main/attachments/search-config-icons/5e03d6f4-6ee9-8bc8-cf22-7a5f2cf55c41.meta.json":"8506d9438825f2dc34875e04e0212e22a2652c5c43aa93e4d184d59ec765316f","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05":"4f1bfbfec1441bd9a304ca7f3b8fd54130e94df185f7b28bb17c86ba517e13b7","dumps/main/attachments/search-config-icons/6644f26f-28ea-4222-929d-5d43a02dae05.meta.json":"f7d37f9c8b87480539cd981f463790c99ed15b2ffc5e3ff4786dd11c25228df4","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66":"f895a965b68d02e7391cc4504d9be75e1ba7f9b50a1dd59af77bb44a7769c08c","dumps/main/attachments/search-config-icons/6d10d702-7bd6-1452-90a5-3df665a38f66.meta.json":"d782d80f8187cf8051be89c6b8a1ef4700e0b84dcda006843d1fd2f266c4419b","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a":"e9849089ffced59563896974afee0fceedac7fc8455bbeaa5bae230f54c933d9","dumps/main/attachments/search-config-icons/6e36a151-e4f4-4117-9067-1ca82c47d01a.meta.json":"0e5a64c06ea0ae875e8e0fdc850feddf5a8714b8290293dcd100d455de32ace0","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27":"dd5cab3711f778677859e86000a127ed07a6175e8e58aecb0fba71b825ce76d7","dumps/main/attachments/search-config-icons/6f4da442-d31e-28f8-03af-797d16bbdd27.meta.json":"0a947797180fdaf031a9c2d2f841b88243c90ff85f0af873f99ddd770fc59e8b","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb":"0a653ea57472694ac05623d9b237e479232a0d65683d05f89661f996054e3276","dumps/main/attachments/search-config-icons/7072564d-a573-4750-bf33-f0a07631c9eb.meta.json":"bb8a256f72b37166fea2ecd4c3a59f49615854a7210e6963f2571f8dcb3d3a3f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173":"31a793dad95b5ffd02d39ebf14fc40877596f418f5926247487265034181dc8f","dumps/main/attachments/search-config-icons/70fdd651-6c50-b7bb-09ec-7e85da259173.meta.json":"8c744e9d2f218256e63f1b1a2193f2fc4a7b980e72464e8d57fbe150446f2efc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522":"5aad083bfcef256d433c1ffa571b814d16f61832bcd7565bf03909011f6a0bfc","dumps/main/attachments/search-config-icons/71f41a0c-5b70-4116-b30f-e62089083522.meta.json":"4a8f0c4e4ee643faa2f8d8cc4ddb8f87d14c740e8c9252223f826181c0117741","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c":"ca8f102ac4f35189ebcb786d080843b603b234f89b8d8b1c0ef27a0ab7148182","dumps/main/attachments/search-config-icons/74793ce1-a918-a5eb-d3c0-2aadaff3c88c.meta.json":"60a7975cd79156623b0ca58be4110d152e50b6e9caaaa211dad1cd37eabb0345","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88":"3376e14529ed2e96c7dc491b3bf11914d7c8ff47a068311b2432c086c2ae0f28","dumps/main/attachments/search-config-icons/74f94dc2-caf6-4b90-b3d2-f3e2f7714d88.meta.json":"3a94a78a846f312c85c0609971b153aaba9819e2b657f25e3b0648a3956933d1","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa":"71413ef23ac14ce2b7bb76f7f5d16b2df267239841a88ddab36b129481e00616","dumps/main/attachments/search-config-icons/764e3b14-fe16-4feb-8384-124c516a5afa.meta.json":"2f16dd51ade97a327d4e5f14d689f822a5c9061b9b27810bbccbf2f406a5e56f","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e":"24daa27a3234d01b5add42e027b0a34000d0ab47c17fe3924c2ca267b7b61c19","dumps/main/attachments/search-config-icons/7bbe6c5c-fdb8-2845-a4f4-e1382e708a0e.meta.json":"308d345dbcfd7583e5f7460d34caf3b63d01b747a6e060a2b0971bf00ed2b22c","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131":"912d20feefcba57d43bffff5e245b8c1e3865155ed686d8ad253bbab71116e83","dumps/main/attachments/search-config-icons/7bf4ca37-e2b8-4d31-a1c3-979bc0e85131.meta.json":"3ec071b0a2940cd8892a72bd28d44237aecfd20d88303661348257ddb98aee43","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb":"e988445d87afe0d285bea251705fc23eb70ac42426ab0d7a69d9276585c5573c","dumps/main/attachments/search-config-icons/7c81cf98-7c11-4afd-8279-db89118a6dfb.meta.json":"273dd09cad2a62459cc062e3b39b835d55a06b10cb7d5149aad77dd55451821f","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb":"8dc2e75e6792b8374b20621fa2151ac24b4626e5c1f6a1abec4f912746441859","dumps/main/attachments/search-config-icons/7cb4d88a-d4df-45b2-87e4-f896eaf1bbdb.meta.json":"21d2522ab4e47477e72da3a2d2223e50e55fef442e2ba736d56df1e09593d76f","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851":"27541cb376bdda829a6cf9cefd13da112728881e3daa4ac3c1178d4ce15f1e8b","dumps/main/attachments/search-config-icons/7edaf4fe-a8a0-432b-86d2-bf75ebe80851.meta.json":"3aea5d0652172940ac33e32628dcc6a03b79fe686c6de752482c8e3ae5cd70eb","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451":"b0c6d1850265e3c946917232ca6c6ace3dad23347bfab4f81351eac569326d34","dumps/main/attachments/search-config-icons/7efbed51-813c-581d-d8d3-f8758434e451.meta.json":"5a723c8f04bffa33a69a7054d30a4816caf1a3924081c85e1d9770126f761a96","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361":"a1fd5d127a5f2590ddcd439b7a2abb3456b48217ea11daf0345b26e108f520e6","dumps/main/attachments/search-config-icons/84bb4962-e571-227a-9ef6-2ac5f2aac361.meta.json":"5cb0ebdde367b9754ddf6cbd01150414d27977b2d4c5f65cd6bbb89989388f3b","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36":"33ca72f1eac56793d1fd811189cedef98004a067c85b1143083b564814a4b0db","dumps/main/attachments/search-config-icons/87ac4cde-f581-398b-1e32-eb4079183b36.meta.json":"d97eca8063cc17b99c81c55d4ff121d765c793e006ed252fec5f9539bd0fc339","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e":"ca3cc8786977f6ffeb0546ff8f3bb2b7fd240d1956fbf86777dbf0e8bec9c03b","dumps/main/attachments/search-config-icons/8831ce10-b1e4-6eb4-4975-83c67457288e.meta.json":"45274d848d1f6d398563bb46a2bfa3eee40ff16a5dbf0bbc8904db442f80702c","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a":"6ba1f0fd1d12014cab32f74daab24dfa16fb26613ace20a1e595267621038a07","dumps/main/attachments/search-config-icons/890de5c4-0941-a116-473a-5d240e79497a.meta.json":"107547059360c3658dcf187a546ffb52bb23fa385e1338151043bebe82bbf640","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810":"f8780adb4d7b28f2f881db4ca7b697d8fc916cd9fa834ccc445fe7d4b72a6cc7","dumps/main/attachments/search-config-icons/8abb10a7-212f-46b5-a7b4-244f414e3810.meta.json":"5401603c7abbc6ca5bdddb8f9cca7eee2e26e5721cc73f23d95f600d5421d431","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716":"5d53ef1866a08cc29011f5f2a9ce99bbf37cf42e80de7f0e8cc30d13337e8187","dumps/main/attachments/search-config-icons/91a9672d-e945-8e1e-0996-aefdb0190716.meta.json":"4e8ea36e3d659eb22ac7c86498003ca8885bab9c40685bb8ca7796a8230201da","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4":"98dca7e24cad0a1be96ef2c323e9759beb63c72440756f887e2482d9ce8e8969","dumps/main/attachments/search-config-icons/94a84724-c30f-4767-ba42-01cc37fc31a4.meta.json":"1070966901fe9db82b71bfa74ddeedd4f23ab2ed1eddaf201634e06a604e6006","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8":"3426b5100a6bdb45f8039f0c71a6b68193750ba7bae5b36e5ed31b2b7f372cda","dumps/main/attachments/search-config-icons/95ed201d-4ab8-4cb8-831d-454f53cab0f8.meta.json":"3447cd050619c1d2e5859147ab894a43da75235a580219306d8629e28a7a3eb5","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b":"ca6e972004f62355c1ea97656bc2328e1643971bdecab9c6b563d45593b8122e","dumps/main/attachments/search-config-icons/96327a73-c433-5eb4-a16d-b090cadfb80b.meta.json":"c4e3c9e6426e6f35410c287eef95b3e2134e54409e462f02dd440876c06b1bb4","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98":"6b1b073183eb0012daea0dce351a94d395c8a0b531b610e56eac52b3d1d1da0e","dumps/main/attachments/search-config-icons/9802e63d-05ec-48ba-93f9-746e0981ad98.meta.json":"cceb55c68db8dddd23d064364a281e982069bfe2bb55eba7d282fffcec2aa89f","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd":"617dec5d635efb0a12d0de935c6999ef0249f4a63c62bdcb96551518bc3d1812","dumps/main/attachments/search-config-icons/a06db97d-1210-ea2e-5474-0e2f7d295bfd.meta.json":"06cf576ca882bd7c2d54c18329e21e5b1a9cb7732d4954b52cbfa52979a67765","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3":"d994f806b1e4225b50be5ab681b2cecf845cc216a19a432d878cea3cb815bafd","dumps/main/attachments/search-config-icons/a06dc3fd-4bdb-41f3-2ebc-4cbed06a9bd3.meta.json":"67524e18799023a017c7d9db1b9ba5c9cc3090d20f8154449a8f44ba22719104","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d":"1bf68aca7bfc75ca8485c3dac9a1daa13c1a3eb480688c32262096af6076adfa","dumps/main/attachments/search-config-icons/a2c7d4e9-f770-51e1-0963-3c2c8401631d.meta.json":"4ab103bba0f8fde581c3950c6c08cfcf6786104d8cbcba240499308f26958d04","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf":"66612f999921d892645c8a2b37aa5dad17b134e7fdaed375a683baec7fc10697","dumps/main/attachments/search-config-icons/a83f24e4-602c-47bd-930c-ad0947ee1adf.meta.json":"f985ffbde6cf6ef972b6798c9336922dcfa29ca9a31e3aa4fae1962e069bdb0c","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b":"c3e8300801c5c585662f14fd8e819d635efd9830783dc3c631212927866e9898","dumps/main/attachments/search-config-icons/b64f09fd-52d1-c48e-af23-4ce918e7bf3b.meta.json":"f7fd846d6717131e75865f8f5ed562e88f40be3dcf1603f2660b425dedabc7d1","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3":"076352591c7077af4af5771918f80b5da9c6bf479327cc68390abdb158f3ec03","dumps/main/attachments/search-config-icons/b882b24d-1776-4ef9-9016-0bdbd935eda3.meta.json":"229139bca53bc63bd59b8f261f36c11fbe76b2b45dfeac2580261cf290c41365","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21":"1474c93e49c209aca2a2df2acb61b64574805106bead6edebd67287de21920e0","dumps/main/attachments/search-config-icons/b8ca5a94-8fff-27ad-6e00-96e244a32e21.meta.json":"6fd72c11afb4249d0166d8d98c552ee02d73c0e07f0578bfd3d7e67d70bcaee3","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6":"601d72e7abde5ec864b3d8ca0031896f769107670b84c66053062481a56d8665","dumps/main/attachments/search-config-icons/b9424309-f601-4a69-98ca-ca68e65633e6.meta.json":"f299a7d56c5552fc592c66073d3e1e1d16ce4a99e935dcc0cad7dafcad6b9e3b","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943":"150765e8e9b985ba5b820ac9b8e7623023d5a0e24f94663d5e9203d8d7598059","dumps/main/attachments/search-config-icons/c411adc1-9661-4fb5-a4c1-8cfe74911943.meta.json":"c5cc89d5f24ef1fa40b1c47c2e97eaeb01439b8d3b186b9c2fe716c94ead30f2","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd":"5b2c34b3c4e8dd898b664dba6c3786e2ff9869eff55d673aa48361f11325ed07","dumps/main/attachments/search-config-icons/cbf9e891-d079-2b28-5617-283450d463dd.meta.json":"b757806fd1b922d81bbecab94c73d3db98cfc2aa2791a4d5137112f795a732ee","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9":"865d76c8175a8f11dedc93f0bc212242a97a8a76adac870e8249368cecc81402","dumps/main/attachments/search-config-icons/d87f251c-3e12-a8bf-e2d0-afd43d36c5f9.meta.json":"22594c8870cbabe5fc5d2637509235202502661b466e9e37c5878716f323a34f","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9":"97a68f0b948b68bbf389a9ef43e2fe6c31ff8dc7889c939fdfdea79378576c67","dumps/main/attachments/search-config-icons/db0e1627-ae89-4c25-8944-a9481d8512d9.meta.json":"1eccc999dcd377af84cf63ed60b7ef23d5d4b936a1e465d12349a5366b1b012d","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c":"247aa26993083705ce99a8e5612cdf262aca98cde86ba19afc964329ba95986a","dumps/main/attachments/search-config-icons/e02f23df-8d48-2b1b-3b5c-6dd27302c61c.meta.json":"06fc893d29cf406519611da9d1993a13bd9134192940c12bf64536ea571db4f0","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785":"809697f48848e7c3638d5f3e0b224ea60b3800504e7bd8417854d55989b85196","dumps/main/attachments/search-config-icons/e718e983-09aa-e8f6-b25f-cd4b395d4785.meta.json":"0d9baef39747776500e5b83e72cd9d901fc09ac08247368dd2117bb4ec011f54","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a":"c971ee33b8c0a57349669d957bf73070b0632b128c94748e845b57d5e15221a4","dumps/main/attachments/search-config-icons/e7547f62-187b-b641-d462-e54a3f813d9a.meta.json":"8ec4f6a7826966f2ff82632ef527366db3452ebc40c90a557602111f0ea956c9","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5":"aa46b3d1ed8557e5bc7e71988cc6c46b00363b890d2a781973f9dc9073f8dd31","dumps/main/attachments/search-config-icons/eb62e768-151b-45d1-9fe5-9e1d2a5991c5.meta.json":"a06682b589df8dd63b1f25c01630ead55a89217f72c0bc04b391829af3fef59f","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636":"91d17ba44192a6430ffdb447ff3a11533ef964628f67c13480cc9470212d3d65","dumps/main/attachments/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636.meta.json":"ce26ab2382a7a67a55688330dd74127b4a980610f4030bde8eaaa20b81306559","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc":"6da5620880159634213e197fafca1dde0272153be3e4590818533fab8d040770","dumps/main/attachments/search-config-icons/fa0fc42c-d91d-fca7-34eb-806ff46062dc.meta.json":"0c3c0eb832be884f25186395b8bf08cdbe0a6e2845b9e55e7cbea5d0f183ed7d","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d":"c4d88cfa5262f6d2cf76b167281d25821c9e1770684b739ed6ad3cf7277a121b","dumps/main/attachments/search-config-icons/fca3e3ee-56cd-f474-dc31-307fd24a891d.meta.json":"a40c37a5150e3745849f67305fe2fe1e06ef1c3901f6dc604a8e3f6c94e7b624","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f":"3a9d06951c7c9d2c19cd00533a760b0f8755b1e2e718af81c710297d030fbe44","dumps/main/attachments/search-config-icons/fe75ce3f-1545-400c-b28c-ad771054e69f.meta.json":"3f353e083d7a885f6d59d36c9276a2d325686a533cf8c502cd41a10172e763ea","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136":"d7fdfd971d874f2ec6f209df6f6b8173d126cd3f7a25daacb94de4259efbcf16","dumps/main/attachments/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136.meta.json":"740f77dcc93ece89fd55557baf399a4464373c81154b0a9758b8622f6c458253","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-icons.json":"76955459bdcd7ea46a67737309ed65c3497b9dd71c66a8f978aa3448001ad33b","dumps/main/search-config-v2.json":"299a8f3f0b9a7ba4330fc8bd8e1b2ce65804cdb452b86d7e40ec30a1bd02d6a2","dumps/main/search-telemetry-v2.json":"b0f3ba5c0b4d9051e87b84ebb90abf4477a56b1999c033deca3ce3c8e4a3f7f9","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"8eaf9e25104b5fe04dad1e098472a8e4b9a5bc77f835552efed17d226335e4b9","src/config.rs":"3e322bdab94855e17427187ffe92a59c1a64c9175d5e1f8605df2f6409a3c93f","src/context.rs":"43bab81026b6f1a2509d129e806fffd09ba80110d656798a02589985017a3c21","src/error.rs":"acd968e1e117f1b43953a9a7a32df1e60aa2a5e1e587e925339fa8a9e63c2183","src/jexl_filter.rs":"48a9d960e05dae444421f7c4ceeb45eab656f03f1e7071215c8e8d39aab56b54","src/lib.rs":"3b4eba3adf4dfad69cea2ed9a03bf38bc999facbd6aafc7a25951941d8309115","src/macros.rs":"6b06d0ba42ee95235bfd71bac1a0eed02f60c894775ebee64165648b10e932c4","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"a3e3ad7a82cffb920b46d350aba39a09a97b460c11a3f21c5526a0153f31d365","src/signatures.rs":"baa2dae76abd8166158fea4676e67e17c17b65af6968de52768350409dbd7092","src/storage.rs":"c33dd92914770e96d3d44dbb9e95f512ce54261710a42c7cf4a896be348c529e","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null} \ No newline at end of file diff --git a/third_party/rust/remote_settings/Cargo.toml b/third_party/rust/remote_settings/Cargo.toml index 26fdb2e25002..f3378bfd095b 100644 --- a/third_party/rust/remote_settings/Cargo.toml +++ b/third_party/rust/remote_settings/Cargo.toml @@ -45,7 +45,6 @@ path = "src/lib.rs" [dependencies] anyhow = "1.0" camino = "1.0" -log = "0.4" parking_lot = "0.12" regex = "1.9" serde_json = "1" diff --git a/third_party/rust/remote_settings/src/client.rs b/third_party/rust/remote_settings/src/client.rs index 35279410c283..9b7740e38039 100644 --- a/third_party/rust/remote_settings/src/client.rs +++ b/third_party/rust/remote_settings/src/client.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::config::{BaseUrl, RemoteSettingsConfig}; -use crate::error::{Error, Result}; +use crate::error::{debug, trace, Error, Result}; use crate::jexl_filter::JexlFilter; #[cfg(feature = "signatures")] use crate::signatures; @@ -309,7 +309,7 @@ impl RemoteSettingsClient { let collection_url = inner.api_client.collection_url(); let timestamp = inner.storage.get_last_modified_timestamp(&collection_url)?; let changeset = inner.api_client.fetch_changeset(timestamp)?; - log::debug!( + debug!( "{0}: apply {1} change(s) locally.", self.collection_name, changeset.changes.len() @@ -327,7 +327,7 @@ impl RemoteSettingsClient { self.perform_sync_operation()?; // Verify that inserted data has valid signature if self.verify_signature().is_err() { - log::debug!( + debug!( "{0}: signature verification failed. Reset and retry.", self.collection_name ); @@ -341,12 +341,12 @@ impl RemoteSettingsClient { .expect("Failed to reset storage after verification failure"); })?; } - log::trace!("{0}: sync done.", self.collection_name); + trace!("{0}: sync done.", self.collection_name); Ok(()) } fn reset_storage(&self) -> Result<()> { - log::trace!("{0}: reset local storage.", self.collection_name); + trace!("{0}: reset local storage.", self.collection_name); let mut inner = self.inner.lock(); let collection_url = inner.api_client.collection_url(); // Clear existing storage @@ -354,7 +354,7 @@ impl RemoteSettingsClient { // Load packaged data only for production if inner.api_client.is_prod_server()? { if let Some(packaged_data) = self.load_packaged_data() { - log::trace!("{0}: restore packaged dump.", self.collection_name); + trace!("{0}: restore packaged dump.", self.collection_name); inner.storage.insert_collection_content( &collection_url, &packaged_data.data, @@ -372,7 +372,7 @@ impl RemoteSettingsClient { #[cfg(not(feature = "signatures"))] fn verify_signature(&self) -> Result<()> { - log::debug!("{0}: signature verification skipped.", self.collection_name); + debug!("{0}: signature verification skipped.", self.collection_name); Ok(()) } @@ -415,15 +415,12 @@ impl RemoteSettingsClient { &expected_leaf_cname, ) .inspect_err(|err| { - log::debug!( + debug!( "{0}: bad signature ({1:?}) using certificate {2} and signer '{3}'", - self.collection_name, - err, - &metadata.signature.x5u, - expected_leaf_cname + self.collection_name, err, &metadata.signature.x5u, expected_leaf_cname ); })?; - log::trace!("{0}: signature verification success.", self.collection_name); + trace!("{0}: signature verification success.", self.collection_name); Ok(()) } _ => { @@ -565,7 +562,7 @@ impl ViaductApiClient { } fn make_request(&mut self, url: Url) -> Result { - log::trace!("make_request: {url}"); + trace!("make_request: {url}"); self.remote_state.ensure_no_backoff()?; let req = Request::get(url); diff --git a/third_party/rust/remote_settings/src/config.rs b/third_party/rust/remote_settings/src/config.rs index fec12e62df3c..5b43a1aa2e6b 100644 --- a/third_party/rust/remote_settings/src/config.rs +++ b/third_party/rust/remote_settings/src/config.rs @@ -10,6 +10,7 @@ use url::Url; +use crate::error::warn; use crate::{ApiResult, Error, RemoteSettingsContext, Result}; /// Remote settings configuration @@ -86,7 +87,7 @@ impl RemoteSettingsServer { Ok(url) => url, // The unwrap below will never fail, since prod is a hard-coded/valid URL. Err(_) => { - log::warn!("Invalid Custom URL: {}", self.raw_url()); + warn!("Invalid Custom URL: {}", self.raw_url()); BaseUrl::parse(Self::Prod.raw_url()).unwrap() } } diff --git a/third_party/rust/remote_settings/src/error.rs b/third_party/rust/remote_settings/src/error.rs index 075600110133..d25fa08b283b 100644 --- a/third_party/rust/remote_settings/src/error.rs +++ b/third_party/rust/remote_settings/src/error.rs @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use error_support::{ErrorHandling, GetErrorHandling}; +// reexport logging helpers. +pub use error_support::{debug, error, info, trace, warn}; pub type ApiResult = std::result::Result; pub type Result = std::result::Result; diff --git a/third_party/rust/remote_settings/src/lib.rs b/third_party/rust/remote_settings/src/lib.rs index 25d6ab1b1d8b..89b16c2732a6 100644 --- a/third_party/rust/remote_settings/src/lib.rs +++ b/third_party/rust/remote_settings/src/lib.rs @@ -23,7 +23,7 @@ mod macros; pub use client::{Attachment, RemoteSettingsRecord, RemoteSettingsResponse, RsJsonObject}; pub use config::{BaseUrl, RemoteSettingsConfig, RemoteSettingsConfig2, RemoteSettingsServer}; pub use context::RemoteSettingsContext; -pub use error::{ApiResult, RemoteSettingsError, Result}; +pub use error::{trace, ApiResult, RemoteSettingsError, Result}; use client::Client; use error::Error; @@ -124,7 +124,7 @@ impl RemoteSettingsClient { Ok(records) => records, Err(e) => { // Log/report the error - log::trace!("get_records error: {e}"); + trace!("get_records error: {e}"); convert_log_report_error(e); // Throw away the converted result and return None, there's nothing a client can // really do with an error except treat it as the None case diff --git a/third_party/rust/remote_settings/src/service.rs b/third_party/rust/remote_settings/src/service.rs index 5c4e7f2e4d6c..7220820039c1 100644 --- a/third_party/rust/remote_settings/src/service.rs +++ b/third_party/rust/remote_settings/src/service.rs @@ -8,6 +8,7 @@ use std::{ }; use camino::Utf8PathBuf; +use error_support::trace; use parking_lot::Mutex; use serde::Deserialize; use viaduct::Request; @@ -101,13 +102,13 @@ impl RemoteSettingsService { if let Some(server_last_modified) = change_map.get(&(collection_name, &bucket_name)) { if client_last_modified != *server_last_modified { - log::trace!("skipping up-to-date collection: {collection_name}"); + trace!("skipping up-to-date collection: {collection_name}"); continue; } } } if synced_collections.insert(collection_name.to_string()) { - log::trace!("syncing collection: {collection_name}"); + trace!("syncing collection: {collection_name}"); client.sync()?; } } @@ -171,7 +172,7 @@ impl RemoteSettingsServiceInner { // notification. url.query_pairs_mut().append_pair("_expected", "0"); let url = url.into_inner(); - log::trace!("make_request: {url}"); + trace!("make_request: {url}"); self.remote_state.ensure_no_backoff()?; let req = Request::get(url); diff --git a/third_party/rust/search/.cargo-checksum.json b/third_party/rust/search/.cargo-checksum.json index 4cd2dd8ccc0b..db73fb6daecf 100644 --- a/third_party/rust/search/.cargo-checksum.json +++ b/third_party/rust/search/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"ac0ac2103375f1c3906436b53627f88515da74864dd3f86ebb2a18952ba72b30","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","android/build.gradle":"e3b617d653aa0221f2229bb16c2fd635003fe82d0274c4b9a6f2d8154851985a","android/proguard-rules.pro":"1cf8c57e8f79c250b0af9c1a5a4edad71a5c348a79ab70243b6bae086c150ad2","android/src/main/AndroidManifest.xml":"0a05039a6124be0296764c2b0f41e863b5538d75e6164dd9ae945b59d983c318","src/configuration_overrides_types.rs":"220a5e12ee3deb309a1571c5820ec5132c959f56667c4c48f997bbe2be0c7eeb","src/configuration_types.rs":"a495199fc19cf9ce1aefe41058a38a0ffad4eb6f719fac11c11dcc3cfe4f234a","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d3c1eda7a8da15446a321139d4d29dd9ceee99e916519690d5eb2d45ed628598","src/filter.rs":"88a39e594397708db888726cac00ad1e5b4a892c5a121c96cc11d20f41851b45","src/lib.rs":"9c83780a74048fbbc7bbba5706067b9dc5db2ae25a0cc751687d2738903723b4","src/selector.rs":"6585b4d487179353f4dc8bae396cc18a97e5fcde58f6afa09373cd04510daa03","src/sort_helpers.rs":"5bcae57c230e1d1123d3c5be1ae38b481c6a1fc5096bc0fdede6f7a7c8d27032","src/types.rs":"8721ccf9443b28435ba211d5705f4a6c82eb0354ba1d100045438800c7e2bf9a","uniffi.toml":"96f1cd569483ff59e3c73852f085a03889fa24a2ce20ff7a3003799a9f48a51e"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"4a04033dec6fd9bb7e2232ee6a47a16a7a07ccf14f0a8870b6bea9a131d5697e","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","android/build.gradle":"e3b617d653aa0221f2229bb16c2fd635003fe82d0274c4b9a6f2d8154851985a","android/proguard-rules.pro":"1cf8c57e8f79c250b0af9c1a5a4edad71a5c348a79ab70243b6bae086c150ad2","android/src/main/AndroidManifest.xml":"0a05039a6124be0296764c2b0f41e863b5538d75e6164dd9ae945b59d983c318","src/configuration_overrides_types.rs":"220a5e12ee3deb309a1571c5820ec5132c959f56667c4c48f997bbe2be0c7eeb","src/configuration_types.rs":"a495199fc19cf9ce1aefe41058a38a0ffad4eb6f719fac11c11dcc3cfe4f234a","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d3c1eda7a8da15446a321139d4d29dd9ceee99e916519690d5eb2d45ed628598","src/filter.rs":"88a39e594397708db888726cac00ad1e5b4a892c5a121c96cc11d20f41851b45","src/lib.rs":"9c83780a74048fbbc7bbba5706067b9dc5db2ae25a0cc751687d2738903723b4","src/selector.rs":"7aa3d7395502357df87fd5f8908a880d1e50d0dd02a00ac7876bdd42cd255498","src/sort_helpers.rs":"5bcae57c230e1d1123d3c5be1ae38b481c6a1fc5096bc0fdede6f7a7c8d27032","src/types.rs":"8721ccf9443b28435ba211d5705f4a6c82eb0354ba1d100045438800c7e2bf9a","uniffi.toml":"96f1cd569483ff59e3c73852f085a03889fa24a2ce20ff7a3003799a9f48a51e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/search/Cargo.toml b/third_party/rust/search/Cargo.toml index 7eed8a5b8953..6d3c6fa314c8 100644 --- a/third_party/rust/search/Cargo.toml +++ b/third_party/rust/search/Cargo.toml @@ -24,9 +24,6 @@ description = "Library for search service related components." readme = "README.md" license = "MPL-2.0" -[features] -enable_env_logger = ["env_logger"] - [lib] name = "search" path = "src/lib.rs" @@ -36,11 +33,6 @@ parking_lot = ">=0.11,<=0.12" serde_json = "1" thiserror = "1" -[dependencies.env_logger] -version = "0.10.0" -optional = true -default-features = false - [dependencies.error-support] path = "../support/error" @@ -62,10 +54,9 @@ mockito = "0.31" once_cell = "1.18.0" pretty_assertions = "0.6" -[dev-dependencies.env_logger] -version = "0.10.0" -features = ["humantime"] -default-features = false +[dev-dependencies.error-support] +path = "../support/error" +features = ["testing"] [dev-dependencies.viaduct-reqwest] path = "../support/viaduct-reqwest" diff --git a/third_party/rust/search/src/selector.rs b/third_party/rust/search/src/selector.rs index 303c297e4149..bcbdb393bb45 100644 --- a/third_party/rust/search/src/selector.rs +++ b/third_party/rust/search/src/selector.rs @@ -160,7 +160,6 @@ impl SearchEngineSelector { mod tests { use super::*; use crate::{types::*, SearchApiError}; - use env_logger; use mockito::mock; use pretty_assertions::assert_eq; use remote_settings::{RemoteSettingsConfig2, RemoteSettingsContext, RemoteSettingsServer}; @@ -1890,7 +1889,7 @@ mod tests { should_apply_overrides: bool, expect_sync_successful: bool, ) -> Arc { - let _ = env_logger::builder().try_init(); + error_support::init_for_tests(); viaduct_reqwest::use_reqwest_backend(); let config = RemoteSettingsConfig2 { diff --git a/third_party/rust/sql-support/.cargo-checksum.json b/third_party/rust/sql-support/.cargo-checksum.json index ef6ece56a62b..a93ebc20a8e9 100644 --- a/third_party/rust/sql-support/.cargo-checksum.json +++ b/third_party/rust/sql-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"00ffcb582afeb58d8249fc5fa2c453dab9ce3e305cb49410e21ca9a8561ce16e","src/conn_ext.rs":"1280fb1f06b74ed312e73f34c4fd86f538411c4b3d4eeccb631c80d02e295645","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"0b4de829ccaf06b743d0ee5bce766399d841e12592cd00d22605b75a5ae6dbd0","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"cb501b3b0482d549cbe6f0350d7321ed315269ccd75215af2582aae340fe354b","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"0e50c02b3a052c6b3cdc742409d46fb40a5939080c1f7ec1684241dc2b02f269","src/repeat.rs":"3dad3cbc6f47fc7598fc7b0fbf79b9c915322396d1f64d3d09651d100d428351"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"f6d6946d71afceda2e19155bd61d5563440f81d67eca67857834ea64aeaf1cc4","src/conn_ext.rs":"8efb8c9fd49f9d7444ef5e7ce426861658cecaf884a50c5e7673bbe92941558f","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"0b4de829ccaf06b743d0ee5bce766399d841e12592cd00d22605b75a5ae6dbd0","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"c3a83ab608724be7da83ca17a08b11ab88e4d5ce632509fd8a498a6e9fb969e8","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"c2ca3bf49dba5b8ae7e2be0fffebd5e440eacbf0748d93572c151259c66b807c","src/repeat.rs":"3dad3cbc6f47fc7598fc7b0fbf79b9c915322396d1f64d3d09651d100d428351"},"package":null} \ No newline at end of file diff --git a/third_party/rust/sql-support/Cargo.toml b/third_party/rust/sql-support/Cargo.toml index cb3d26213775..b7d47fb8307f 100644 --- a/third_party/rust/sql-support/Cargo.toml +++ b/third_party/rust/sql-support/Cargo.toml @@ -33,11 +33,13 @@ path = "src/lib.rs" [dependencies] lazy_static = "1.4" -log = "0.4" parking_lot = ">=0.11,<=0.12" tempfile = "3.1.0" thiserror = "1.0" +[dependencies.error-support] +path = "../error" + [dependencies.interrupt-support] path = "../interrupt" @@ -50,6 +52,6 @@ features = [ "unlock_notify", ] -[dev-dependencies.env_logger] -version = "0.10" -default-features = false +[dev-dependencies.error-support] +path = "../error" +features = ["testing"] diff --git a/third_party/rust/sql-support/src/conn_ext.rs b/third_party/rust/sql-support/src/conn_ext.rs index 9abb21fa6264..0aac92c895f3 100644 --- a/third_party/rust/sql-support/src/conn_ext.rs +++ b/third_party/rust/sql-support/src/conn_ext.rs @@ -12,6 +12,7 @@ use std::ops::Deref; use std::time::Instant; use crate::maybe_cached::MaybeCached; +use crate::{debug, warn}; /// This trait exists so that we can use these helpers on `rusqlite::{Transaction, Connection}`. /// Note that you must import ConnExt in order to call these methods on anything. @@ -332,19 +333,19 @@ impl<'conn> UncheckedTransaction<'conn> { /// Consumes and commits an unchecked transaction. pub fn commit(mut self) -> SqlResult<()> { if self.finished { - log::warn!("ignoring request to commit an already finished transaction"); + warn!("ignoring request to commit an already finished transaction"); return Ok(()); } self.finished = true; self.conn.execute_batch("COMMIT")?; - log::debug!("Transaction commited after {:?}", self.started_at.elapsed()); + debug!("Transaction commited after {:?}", self.started_at.elapsed()); Ok(()) } /// Consumes and rolls back an unchecked transaction. pub fn rollback(mut self) -> SqlResult<()> { if self.finished { - log::warn!("ignoring request to rollback an already finished transaction"); + warn!("ignoring request to rollback an already finished transaction"); return Ok(()); } self.rollback_() @@ -377,7 +378,7 @@ impl Deref for UncheckedTransaction<'_> { impl Drop for UncheckedTransaction<'_> { fn drop(&mut self) { if let Err(e) = self.finish_() { - log::warn!("Error dropping an unchecked transaction: {}", e); + warn!("Error dropping an unchecked transaction: {}", e); } } } diff --git a/third_party/rust/sql-support/src/lib.rs b/third_party/rust/sql-support/src/lib.rs index 60c5b8bcc0c1..949d57b20435 100644 --- a/third_party/rust/sql-support/src/lib.rs +++ b/third_party/rust/sql-support/src/lib.rs @@ -30,6 +30,9 @@ pub use lazy::*; pub use maybe_cached::*; pub use repeat::*; +// reexport logging helpers. +use error_support::{debug, info, warn}; + /// In PRAGMA foo='bar', `'bar'` must be a constant string (it cannot be a /// bound parameter), so we need to escape manually. According to /// , the only character that must be escaped is diff --git a/third_party/rust/sql-support/src/open_database.rs b/third_party/rust/sql-support/src/open_database.rs index c9e6b1730c2b..ad20258820ca 100644 --- a/third_party/rust/sql-support/src/open_database.rs +++ b/third_party/rust/sql-support/src/open_database.rs @@ -41,6 +41,7 @@ use rusqlite::{ use thiserror::Error; use crate::ConnExt; +use crate::{debug, info, warn}; #[derive(Error, Debug)] pub enum Error { @@ -143,18 +144,18 @@ fn do_open_database_with_flags>( connection_initializer: &CI, ) -> Result { // Try running the migration logic with an existing file - log::debug!("{}: opening database", CI::NAME); + debug!("{}: opening database", CI::NAME); let mut conn = Connection::open_with_flags(path, open_flags)?; - log::debug!("{}: checking if initialization is necessary", CI::NAME); + debug!("{}: checking if initialization is necessary", CI::NAME); let db_empty = is_db_empty(&conn)?; - log::debug!("{}: preparing", CI::NAME); + debug!("{}: preparing", CI::NAME); connection_initializer.prepare(&conn, db_empty)?; if open_flags.contains(OpenFlags::SQLITE_OPEN_READ_WRITE) { let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate)?; if db_empty { - log::debug!("{}: initializing new database", CI::NAME); + debug!("{}: initializing new database", CI::NAME); connection_initializer.init(&tx)?; } else { let mut current_version = get_schema_version(&tx)?; @@ -162,7 +163,7 @@ fn do_open_database_with_flags>( return Err(Error::IncompatibleVersion(current_version)); } while current_version < CI::END_VERSION { - log::debug!( + debug!( "{}: upgrading database to {}", CI::NAME, current_version + 1 @@ -171,7 +172,7 @@ fn do_open_database_with_flags>( current_version += 1; } } - log::debug!("{}: finishing writable database open", CI::NAME); + debug!("{}: finishing writable database open", CI::NAME); connection_initializer.finish(&tx)?; set_schema_version(&tx, CI::END_VERSION)?; tx.commit()?; @@ -183,10 +184,10 @@ fn do_open_database_with_flags>( get_schema_version(&conn)? == CI::END_VERSION, "existing writer must have migrated" ); - log::debug!("{}: finishing readonly database open", CI::NAME); + debug!("{}: finishing readonly database open", CI::NAME); connection_initializer.finish(&conn)?; } - log::debug!("{}: database open successful", CI::NAME); + debug!("{}: database open successful", CI::NAME); Ok(conn) } @@ -211,15 +212,15 @@ fn try_handle_db_failure>( if !open_flags.contains(OpenFlags::SQLITE_OPEN_CREATE) && matches!(err, Error::SqlError(rusqlite::Error::SqliteFailure(code, _)) if code.code == rusqlite::ErrorCode::CannotOpen) { - log::info!( + info!( "{}: database doesn't exist, but we weren't requested to create it", CI::NAME ); return Err(err); } - log::warn!("{}: database operation failed: {}", CI::NAME, err); + warn!("{}: database operation failed: {}", CI::NAME, err); if !open_flags.contains(OpenFlags::SQLITE_OPEN_READ_WRITE) { - log::warn!( + warn!( "{}: not attempting recovery as this is a read-only connection request", CI::NAME ); @@ -228,7 +229,7 @@ fn try_handle_db_failure>( let delete = matches!(err, Error::Corrupt); if delete { - log::info!( + info!( "{}: the database is fatally damaged; deleting and starting fresh", CI::NAME ); diff --git a/third_party/rust/suggest/.cargo-checksum.json b/third_party/rust/suggest/.cargo-checksum.json index c5366b7c9bbc..5af7e8151da2 100644 --- a/third_party/rust/suggest/.cargo-checksum.json +++ b/third_party/rust/suggest/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"922b2e4d85f325dbef99d5e439558a75dbfda82e1d263c2dd3bfadac9879df18","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"5909dfb1e62793afb1f2bc15b75914527a4d14fce6796307c04a309e45c0598c","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"e5897d4e2eda06809fa6dc6db4e780b9ef266f613fb113aa6613b83f7005dd0b","src/benchmarks/geoname.rs":"00fab05cf9465cf8e22e143cde75a81885411001b240af00efda4071975d0563","src/benchmarks/ingest.rs":"1f3b5eca704c51bc8f972e7a3492a518516461e5834f97a5f7d1855a048ab16b","src/benchmarks/mod.rs":"2c9a39b7a5144674d2475f4d7d69d77c4545f9aa5f123968cb32574e76f10b1a","src/benchmarks/query.rs":"d54946063e72cf98e7f46d94665c17c66af637774c2bb50cd5798dbe63d74f3c","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"c22aab621ae8c1b70595c2073e62ff766272400be13f393327c27451bce10498","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"f501c9fe5296e7c130a9fcb532b861465717652cb5ef688230bc7a3b94df91b1","src/geoname.rs":"77376dbc7d06532a7797a93b863f150317df7f31d9200d375c8ea489ac8bee6f","src/lib.rs":"a4c0989a01a7c13184049c1f11bc7813cd3cbfb6354fcca1f5a7204e45a0dc9c","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"e85d606e98a8ba37557072f91c6906b1a4d7c5586a9913bf3570ef25106b007f","src/query.rs":"66f229272c9245eb8ee0cab237071627aec599f145f64da8894bcaeb1ed7c6f9","src/rs.rs":"3e2310d069b4cbc7447c2bb625f03bb49439b218a1e8f04190015a31cde22842","src/schema.rs":"68dbdc960097cc3421247cd9f705f6dcf74c9d357b37a5824b80e37837cbf053","src/store.rs":"76e6e2134d1d0e6f8dcf30ed65fe18eb093531bdddec461ad708b1eb4ac6a01c","src/suggestion.rs":"33dd2fb8e966a72f9843476bc006c8dfb1326ed1268ad88aa91801356f2623a1","src/testing/client.rs":"47a32fd84c733001f11e8bfff94dc8c060b6b0780346dca5ddc7a5f5489c1d85","src/testing/data.rs":"ad710b31532a9540491a73cba33a54db02e85dd5ec0a4f2260430f144c3d7380","src/testing/mod.rs":"fe930be25229517831111fb6d7796ae957ec0eb1b9a190c59cf538ac41ae27f5","src/util.rs":"52c6ec405637afa2d1a89f29fbbb7dcc341546b6deb97d326c4490bbf8713cb0","src/weather.rs":"7cc9167dcdfca49d6ad91eba6fba4d5fd49f45052f25a7fe3ad6749d3e6783fb","src/yelp.rs":"1fe3b7eb6b3f7462e9758b6eb62457dfa26f7549a8290cdff7637d2fb3ffea4f","uniffi.toml":"8205e4679ac26d53e70af0f85c013fd27cda1119f4322aebf5f2b9403d45a611"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"57d202b48263d0ea4070807c66f26260497fb947f2099b7275a3e28463ad28ca","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"5909dfb1e62793afb1f2bc15b75914527a4d14fce6796307c04a309e45c0598c","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"e5897d4e2eda06809fa6dc6db4e780b9ef266f613fb113aa6613b83f7005dd0b","src/benchmarks/geoname.rs":"fb4e8eb48e27879fe3f35d6d2415f0237b087b51b89ee03fb50fa635e1c1a3b5","src/benchmarks/ingest.rs":"1f3b5eca704c51bc8f972e7a3492a518516461e5834f97a5f7d1855a048ab16b","src/benchmarks/mod.rs":"2c9a39b7a5144674d2475f4d7d69d77c4545f9aa5f123968cb32574e76f10b1a","src/benchmarks/query.rs":"d54946063e72cf98e7f46d94665c17c66af637774c2bb50cd5798dbe63d74f3c","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"0ca876e845841bb6429862c0904c82265003f53b55aea053fac60aed278586a7","src/db.rs":"dbb2923192d062ee6f20e780ce5544afc999b01ab3eea81b46abe9e412750c4d","src/error.rs":"e2ef3ec0e0b2b8ecbb8f2f1717d4cb753af06913b8395d086b7643098ad100a7","src/fakespot.rs":"f501c9fe5296e7c130a9fcb532b861465717652cb5ef688230bc7a3b94df91b1","src/geoname.rs":"24d4e37f67ece92e5d268ecca22bdeef65a674db282530f248c1011c5ca77449","src/lib.rs":"3b8ccb1e93d214d27b7ef77326da40a0b85621f32ba143664f55e4fb2a665e7c","src/metrics.rs":"871f0d834efbbc9e26d61f66fa31f0021dcf41444746cd7c082f93ba9628e399","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"6ec6b207eca1f4f9553fcb2d57d3a05d87279e81e09def5abdc5219ce838a4e9","src/query.rs":"66f229272c9245eb8ee0cab237071627aec599f145f64da8894bcaeb1ed7c6f9","src/rs.rs":"42b5a81c33df7dbabae5cb9756b7d947553545ae76e3dbd5eb3dcced3a31ce68","src/schema.rs":"a925dd09c609c2bc2338242a3f057e884e9add6478b15180f61bb53adda6574d","src/store.rs":"66d7f31b9d8713b11ecf389728beda3d9c5b0ea8402141b7ddf198372a1111f4","src/suggestion.rs":"6e902501624b62d9bde1c771eded87e7620540c691667d0ac913d8c21c183e9a","src/testing/client.rs":"47a32fd84c733001f11e8bfff94dc8c060b6b0780346dca5ddc7a5f5489c1d85","src/testing/data.rs":"ad710b31532a9540491a73cba33a54db02e85dd5ec0a4f2260430f144c3d7380","src/testing/mod.rs":"bd02746cdc6e2d54a7691b3ffbccb1a81b66b717871c34dd1a8b6088dc125185","src/util.rs":"52c6ec405637afa2d1a89f29fbbb7dcc341546b6deb97d326c4490bbf8713cb0","src/weather.rs":"c3ab5e8a4e3dd7be0a4bb37848db0b6295050d151ade9c935a7fb4c7e12a1367","src/yelp.rs":"1fe3b7eb6b3f7462e9758b6eb62457dfa26f7549a8290cdff7637d2fb3ffea4f","uniffi.toml":"8205e4679ac26d53e70af0f85c013fd27cda1119f4322aebf5f2b9403d45a611"},"package":null} \ No newline at end of file diff --git a/third_party/rust/suggest/Cargo.toml b/third_party/rust/suggest/Cargo.toml index 0acb2fc10692..f5ef625ff39c 100644 --- a/third_party/rust/suggest/Cargo.toml +++ b/third_party/rust/suggest/Cargo.toml @@ -54,12 +54,13 @@ required-features = ["benchmark_api"] anyhow = "1.0" chrono = "0.4" extend = "1.1" -log = "0.4" once_cell = "1.5" parking_lot = ">=0.11,<=0.12" rmp-serde = "1.3" serde_json = "1" thiserror = "1" +unicase = "2.6" +unicode-normalization = "0.1" [dependencies.error-support] path = "../support/error" @@ -76,6 +77,7 @@ features = [ "functions", "bundled", "load_extension", + "collation", ] [dependencies.serde] @@ -107,10 +109,11 @@ optional = true criterion = "0.5" expect-test = "1.4" hex = "0.4" +itertools = "0.14" -[dev-dependencies.env_logger] -version = "0.10" -default-features = false +[dev-dependencies.error-support] +path = "../support/error" +features = ["testing"] [dev-dependencies.rc_crypto] path = "../support/rc_crypto" diff --git a/third_party/rust/suggest/src/benchmarks/geoname.rs b/third_party/rust/suggest/src/benchmarks/geoname.rs index 26a1a6d176dc..9de321206c22 100644 --- a/third_party/rust/suggest/src/benchmarks/geoname.rs +++ b/third_party/rust/suggest/src/benchmarks/geoname.rs @@ -17,7 +17,6 @@ pub struct GeonameBenchmark { pub struct FetchGeonamesArgs { query: &'static str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, } @@ -49,7 +48,6 @@ impl BenchmarkWithInput for GeonameBenchmark { .fetch_geonames( i_input.fetch_args.query, i_input.fetch_args.match_name_prefix, - i_input.fetch_args.geoname_type, i_input.fetch_args.filter, ) .unwrap_or_else(|e| panic!("Error fetching geonames: {e}")); @@ -67,13 +65,16 @@ impl BenchmarkWithInput for GeonameBenchmark { pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { let ny_state = Geoname { - geoname_id: 8, + geoname_id: 5128638, + geoname_type: GeonameType::AdminDivision { level: 1 }, name: "New York".to_string(), - latitude: 43.00035, - longitude: -75.4999, + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), country_code: "US".to_string(), - admin1_code: "NY".to_string(), + admin_division_codes: [(1, "NY".to_string())].into(), population: 19274244, + latitude: "43.00035".to_string(), + longitude: "-75.4999".to_string(), }; vec![ @@ -84,7 +85,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "nomatch", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: false, @@ -96,7 +96,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "no match", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: false, @@ -108,7 +107,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "no match either", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: false, @@ -120,7 +118,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "this is a very long string that does not match anything in the geonames database but it sure is very long", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: false, @@ -134,7 +131,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "nomatch", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: false, @@ -146,7 +142,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "no match", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: false, @@ -158,7 +153,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "no match either", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: false, @@ -170,7 +164,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "this is a very long string that does not match anything in the geonames database but it sure is very long", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: false, @@ -184,7 +177,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "ny", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -196,7 +188,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "nyc", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -208,7 +199,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "ca", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -220,7 +210,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "pdx", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -232,7 +221,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "roc", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -246,7 +234,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "ny", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -258,7 +245,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "nyc", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -270,7 +256,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "ca", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -282,7 +267,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "pdx", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -294,7 +278,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "roc", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -308,7 +291,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "new york", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -320,7 +302,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "rochester", match_name_prefix: false, - geoname_type: None, filter: None, }, should_match: true, @@ -334,7 +315,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "new york", match_name_prefix: true, - geoname_type: None, filter: None, }, should_match: true, @@ -346,33 +326,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "rochester", match_name_prefix: true, - geoname_type: None, - filter: None, - }, - should_match: true, - } - ), - - // restricting to a geoname type - ( - "geoname-fetch-type-city-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::City), - filter: None, - }, - should_match: true, - } - ), - ( - "geoname-fetch-type-region-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::Region), filter: None, }, should_match: true, @@ -386,59 +339,6 @@ pub fn all_benchmarks() -> Vec<(&'static str, GeonameBenchmark)> { args: FetchGeonamesArgs { query: "ny", match_name_prefix: false, - geoname_type: None, - filter: Some(vec![ny_state.clone()]), - }, - should_match: true, - } - ), - - // restricting to a geoname type + filtering - ( - "geoname-fetch-type-filter-city-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::City), - filter: Some(vec![ny_state.clone()]), - }, - should_match: true, - } - ), - ( - "geoname-fetch-type-filter-region-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::Region), - filter: Some(vec![ny_state.clone()]), - }, - should_match: true, - } - ), - - // restricting to a geoname type + filtering w/ prefix matching - ( - "geoname-fetch-type-filter-prefix-city-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: true, - geoname_type: Some(GeonameType::City), - filter: Some(vec![ny_state.clone()]), - }, - should_match: true, - } - ), - ( - "geoname-fetch-type-filter-prefix-region-ny", - GeonameBenchmark { - args: FetchGeonamesArgs { - query: "ny", - match_name_prefix: true, - geoname_type: Some(GeonameType::Region), filter: Some(vec![ny_state.clone()]), }, should_match: true, diff --git a/third_party/rust/suggest/src/db.rs b/third_party/rust/suggest/src/db.rs index a88b2a354fde..cf574523c6da 100644 --- a/third_party/rust/suggest/src/db.rs +++ b/third_party/rust/suggest/src/db.rs @@ -26,6 +26,7 @@ use crate::{ DownloadedAmoSuggestion, DownloadedAmpSuggestion, DownloadedDynamicRecord, DownloadedDynamicSuggestion, DownloadedFakespotSuggestion, DownloadedMdnSuggestion, DownloadedPocketSuggestion, DownloadedWikipediaSuggestion, Record, SuggestRecordId, + SuggestRecordType, }, schema::{clear_database, SuggestConnectionInitializer}, suggestion::{cook_raw_suggestion_url, FtsMatchInfo, Suggestion}, @@ -1365,6 +1366,11 @@ impl<'a> SuggestDao<'a> { named_params! { ":record_id": record_id.as_str() }, )?; self.scope.err_if_interrupted()?; + self.conn.execute_cached( + "DELETE FROM geonames_alternates WHERE record_id = :record_id", + named_params! { ":record_id": record_id.as_str() }, + )?; + self.scope.err_if_interrupted()?; self.conn.execute_cached( "DELETE FROM geonames_metrics WHERE record_id = :record_id", named_params! { ":record_id": record_id.as_str() }, @@ -1446,6 +1452,32 @@ impl<'a> SuggestDao<'a> { self.get_meta::(&provider_config_meta_key(provider))? .map_or_else(|| Ok(None), |json| Ok(serde_json::from_str(&json)?)) } + + /// Gets keywords metrics for a record type. + pub fn get_keywords_metrics(&self, record_type: SuggestRecordType) -> Result { + let data = self.conn.try_query_row( + r#" + SELECT + max(max_len) AS len, + max(max_word_count) AS word_count + FROM + keywords_metrics + WHERE + record_type = :record_type + "#, + named_params! { + ":record_type": record_type, + }, + |row| -> Result<(usize, usize)> { Ok((row.get("len")?, row.get("word_count")?)) }, + true, // cache + )?; + Ok(data + .map(|(max_len, max_word_count)| KeywordsMetrics { + max_len, + max_word_count, + }) + .unwrap_or_default()) + } } #[derive(Debug, PartialEq, Eq, Hash)] @@ -1839,32 +1871,68 @@ impl<'conn> PrefixKeywordInsertStatement<'conn> { } } -pub(crate) struct KeywordMetricsInsertStatement<'conn>(rusqlite::Statement<'conn>); +#[derive(Debug, Default)] +pub(crate) struct KeywordsMetrics { + pub(crate) max_len: usize, + pub(crate) max_word_count: usize, +} -impl<'conn> KeywordMetricsInsertStatement<'conn> { - pub(crate) fn new(conn: &'conn Connection) -> Result { - Ok(Self(conn.prepare( - "INSERT INTO keywords_metrics( - record_id, - provider, - max_length, - max_word_count - ) - VALUES(?, ?, ?, ?) - ", - )?)) +/// This can be used to update metrics as keywords are inserted into the DB. +/// Create a `KeywordsMetricsUpdater`, call `update` on it as each keyword is +/// inserted, and then call `finish` after all keywords have been inserted. +pub(crate) struct KeywordsMetricsUpdater { + pub(crate) max_len: usize, + pub(crate) max_word_count: usize, +} + +impl KeywordsMetricsUpdater { + pub(crate) fn new() -> Self { + Self { + max_len: 0, + max_word_count: 0, + } } - pub(crate) fn execute( - &mut self, + pub(crate) fn update(&mut self, keyword: &str) { + self.max_len = std::cmp::max(self.max_len, keyword.len()); + self.max_word_count = + std::cmp::max(self.max_word_count, keyword.split_whitespace().count()); + } + + /// Inserts keywords metrics into the database. This assumes you have a + /// cache object inside the `cache` cell that caches the metrics. It will be + /// cleared since it will be invalidated by the metrics update. + pub(crate) fn finish( + &self, + conn: &Connection, record_id: &SuggestRecordId, - provider: SuggestionProvider, - max_len: usize, - max_word_count: usize, + record_type: SuggestRecordType, + cache: &mut OnceCell, ) -> Result<()> { - self.0 - .execute((record_id.as_str(), provider, max_len, max_word_count)) - .with_context("keyword metrics insert")?; + let mut insert_stmt = conn.prepare( + r#" + INSERT OR REPLACE INTO keywords_metrics( + record_id, + record_type, + max_len, + max_word_count + ) + VALUES(?, ?, ?, ?) + "#, + )?; + insert_stmt + .execute(( + record_id.as_str(), + record_type, + self.max_len, + self.max_word_count, + )) + .with_context("keywords metrics insert")?; + + // We just made some insertions that might invalidate the data in the + // cache. Clear it so it's repopulated the next time it's accessed. + cache.take(); + Ok(()) } } diff --git a/third_party/rust/suggest/src/geoname.rs b/third_party/rust/suggest/src/geoname.rs index 58e073791fb2..7cc38ab11537 100644 --- a/third_party/rust/suggest/src/geoname.rs +++ b/third_party/rust/suggest/src/geoname.rs @@ -6,20 +6,29 @@ /// GeoNames support. GeoNames is an open-source geographical database of place /// names worldwide, including cities, regions, and countries [1]. Notably it's /// used by MaxMind's databases [2]. We use GeoNames to detect city and region -/// names and to map cities to regions. +/// names and to map cities to regions. Specifically we use the data at [3]; +/// also see [3] for documentation. /// /// [1]: https://www.geonames.org/ /// [2]: https://www.maxmind.com/en/geoip-databases +/// [3]: https://download.geonames.org/export/dump/ use rusqlite::{named_params, Connection}; use serde::Deserialize; use sql_support::ConnExt; -use std::hash::{Hash, Hasher}; +use std::{ + borrow::Cow, + cell::OnceCell, + collections::HashMap, + hash::{Hash, Hasher}, +}; +use unicase::UniCase; +use unicode_normalization::{char::is_combining_mark, UnicodeNormalization}; use crate::{ - db::SuggestDao, + db::{KeywordsMetrics, KeywordsMetricsUpdater, SuggestDao}, error::RusqliteResultExt, metrics::MetricsContext, - rs::{deserialize_f64_or_default, Client, Record, SuggestRecordId}, + rs::{Client, Record, SuggestRecordId, SuggestRecordType}, store::SuggestStoreInner, Result, }; @@ -27,57 +36,135 @@ use crate::{ /// The type of a geoname. #[derive(Clone, Debug, Eq, Hash, PartialEq, uniffi::Enum)] pub enum GeonameType { + Country, + /// A state, province, prefecture, district, borough, etc. + AdminDivision { + level: u8, + }, + AdminDivisionOther, + /// A city, town, village, populated place, etc. City, - Region, + Other, } +pub type GeonameId = i64; + /// A single geographic place. /// /// This corresponds to a single row in the main "geoname" table described in /// the GeoNames documentation [1]. We exclude fields we don't need. /// /// [1]: https://download.geonames.org/export/dump/readme.txt -#[derive(Clone, Debug, uniffi::Record)] +#[derive(Clone, Debug, Eq, PartialEq, uniffi::Record)] pub struct Geoname { /// The `geonameid` straight from the geoname table. - pub geoname_id: i64, - /// This is pretty much the place's canonical name. Usually there will be a - /// row in the alternates table with the same name, but not always. When - /// there is such a row, it doesn't always have `is_preferred_name` set, and - /// in fact fact there may be another row with a different name with - /// `is_preferred_name` set. + pub geoname_id: GeonameId, + /// The geoname type. This is derived from `feature_class` and + /// `feature_code` as a more convenient representation of the type. + pub geoname_type: GeonameType, + /// The place's primary name. pub name: String, - /// Latitude in decimal degrees. - pub latitude: f64, - /// Longitude in decimal degrees. - pub longitude: f64, /// ISO-3166 two-letter uppercase country code, e.g., "US". pub country_code: String, - /// The top-level administrative region for the place within its country, - /// like a state or province. For the U.S., the two-letter uppercase state - /// abbreviation. - pub admin1_code: String, + /// Primary geoname category. Examples: + /// + /// "PCLI" - Independent political entity: country + /// "A" - Administrative division: state, province, borough, district, etc. + /// "P" - Populated place: city, village, etc. + pub feature_class: String, + /// Secondary geoname category, depends on `feature_class`. Examples: + /// + /// "ADM1" - Administrative division 1 + /// "PPL" - Populated place like a city + pub feature_code: String, + /// Administrative divisions. This maps admin division levels (1-based) to + /// their corresponding codes. For example, Liverpool has two admin + /// divisions: "ENG" at level 1 and "H8" at level 2. They would be + /// represented in this map with entries `(1, "ENG")` and `(2, "H8")`. + pub admin_division_codes: HashMap, /// Population size. pub population: u64, + /// Latitude in decimal degrees (as a string). + pub latitude: String, + /// Longitude in decimal degrees (as a string). + pub longitude: String, +} + +/// Alternate names for a geoname and its country and admin divisions. +#[derive(Clone, Debug, Eq, PartialEq, uniffi::Record)] +pub struct GeonameAlternates { + /// Names for the geoname itself. + geoname: AlternateNames, + /// Names for the geoname's country. This will be `Some` as long as the + /// country is also in the ingested data, which should typically be true. + country: Option, + /// Names for the geoname's admin divisions. This is parallel to + /// `Geoname::admin_division_codes`. If there are no names in the ingested + /// data for an admin division, then it will be absent from this map. + admin_divisions: HashMap, +} + +/// A set of names for a single entity. +#[derive(Clone, Debug, Eq, PartialEq, uniffi::Record)] +pub struct AlternateNames { + /// The entity's primary name. For a `Geoname`, this is `Geoname::name`. + primary: String, + /// The entity's name in the language that was ingested according to the + /// locale in the remote settings context. If none exists and this + /// `AlternateNames` is for a `Geoname`, then this will be its primary name. + localized: Option, + /// The entity's abbreviation, if any. + abbreviation: Option, } impl Geoname { - /// Whether `self` and `other` have the same region and country. If one is a - /// city and the other is a region, this will return `true` if the city is - /// located in the region. - pub fn has_same_region(&self, other: &Self) -> bool { - self.admin1_code == other.admin1_code && self.country_code == other.country_code + /// Whether `self` and `other` are related. For example, if one is a city + /// and the other is an administrative division, this will return `true` if + /// the city is located in the division. + pub fn is_related_to(&self, other: &Self) -> bool { + if self.country_code != other.country_code { + return false; + } + + let self_level = self.admin_level(); + let other_level = other.admin_level(); + + // Build a sorted vec of levels in both `self and `other`. + let mut levels_asc: Vec<_> = self + .admin_division_codes + .keys() + .chain(other.admin_division_codes.keys()) + .copied() + .collect(); + levels_asc.sort(); + + // Each admin level needs to be the same in `self` and `other` up to the + // minimum level of `self` and `other`. + for level in levels_asc { + if self_level < level || other_level < level { + break; + } + if self.admin_division_codes.get(&level) != other.admin_division_codes.get(&level) { + return false; + } + } + + // At this point, admin levels are the same up to the minimum level. If + // the types of `self` and `other` aren't the same, then one is an admin + // division of the other. If they are the same type, then they need to + // be the same geoname. + self.geoname_type != other.geoname_type || self.geoname_id == other.geoname_id + } + + fn admin_level(&self) -> u8 { + match self.geoname_type { + GeonameType::Country => 0, + GeonameType::AdminDivision { level } => level, + _ => 4, + } } } -impl PartialEq for Geoname { - fn eq(&self, other: &Geoname) -> bool { - self.geoname_id == other.geoname_id - } -} - -impl Eq for Geoname {} - impl Hash for Geoname { fn hash(&self, state: &mut H) { self.geoname_id.hash(state) @@ -97,7 +184,6 @@ pub struct GeonameMatch { #[derive(Clone, Debug, Eq, PartialEq, uniffi::Enum)] pub enum GeonameMatchType { - /// For U.S. states, abbreviations are the usual two-letter codes ("CA"). Abbreviation, AirportCode, /// This includes any names that aren't abbreviations or airport codes. @@ -118,76 +204,106 @@ impl GeonameMatchType { /// potentially other providers, so we cache it from the DB. #[derive(Debug, Default)] pub struct GeonameCache { - /// Max length of all geoname names. - pub max_name_length: usize, - /// Max word count across all geoname names. - pub max_name_word_count: usize, + pub keywords_metrics: KeywordsMetrics, } +/// See `Geoname` for documentation. #[derive(Clone, Debug, Deserialize)] -pub(crate) struct DownloadedGeonameAttachment { - /// The max length of all names in the attachment. Used for name metrics. We - /// pre-compute this to avoid doing duplicate work on all user's machines. - pub max_alternate_name_length: u32, - /// The max word count across all names in the attachment. Used for name - /// metrics. We pre-compute this to avoid doing duplicate work on all user's - /// machines. - pub max_alternate_name_word_count: u32, - pub geonames: Vec, -} - -/// This corresponds to a single row in the main "geoname" table described in -/// the GeoNames documentation [1] except where noted. It represents a single -/// place. We exclude fields we don't need. -/// -/// [1] https://download.geonames.org/export/dump/readme.txt -#[derive(Clone, Debug, Deserialize)] -pub(crate) struct DownloadedGeoname { - /// The `geonameid` straight from the geoname table. - pub id: i64, - /// NOTE: For ease of implementation, this name should always also be - /// included as a lowercased alternate name even if the original GeoNames - /// data doesn't include it as an alternate. - pub name: String, - /// "P" - Populated place like a city or village. - /// "A" - Administrative division like a country, state, or region. - pub feature_class: String, - /// "ADM1" - Primary administrative division like a U.S. state. - pub feature_code: String, - /// ISO-3166 two-letter uppercase country code, e.g., "US". - pub country_code: String, - /// For the U.S., the two-letter uppercase state abbreviation. - pub admin1_code: String, - /// This can be helpful for resolving name conflicts. If two geonames have - /// the same name, we might prefer the one with the larger population. - pub population: u64, - /// Latitude in decimal degrees. Expected to be a string in the RS data. - #[serde(deserialize_with = "deserialize_f64_or_default")] - pub latitude: f64, - /// Longitude in decimal degrees. Expected to be a string in the RS data. - #[serde(deserialize_with = "deserialize_f64_or_default")] - pub longitude: f64, - /// List of names that the place is known by. Despite the word "alternate", - /// this often includes the place's proper name. This list is pulled from - /// the "alternate names" table described in the GeoNames documentation and - /// included here inline. - /// - /// NOTE: For ease of implementation, this list should always include a - /// lowercase version of `name` even if the original GeoNames record doesn't - /// include it as an alternate. - /// - /// Version 1 of this field was a `Vec`. - pub alternate_names_2: Vec, -} - -#[derive(Clone, Debug, Deserialize)] -pub(crate) struct DownloadedGeonameAlternate { - /// Lowercase alternate name. +struct DownloadedGeoname { + id: GeonameId, name: String, - /// The value of the `iso_language` field for the alternate. This will be - /// `None` for the alternate we artificially create for the `name` in the - /// corresponding geoname record. - iso_language: Option, + ascii_name: Option, + feature_class: String, + feature_code: String, + country: String, + admin1: Option, + admin2: Option, + admin3: Option, + admin4: Option, + population: Option, + latitude: Option, + longitude: Option, +} + +#[derive(Clone, Debug, Deserialize)] +struct DownloadedGeonamesAlternatesAttachment { + /// The language of the names in this attachment as a lowercase ISO 639 + /// code: "en", "de", "fr", etc. Can also be a geonames pseduo-language like + /// "abbr" for abbreviations and "iata" for airport codes. + language: String, + /// Tuples of geoname IDs and their alternate names. + alternates_by_geoname_id: Vec<(GeonameId, Vec>)>, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +enum DownloadedGeonamesAlternate> { + Name(S), + Full { + name: S, + is_preferred: Option, + is_short: Option, + }, +} + +impl> DownloadedGeonamesAlternate { + fn name(&self) -> &str { + match self { + Self::Name(name) => name.as_ref(), + Self::Full { name, .. } => name.as_ref(), + } + } + + fn is_preferred(&self) -> bool { + match self { + Self::Name(_) => false, + Self::Full { is_preferred, .. } => is_preferred.unwrap_or(false), + } + } + + fn is_short(&self) -> bool { + match self { + Self::Name(_) => false, + Self::Full { is_short, .. } => is_short.unwrap_or(false), + } + } +} + +/// Compares two strings ignoring case, Unicode combining marks, and some +/// punctuation. Intended to be used as a Sqlite collating sequence for +/// comparing geoname names. +pub fn geonames_collate(a: &str, b: &str) -> std::cmp::Ordering { + UniCase::new(collate_remove_chars(a)).cmp(&UniCase::new(collate_remove_chars(b))) +} + +fn collate_remove_chars(s: &str) -> Cow<'_, str> { + let borrowable = !s + .nfkd() + .any(|c| is_combining_mark(c) || matches!(c, '.' | ',' | '-')); + + if borrowable { + Cow::from(s) + } else { + s.nfkd() + .filter_map(|c| { + if is_combining_mark(c) { + // Remove Unicode combining marks: + // "Que\u{0301}bec" => "Quebec" + None + } else { + match c { + // Remove '.' and ',': + // "St. Louis, U.S.A." => "St Louis USA" + '.' | ',' => None, + // Replace '-' with space: + // "Carmel-by-the-Sea" => "Carmel by the Sea" + '-' => Some(' '), + _ => Some(c), + } + } + }) + .collect::<_>() + } } impl SuggestDao<'_> { @@ -200,18 +316,12 @@ impl SuggestDao<'_> { /// will match. Prefix matching is never performed on abbreviations and /// airport codes because we don't currently have a use case for that. /// - /// `geoname_type` restricts returned geonames to the specified type. `None` - /// restricts geonames to cities and regions. There's no way to return - /// geonames of other types, but we shouldn't ingest other types to begin - /// with. - /// - /// `filter` restricts returned geonames to certain cities or regions. - /// Cities can be restricted to certain regions by including the regions in - /// `filter`, and regions can be restricted to those containing certain - /// cities by including the cities in `filter`. This is especially useful - /// since city and region names are not unique. `filter` is disjunctive: If - /// any item in `filter` matches a geoname, the geoname will be filtered in. - /// If `filter` is empty, all geonames will be filtered out. + /// `filter` restricts returned geonames to those that are related to the + /// ones in the filter. Cities can be restricted to administrative divisions + /// by including the divisions in `filter` and vice versa. This is + /// especially useful since place names are not unique. `filter` is + /// conjunctive: All geonames in `filter` must be related to a geoname in + /// order for it to be filtered in. /// /// The returned matches will include all matching types for a geoname, one /// match per type per geoname. For example, if the query matches both a @@ -223,74 +333,102 @@ impl SuggestDao<'_> { &self, query: &str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, ) -> Result> { - let city_pred = "(g.feature_class = 'P')"; - let region_pred = "(g.feature_class = 'A' AND g.feature_code = 'ADM1')"; - let type_pred = match geoname_type { - None => format!("({} OR {})", city_pred, region_pred), - Some(GeonameType::City) => city_pred.to_string(), - Some(GeonameType::Region) => region_pred.to_string(), - }; + let candidate_name = query; Ok(self .conn .query_rows_and_then_cached( - &format!( - r#" - SELECT - g.id, - g.name, - g.latitude, - g.longitude, - g.feature_class, - g.country_code, - g.admin1_code, - g.population, - a.name != :name AS prefix, - (SELECT CASE - -- abbreviation - WHEN a.iso_language = 'abbr' THEN 1 - -- airport code - WHEN a.iso_language IN ('iata', 'icao', 'faac') THEN 2 - -- name - ELSE 3 - END - ) AS match_type - FROM - geonames g - JOIN - geonames_alternates a ON g.id = a.geoname_id - WHERE - {} - AND CASE :prefix - WHEN FALSE THEN a.name = :name - ELSE (a.name = :name OR ( - (a.name BETWEEN :name AND :name || X'FFFF') - AND match_type = 3 - )) - END - GROUP BY - g.id, match_type - ORDER BY - g.feature_class = 'P' DESC, g.population DESC, g.id ASC, a.iso_language ASC - "#, - type_pred - ), + r#" + SELECT + g.id, + g.name, + g.feature_class, + g.feature_code, + g.country_code, + g.admin1_code, + g.admin2_code, + g.admin3_code, + g.admin4_code, + g.population, + g.latitude, + g.longitude, + a.name != :name AS prefix, + (SELECT CASE + -- abbreviation + WHEN a.language = 'abbr' THEN 1 + -- airport code + WHEN a.language IN ('iata', 'icao', 'faac') THEN 2 + -- name + ELSE 3 + END + ) AS match_type + FROM + geonames g + JOIN + geonames_alternates a ON g.id = a.geoname_id + WHERE + a.name = :name + OR ( + :prefix + AND match_type = 3 + AND (a.name BETWEEN :name AND :name || X'FFFF') + ) + GROUP BY + g.id, match_type + ORDER BY + g.feature_class = 'P' DESC, g.population DESC, g.id ASC, a.language ASC + "#, named_params! { - ":name": query.to_lowercase(), + ":name": candidate_name, ":prefix": match_name_prefix, }, |row| -> Result> { + let feature_class: String = row.get("feature_class")?; + let feature_code: String = row.get("feature_code")?; + let geoname_type = match feature_class.as_str() { + "A" => { + if feature_code.starts_with("P") { + GeonameType::Country + } else { + match feature_code.as_str() { + "ADM1" => GeonameType::AdminDivision { level: 1 }, + "ADM2" => GeonameType::AdminDivision { level: 2 }, + "ADM3" => GeonameType::AdminDivision { level: 3 }, + "ADM4" => GeonameType::AdminDivision { level: 4 }, + _ => GeonameType::AdminDivisionOther, + } + } + } + "P" => GeonameType::City, + _ => GeonameType::Other, + }; let g_match = GeonameMatch { geoname: Geoname { geoname_id: row.get("id")?, + geoname_type, name: row.get("name")?, - latitude: row.get("latitude")?, - longitude: row.get("longitude")?, + feature_class, + feature_code, country_code: row.get("country_code")?, - admin1_code: row.get("admin1_code")?, - population: row.get("population")?, + admin_division_codes: [ + row.get::<_, Option>("admin1_code")?.map(|c| (1, c)), + row.get::<_, Option>("admin2_code")?.map(|c| (2, c)), + row.get::<_, Option>("admin3_code")?.map(|c| (3, c)), + row.get::<_, Option>("admin4_code")?.map(|c| (4, c)), + ] + .into_iter() + .flatten() + .collect(), + population: row + .get::<_, Option>("population")? + .unwrap_or_default(), + latitude: row + .get::<_, Option>("latitude")? + .unwrap_or_default(), + longitude: row + .get::<_, Option>("longitude")? + .unwrap_or_default(), }, prefix: row.get("prefix")?, match_type: match row.get::<_, i32>("match_type")? { @@ -300,11 +438,11 @@ impl SuggestDao<'_> { }, }; if let Some(geonames) = &filter { - geonames - .iter() - .find(|g| g.has_same_region(&g_match.geoname)) - .map(|_| Ok(Some(g_match))) - .unwrap_or(Ok(None)) + if geonames.iter().all(|g| g.is_related_to(&g_match.geoname)) { + Ok(Some(g_match)) + } else { + Ok(None) + } } else { Ok(Some(g_match)) } @@ -315,61 +453,230 @@ impl SuggestDao<'_> { .collect()) } + /// Fetches alternate names for a geoname and its country and admin + /// divisions. + pub fn fetch_geoname_alternates(&self, geoname: &Geoname) -> Result { + #[derive(Debug)] + struct Row { + geoname_id: GeonameId, + feature_code: String, + primary_name: String, + alt_language: Option, + alt_name: String, + } + + let rows = self.conn.query_rows_and_then_cached( + r#" + SELECT + g.id, + g.feature_code, + g.name AS primary_name, + a.language AS alt_language, + a.name AS alt_name + FROM + geonames g + JOIN + geonames_alternates a ON g.id = a.geoname_id + WHERE + -- Ignore airport codes + (a.language IS NULL OR a.language NOT IN ('iata', 'icao', 'faac')) + AND ( + -- The row matches the passed-in geoname + g.id = :geoname_id + -- The row matches the geoname's country + OR ( + g.feature_code IN ('PCLI', 'PCL', 'PCLD', 'PCLF', 'PCLS') + AND g.country_code = :country + ) + -- The row matches one of the geoname's admin divisions + OR (g.feature_code = 'ADM1' AND g.admin1_code = :admin1) + OR (g.feature_code = 'ADM2' AND g.admin2_code = :admin2) + OR (g.feature_code = 'ADM3' AND g.admin3_code = :admin3) + OR (g.feature_code = 'ADM4' AND g.admin4_code = :admin4) + ) + ORDER BY + -- Group rows for the same geoname together + g.id ASC, + -- Sort preferred and short names first; longer names tend to be + -- less commonly used ("California" vs. "State of California") + a.is_preferred DESC, + a.is_short DESC, + -- `a.language` is null for the primary and ASCII name (see + -- `insert_geonames`); sort those last + a.language IS NULL ASC, + -- Group by language; `a.language` should be either null, 'abbr' + -- for abbreviations, or the language code that was ingested + -- according to the locale in the RS context + a.language ASC, + -- Sort shorter names first, same reason as above + length(a.name) ASC, + a.name ASC + "#, + named_params! { + ":geoname_id": geoname.geoname_id, + ":country": geoname.country_code, + ":admin1": geoname.admin_division_codes.get(&1), + ":admin2": geoname.admin_division_codes.get(&2), + ":admin3": geoname.admin_division_codes.get(&3), + ":admin4": geoname.admin_division_codes.get(&4), + }, + |row| -> Result { + Ok(Row { + geoname_id: row.get("id")?, + feature_code: row.get("feature_code")?, + primary_name: row.get("primary_name")?, + alt_language: row.get("alt_language")?, + alt_name: row.get("alt_name")?, + }) + }, + )?; + + let mut geoname_localized: OnceCell = OnceCell::new(); + let mut geoname_abbr: OnceCell = OnceCell::new(); + let mut country_primary: OnceCell = OnceCell::new(); + let mut country_localized: OnceCell = OnceCell::new(); + let mut country_abbr: OnceCell = OnceCell::new(); + let mut admin_primary: HashMap = HashMap::new(); + let mut admin_localized: HashMap = HashMap::new(); + let mut admin_abbr: HashMap = HashMap::new(); + + // Loop through the rows. For each of the geoname, country, and admin + // divisions, save the first primary name, localized name, abbreviation + // we encounter. The `ORDER BY` in the query ensures that these will be + // the best names for each (or what we guess will be the best names). + for row in rows.into_iter() { + if row.geoname_id == geoname.geoname_id { + match row.alt_language.as_deref() { + Some("abbr") => geoname_abbr.get_or_init(|| row.alt_name), + _ => geoname_localized.get_or_init(|| row.alt_name), + }; + } else if let Some(level) = match row.feature_code.as_str() { + "ADM1" => Some(1), + "ADM2" => Some(2), + "ADM3" => Some(3), + "ADM4" => Some(4), + _ => None, + } { + admin_primary.entry(level).or_insert(row.primary_name); + match row.alt_language.as_deref() { + Some("abbr") => admin_abbr.entry(level).or_insert(row.alt_name), + _ => admin_localized.entry(level).or_insert(row.alt_name), + }; + } else { + country_primary.get_or_init(|| row.primary_name); + match row.alt_language.as_deref() { + Some("abbr") => country_abbr.get_or_init(|| row.alt_name), + _ => country_localized.get_or_init(|| row.alt_name), + }; + } + } + + Ok(GeonameAlternates { + geoname: AlternateNames { + primary: geoname.name.clone(), + localized: geoname_localized.take(), + abbreviation: geoname_abbr.take(), + }, + country: country_primary.take().map(|primary| AlternateNames { + primary, + localized: country_localized.take(), + abbreviation: country_abbr.take(), + }), + admin_divisions: geoname + .admin_division_codes + .keys() + .filter_map(|level| { + admin_primary.remove(level).map(|primary| { + ( + *level, + AlternateNames { + primary, + localized: admin_localized.remove(level), + abbreviation: admin_abbr.remove(level), + }, + ) + }) + }) + .collect(), + }) + } + /// Inserts GeoNames data into the database. fn insert_geonames( &mut self, record_id: &SuggestRecordId, - attachments: &[DownloadedGeonameAttachment], + geonames: &[DownloadedGeoname], ) -> Result<()> { self.scope.err_if_interrupted()?; + let mut geoname_insert = GeonameInsertStatement::new(self.conn)?; let mut alt_insert = GeonameAlternateInsertStatement::new(self.conn)?; - let mut metrics_insert = GeonameMetricsInsertStatement::new(self.conn)?; - let mut max_len = 0; - let mut max_word_count = 0; - for attach in attachments { - for geoname in &attach.geonames { - geoname_insert.execute(record_id, geoname)?; - for alt in &geoname.alternate_names_2 { - alt_insert.execute(alt, geoname.id)?; - } + let mut metrics_updater = KeywordsMetricsUpdater::new(); + + for geoname in geonames { + geoname_insert.execute(record_id, geoname)?; + + // Add alternates for each geoname's primary name (`geoname.name`) + // and ASCII name. `language` is set to null for these alternates. + alt_insert.execute( + record_id, + geoname.id, + None, // language + &DownloadedGeonamesAlternate::Name(geoname.name.as_str()), + )?; + metrics_updater.update(&geoname.name); + + if let Some(ascii_name) = &geoname.ascii_name { + alt_insert.execute( + record_id, + geoname.id, + None, // language + &DownloadedGeonamesAlternate::Name(ascii_name.as_str()), + )?; + metrics_updater.update(ascii_name); } - max_len = std::cmp::max(max_len, attach.max_alternate_name_length as usize); - max_word_count = std::cmp::max( - max_word_count, - attach.max_alternate_name_word_count as usize, - ); } - // Update geoname metrics. - metrics_insert.execute(record_id, max_len, max_word_count)?; - - // We just made some insertions that might invalidate the data in the - // cache. Clear it so it's repopulated the next time it's accessed. - self.geoname_cache.take(); + metrics_updater.finish( + self.conn, + record_id, + SuggestRecordType::GeonamesAlternates, + &mut self.geoname_cache, + )?; Ok(()) } + /// Inserts GeoNames alternates data into the database. + fn insert_geonames_alternates( + &mut self, + record_id: &SuggestRecordId, + attachments: &[DownloadedGeonamesAlternatesAttachment], + ) -> Result<()> { + let mut alt_insert = GeonameAlternateInsertStatement::new(self.conn)?; + let mut metrics_updater = KeywordsMetricsUpdater::new(); + for attach in attachments { + for (geoname_id, alts) in &attach.alternates_by_geoname_id { + for alt in alts { + alt_insert.execute(record_id, *geoname_id, Some(&attach.language), alt)?; + metrics_updater.update(alt.name()); + } + } + } + metrics_updater.finish( + self.conn, + record_id, + SuggestRecordType::GeonamesAlternates, + &mut self.geoname_cache, + )?; + Ok(()) + } + pub fn geoname_cache(&self) -> &GeonameCache { - self.geoname_cache.get_or_init(|| { - self.conn - .query_row_and_then( - r#" - SELECT - max(max_name_length) AS len, max(max_name_word_count) AS word_count - FROM - geonames_metrics - "#, - [], - |row| -> Result { - Ok(GeonameCache { - max_name_length: row.get("len")?, - max_name_word_count: row.get("word_count")?, - }) - }, - ) - .unwrap_or_default() + self.geoname_cache.get_or_init(|| GeonameCache { + keywords_metrics: self + .get_keywords_metrics(SuggestRecordType::GeonamesAlternates) + .unwrap_or_default(), }) } } @@ -379,7 +686,7 @@ where S: Client, { /// Inserts a GeoNames record into the database. - pub fn process_geoname_record( + pub fn process_geonames_record( &self, dao: &mut SuggestDao, record: &Record, @@ -389,6 +696,18 @@ where dao.insert_geonames(record_id, data) }) } + + /// Inserts a GeoNames record into the database. + pub fn process_geonames_alternates_record( + &self, + dao: &mut SuggestDao, + record: &Record, + context: &mut MetricsContext, + ) -> Result<()> { + self.download_attachment(dao, record, context, |dao, record_id, data| { + dao.insert_geonames_alternates(record_id, data) + }) + } } struct GeonameInsertStatement<'conn>(rusqlite::Statement<'conn>); @@ -400,33 +719,39 @@ impl<'conn> GeonameInsertStatement<'conn> { id, record_id, name, - latitude, - longitude, feature_class, feature_code, country_code, admin1_code, - population + admin2_code, + admin3_code, + admin4_code, + population, + latitude, + longitude ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ", )?)) } fn execute(&mut self, record_id: &SuggestRecordId, g: &DownloadedGeoname) -> Result<()> { self.0 - .execute(( + .execute(rusqlite::params![ &g.id, record_id.as_str(), &g.name, - &g.latitude, - &g.longitude, &g.feature_class, &g.feature_code, - &g.country_code, - &g.admin1_code, + &g.country, + &g.admin1, + &g.admin2, + &g.admin3, + &g.admin4, &g.population, - )) + &g.latitude, + &g.longitude, + ]) .with_context("geoname insert")?; Ok(()) } @@ -437,48 +762,37 @@ struct GeonameAlternateInsertStatement<'conn>(rusqlite::Statement<'conn>); impl<'conn> GeonameAlternateInsertStatement<'conn> { fn new(conn: &'conn Connection) -> Result { Ok(Self(conn.prepare( - "INSERT OR REPLACE INTO geonames_alternates( - name, - geoname_id, - iso_language - ) - VALUES(?, ?, ?) - ", + r#" + INSERT INTO geonames_alternates( + record_id, + geoname_id, + language, + name, + is_preferred, + is_short + ) + VALUES(?, ?, ?, ?, ?, ?) + "#, )?)) } - fn execute(&mut self, a: &DownloadedGeonameAlternate, geoname_id: i64) -> Result<()> { - self.0 - .execute((&a.name, geoname_id, &a.iso_language)) - .with_context("geoname alternate insert")?; - Ok(()) - } -} - -struct GeonameMetricsInsertStatement<'conn>(rusqlite::Statement<'conn>); - -impl<'conn> GeonameMetricsInsertStatement<'conn> { - pub(crate) fn new(conn: &'conn Connection) -> Result { - Ok(Self(conn.prepare( - "INSERT OR REPLACE INTO geonames_metrics( - record_id, - max_name_length, - max_name_word_count - ) - VALUES(?, ?, ?) - ", - )?)) - } - - pub(crate) fn execute( + fn execute>( &mut self, record_id: &SuggestRecordId, - max_len: usize, - max_word_count: usize, + geoname_id: GeonameId, + language: Option<&str>, + alt: &DownloadedGeonamesAlternate, ) -> Result<()> { self.0 - .execute((record_id.as_str(), max_len, max_word_count)) - .with_context("geoname metrics insert")?; + .execute(( + record_id.as_str(), + geoname_id, + language, + alt.name(), + alt.is_preferred(), + alt.is_short(), + )) + .with_context("geoname alternate insert")?; Ok(()) } } @@ -493,9 +807,10 @@ pub(crate) mod tests { testing::*, SuggestIngestionConstraints, }; + use itertools::Itertools; use serde_json::Value as JsonValue; - pub(crate) const LONG_NAME: &str = "aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp qqq rrr sss ttt uuu vvv www x yyy zzz"; + pub(crate) const LONG_NAME: &str = "123 aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp qqq rrr sss ttt uuu vvv www x yyy zzz"; pub(crate) fn geoname_mock_record(id: &str, json: JsonValue) -> MockRecord { MockRecord { @@ -507,311 +822,1133 @@ pub(crate) mod tests { } } + pub(crate) fn geoname_alternates_mock_record(id: &str, json: JsonValue) -> MockRecord { + MockRecord { + collection: Collection::Other, + record_type: SuggestRecordType::GeonamesAlternates, + id: id.to_string(), + inline_data: None, + attachment: Some(MockAttachment::Json(json)), + } + } + pub(crate) fn new_test_store() -> TestStore { TestStore::new( MockRemoteSettingsClient::default() - .with_record(geoname_mock_record("geonames-0", geonames_data())), + .with_record(geoname_mock_record("geonames-0", geonames_data())) + .with_record(geoname_alternates_mock_record( + "geonames-alternates-en", + geonames_alternates_data_en(), + )) + .with_record(geoname_alternates_mock_record( + "geonames-alternates-abbr", + geonames_alternates_data_abbr(), + )) + .with_record(geoname_alternates_mock_record( + "geonames-alternates-iata", + geonames_alternates_data_iata(), + )), ) } fn geonames_data() -> serde_json::Value { + json!([ + // Waterloo, AL + { + "id": 4096497, + "name": "Waterloo", + "feature_class": "P", + "feature_code": "PPL", + "country": "US", + "admin1": "AL", + "admin2": "077", + "population": 200, + "latitude": "34.91814", + "longitude": "-88.0642", + }, + + // AL + { + "id": 4829764, + "name": "Alabama", + "feature_class": "A", + "feature_code": "ADM1", + "country": "US", + "admin1": "AL", + "population": 4530315, + "latitude": "32.75041", + "longitude": "-86.75026", + }, + + // Waterloo, IA + { + "id": 4880889, + "name": "Waterloo", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "US", + "admin1": "IA", + "admin2": "013", + "admin3": "94597", + "population": 68460, + "latitude": "42.49276", + "longitude": "-92.34296", + }, + + // IA + { + "id": 4862182, + "name": "Iowa", + "feature_class": "A", + "feature_code": "ADM1", + "country": "US", + "admin1": "IA", + "population": 2955010, + "latitude": "42.00027", + "longitude": "-93.50049", + }, + + // New York City + { + "id": 5128581, + "name": "New York City", + "feature_class": "P", + "feature_code": "PPL", + "country": "US", + "admin1": "NY", + "population": 8804190, + "latitude": "40.71427", + "longitude": "-74.00597", + }, + + // Rochester, NY + { + "id": 5134086, + "name": "Rochester", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "US", + "admin1": "NY", + "admin2": "055", + "admin3": "63000", + "population": 209802, + "latitude": "43.15478", + "longitude": "-77.61556", + }, + + // NY state + { + "id": 5128638, + "name": "New York", + "feature_class": "A", + "feature_code": "ADM1", + "country": "US", + "admin1": "NY", + "population": 19274244, + "latitude": "43.00035", + "longitude": "-75.4999", + }, + + // Waco, TX: Has a surprising IATA airport code that's a + // common English word and not a prefix of the city name + { + "id": 4739526, + "name": "Waco", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "US", + "admin1": "TX", + "admin2": "309", + "population": 132356, + "latitude": "31.54933", + "longitude": "-97.14667", + }, + + // TX + { + "id": 4736286, + "name": "Texas", + "feature_class": "A", + "feature_code": "ADM1", + "country": "US", + "admin1": "TX", + "population": 22875689, + "latitude": "31.25044", + "longitude": "-99.25061", + }, + + // Made-up city with a long name (the digits in the name are to + // prevent matches on this geoname in weather tests, etc.) + { + "id": 999, + "name": "123 Long Name", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "US", + "admin1": "NY", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + + // Made-up cities with punctuation their alternates (the digits in + // the names are to prevent matches on these geonames in weather + // tests, etc.) + { + "id": 1000, + "name": "123 Punctuation City 0", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + { + "id": 1001, + "name": "123 Punctuation City 1", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + { + "id": 1002, + "name": "123 Punctuation City 2", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + { + "id": 1003, + "name": "123 Punctuation City 3", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + { + "id": 1004, + "name": "123 Punctuation City 4", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + { + "id": 1005, + "name": "123 Punctuation City 5", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "XX", + "population": 2, + "latitude": "38.06084", + "longitude": "-97.92977", + }, + + // St. Louis (has '.' in name) + { + "id": 4407066, + "name": "St. Louis", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "US", + "admin1": "MO", + "admin2": "510", + "population": 315685, + "latitude": "38.62727", + "longitude": "-90.19789", + }, + + // Carmel-by-the-Sea (has '-' in name) + { + "id": 5334320, + "name": "Carmel-by-the-Sea", + "feature_class": "P", + "feature_code": "PPL", + "country": "US", + "admin1": "CA", + "admin2": "053", + "population": 3897, + "latitude": "36.55524", + "longitude": "-121.92329", + }, + + // United States + { + "id": 6252001, + "name": "United States", + "feature_class": "A", + "feature_code": "PCLI", + "country": "US", + "admin1": "00", + "population": 327167434, + "latitude": "39.76", + "longitude": "-98.5", + }, + + // Canada + { + "id": 6251999, + "name": "Canada", + "feature_class": "A", + "feature_code": "PCLI", + "country": "CA", + "admin1": "00", + "population": 37058856, + "latitude": "60.10867", + "longitude": "-113.64258", + }, + + // ON + { + "id": 6093943, + "name": "Ontario", + "feature_class": "A", + "feature_code": "ADM1", + "country": "CA", + "admin1": "08", + "population": 12861940, + "latitude": "49.25014", + "longitude": "-84.49983", + }, + + // Waterloo, ON + { + "id": 6176823, + "name": "Waterloo", + "feature_class": "P", + "feature_code": "PPL", + "country": "CA", + "admin1": "08", + "admin2": "3530", + "population": 104986, + "latitude": "43.4668", + "longitude": "-80.51639", + }, + + // UK + { + "id": 2635167, + "name": "United Kingdom of Great Britain and Northern Ireland", + "feature_class": "A", + "feature_code": "PCLI", + "country": "GB", + "admin1": "00", + "population": 66488991, + "latitude": "54.75844", + "longitude": "-2.69531", + }, + + // England + { + "id": 6269131, + "name": "England", + "feature_class": "A", + "feature_code": "ADM1", + "country": "GB", + "admin1": "ENG", + "population": 57106398, + "latitude": "52.16045", + "longitude": "-0.70312", + }, + + // Liverpool (metropolitan borough, admin2 for Liverpool city) + { + "id": 3333167, + "name": "Liverpool", + "feature_class": "A", + "feature_code": "ADM2", + "country": "GB", + "admin1": "ENG", + "admin2": "H8", + "population": 484578, + "latitude": "53.41667", + "longitude": "-2.91667", + }, + + // Liverpool (city) + { + "id": 2644210, + "name": "Liverpool", + "feature_class": "P", + "feature_code": "PPLA2", + "country": "GB", + "admin1": "ENG", + "admin2": "H8", + "population": 864122, + "latitude": "53.41058", + "longitude": "-2.97794", + }, + + // Gößnitz, DE (has non-basic-Latin chars and an `ascii_name`) + { + "id": 2918770, + "name": "Gößnitz", + "ascii_name": "Goessnitz", + "feature_class": "P", + "feature_code": "PPL", + "country": "DE", + "admin1": "15", + "admin2": "00", + "admin3": "16077", + "admin4": "16077012", + "population": 4104, + "latitude": "50.88902", + "longitude": "12.43292", + }, + ]) + } + + fn geonames_alternates_data_en() -> serde_json::Value { json!({ - "max_alternate_name_length": LONG_NAME.len(), - "max_alternate_name_word_count": LONG_NAME.split_whitespace().collect::>().len(), - "geonames": [ - // Waterloo, AL - { - "id": 1, - "name": "Waterloo", - "latitude": "34.91814", - "longitude": "-88.0642", - "feature_class": "P", - "feature_code": "PPL", - "country_code": "US", - "admin1_code": "AL", - "population": 200, - "alternate_names": ["waterloo"], - "alternate_names_2": [ - { "name": "waterloo" }, - ], - }, - // AL - { - "id": 2, - "name": "Alabama", - "latitude": "32.75041", - "longitude": "-86.75026", - "feature_class": "A", - "feature_code": "ADM1", - "country_code": "US", - "admin1_code": "AL", - "population": 4530315, - "alternate_names": ["al", "alabama"], - "alternate_names_2": [ - { "name": "alabama" }, - { "name": "al", "iso_language": "abbr" }, - ], - }, - // Waterloo, IA - { - "id": 3, - "name": "Waterloo", - "latitude": "42.49276", - "longitude": "-92.34296", - "feature_class": "P", - "feature_code": "PPLA2", - "country_code": "US", - "admin1_code": "IA", - "population": 68460, - "alternate_names": ["waterloo"], - "alternate_names_2": [ - { "name": "waterloo" }, - ], - }, - // IA - { - "id": 4, - "name": "Iowa", - "latitude": "42.00027", - "longitude": "-93.50049", - "feature_class": "A", - "feature_code": "ADM1", - "country_code": "US", - "admin1_code": "IA", - "population": 2955010, - "alternate_names": ["ia", "iowa"], - "alternate_names_2": [ - { "name": "iowa" }, - { "name": "ia", "iso_language": "abbr" }, - ], - }, - // Waterloo (Lake, not a city or region) - { - "id": 5, - "name": "waterloo lake", - "latitude": "31.25044", - "longitude": "-99.25061", - "feature_class": "H", - "feature_code": "LK", - "country_code": "US", - "admin1_code": "TX", - "population": 0, - "alternate_names_2": [ - { "name": "waterloo lake" }, - { "name": "waterloo", "iso_language": "en" }, - ], - }, + "language": "en", + "alternates_by_geoname_id": [ + // United States + [6252001, [ + { "name": "United States", "is_preferred": true, "is_short": true }, + { "name": "United States of America", "is_preferred": true }, + { "name": "USA", "is_short": true }, + "America", + ]], + + // UK + [2635167, [ + { "name": "United Kingdom", "is_preferred": true, "is_short": true }, + { "name": "Great Britain", "is_short": true }, + { "name": "UK", "is_short": true }, + "Britain", + "U.K.", + "United Kingdom of Great Britain and Northern Ireland", + "U.K", + ]], + // New York City - { - "id": 6, - "name": "New York City", - "latitude": "40.71427", - "longitude": "-74.00597", - "feature_class": "P", - "feature_code": "PPL", - "country_code": "US", - "admin1_code": "NY", - "population": 8804190, - "alternate_names_2": [ - { "name": "new york city" }, - { "name": "new york", "iso_language": "en" }, - { "name": "nyc", "iso_language": "abbr" }, - { "name": "ny", "iso_language": "abbr" }, - ], - }, - // Rochester, NY - { - "id": 7, - "name": "Rochester", - "latitude": "43.15478", - "longitude": "-77.61556", - "feature_class": "P", - "feature_code": "PPLA2", - "country_code": "US", - "admin1_code": "NY", - "population": 209802, - "alternate_names_2": [ - { "name": "rochester" }, - { "name": "roc", "iso_language": "iata" }, - ], - }, - // NY state - { - "id": 8, - "name": "New York", - "latitude": "43.00035", - "longitude": "-75.4999", - "feature_class": "A", - "feature_code": "ADM1", - "country_code": "US", - "admin1_code": "NY", - "population": 19274244, - "alternate_names_2": [ - { "name": "new york" }, - { "name": "ny", "iso_language": "abbr" }, - ], - }, - // Waco, TX: Has a surprising IATA airport code that's a - // common English word and not a prefix of the city name - { - "id": 9, - "name": "Waco", - "latitude": "31.54933", - "longitude": "-97.14667", - "feature_class": "P", - "feature_code": "PPLA2", - "country_code": "US", - "admin1_code": "TX", - "population": 132356, - "alternate_names_2": [ - { "name": "waco" }, - { "name": "act", "iso_language": "iata" }, - ], - }, - // TX - { - "id": 10, - "name": "Texas", - "latitude": "31.25044", - "longitude": "-99.25061", - "feature_class": "A", - "feature_code": "ADM1", - "country_code": "US", - "admin1_code": "TX", - "population": 22875689, - "alternate_names_2": [ - { "name": "texas" }, - { "name": "tx", "iso_language": "abbr" }, - ], - }, + [5128581, [ + { "name": "New York", "is_preferred": true, "is_short": true }, + ]], + // Made-up city with a long name - { - "id": 999, - "name": "Long Name", - "latitude": "38.06084", - "longitude": "-97.92977", - "feature_class": "P", - "feature_code": "PPLA2", - "country_code": "US", - "admin1_code": "NY", - "population": 2, - "alternate_names_2": [ - { "name": "long name" }, - { "name": LONG_NAME, "iso_language": "en" }, - ], - }, + [999, [LONG_NAME]], + + // Made-up cities with punctuation in their alternates + [1000, [ + // The first name is shorter, so we should prefer it. + "123 Made Up City w Punct in Alternates", + "123 Made-Up City. w/ Punct. in Alternates", + ]], + [1001, [ + // The second name is shorter, so we should prefer it. + "123 Made-Up City. w/ Punct. in Alternates", + "123 Made Up City w Punct in Alternates", + ]], + [1002, [ + // These names are the same length but the second will be + // sorted first due to the `a.name ASC` in the `ORDER BY`, + // so we should prefer it. + "123 Made-Up City. w/ Punct. in Alternates", + "123 Made Up City w Punct in Alternates", + "123 Made-Up City. w/ Punct. in Alternatex", + ]], + [1003, [ + // The second name has `is_preferred`, so we should prefer + // it. + "123 Aaa Bbb Ccc Ddd", + { "name": "123 Aaa, Bbb-Ccc. Ddd", "is_preferred": true }, + "123 Aaa Bbb Ccc Eee", + ]], + [1004, [ + // The second name has `is_short`, so we should prefer it. + "123 Aaa Bbb Ccc Ddd", + { "name": "123 Aaa, Bbb-Ccc. Ddd", "is_short": true }, + "123 Aaa Bbb Ccc Eee", + ]], + [1005, [ + // The second name has `is_preferred` and `is_short`, so we + // should prefer it. + "123 Aaa Bbb Ccc Ddd", + { "name": "123 Aaa, Bbb-Ccc. Ddd", "is_preferred": true, "is_short": true }, + "123 Aaa Bbb Ccc Eee", + ]], + ], + }) + } + + fn geonames_alternates_data_abbr() -> serde_json::Value { + json!({ + "language": "abbr", + "alternates_by_geoname_id": [ + // AL + [4829764, ["AL"]], + // IA + [4862182, ["IA"]], + // ON + [6093943, [ + "ON", + "Ont.", + ]], + // NY State + [5128638, ["NY"]], + // TX + [4736286, ["TX"]], + // New York City + [5128581, [ + "NYC", + "NY", + ]], + // United States + [6252001, [ + { "name": "US", "is_short": true }, + "U.S.", + "USA", + "U.S.A.", + ]], + // Liverpool (metropolitan borough, admin2 for Liverpool city) + [3333167, ["LIV"]], + // UK + [2635167, [ + "UK", + ]], + ], + }) + } + + fn geonames_alternates_data_iata() -> serde_json::Value { + json!({ + "language": "iata", + "alternates_by_geoname_id": [ + // Waco, TX + [4739526, ["ACT"]], + // Rochester, NY + [5134086, ["ROC"]], ], }) } pub(crate) fn waterloo_al() -> Geoname { Geoname { - geoname_id: 1, + geoname_id: 4096497, + geoname_type: GeonameType::City, name: "Waterloo".to_string(), - latitude: 34.91814, - longitude: -88.0642, + feature_class: "P".to_string(), + feature_code: "PPL".to_string(), country_code: "US".to_string(), - admin1_code: "AL".to_string(), + admin_division_codes: [(1, "AL".to_string()), (2, "077".to_string())].into(), population: 200, + latitude: "34.91814".to_string(), + longitude: "-88.0642".to_string(), } } pub(crate) fn waterloo_ia() -> Geoname { Geoname { - geoname_id: 3, + geoname_id: 4880889, + geoname_type: GeonameType::City, name: "Waterloo".to_string(), - latitude: 42.49276, - longitude: -92.34296, + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), country_code: "US".to_string(), - admin1_code: "IA".to_string(), + admin_division_codes: [ + (1, "IA".to_string()), + (2, "013".to_string()), + (3, "94597".to_string()), + ] + .into(), population: 68460, + latitude: "42.49276".to_string(), + longitude: "-92.34296".to_string(), } } pub(crate) fn nyc() -> Geoname { Geoname { - geoname_id: 6, + geoname_id: 5128581, + geoname_type: GeonameType::City, name: "New York City".to_string(), - latitude: 40.71427, - longitude: -74.00597, + feature_class: "P".to_string(), + feature_code: "PPL".to_string(), country_code: "US".to_string(), - admin1_code: "NY".to_string(), + admin_division_codes: [(1, "NY".to_string())].into(), population: 8804190, + latitude: "40.71427".to_string(), + longitude: "-74.00597".to_string(), } } pub(crate) fn rochester() -> Geoname { Geoname { - geoname_id: 7, + geoname_id: 5134086, + geoname_type: GeonameType::City, name: "Rochester".to_string(), - latitude: 43.15478, - longitude: -77.61556, + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), country_code: "US".to_string(), - admin1_code: "NY".to_string(), + admin_division_codes: [ + (1, "NY".to_string()), + (2, "055".to_string()), + (3, "63000".to_string()), + ] + .into(), population: 209802, + latitude: "43.15478".to_string(), + longitude: "-77.61556".to_string(), } } pub(crate) fn waco() -> Geoname { Geoname { - geoname_id: 9, + geoname_id: 4739526, + geoname_type: GeonameType::City, name: "Waco".to_string(), - latitude: 31.54933, - longitude: -97.14667, + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), country_code: "US".to_string(), - admin1_code: "TX".to_string(), + admin_division_codes: [(1, "TX".to_string()), (2, "309".to_string())].into(), population: 132356, + latitude: "31.54933".to_string(), + longitude: "-97.14667".to_string(), } } pub(crate) fn long_name_city() -> Geoname { Geoname { geoname_id: 999, - name: "Long Name".to_string(), - latitude: 38.06084, - longitude: -97.92977, + geoname_type: GeonameType::City, + name: "123 Long Name".to_string(), + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), country_code: "US".to_string(), - admin1_code: "NY".to_string(), + admin_division_codes: [(1, "NY".to_string())].into(), population: 2, + latitude: "38.06084".to_string(), + longitude: "-97.92977".to_string(), + } + } + + pub(crate) fn punctuation_city(i: i64) -> Geoname { + Geoname { + geoname_id: 1000 + i, + geoname_type: GeonameType::City, + name: format!("123 Punctuation City {i}"), + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), + country_code: "XX".to_string(), + admin_division_codes: [].into(), + population: 2, + latitude: "38.06084".to_string(), + longitude: "-97.92977".to_string(), } } pub(crate) fn al() -> Geoname { Geoname { - geoname_id: 2, + geoname_id: 4829764, + geoname_type: GeonameType::AdminDivision { level: 1 }, name: "Alabama".to_string(), - latitude: 32.75041, - longitude: -86.75026, + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), country_code: "US".to_string(), - admin1_code: "AL".to_string(), + admin_division_codes: [(1, "AL".to_string())].into(), population: 4530315, + latitude: "32.75041".to_string(), + longitude: "-86.75026".to_string(), } } pub(crate) fn ia() -> Geoname { Geoname { - geoname_id: 4, + geoname_id: 4862182, + geoname_type: GeonameType::AdminDivision { level: 1 }, name: "Iowa".to_string(), - latitude: 42.00027, - longitude: -93.50049, + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), country_code: "US".to_string(), - admin1_code: "IA".to_string(), + admin_division_codes: [(1, "IA".to_string())].into(), population: 2955010, + latitude: "42.00027".to_string(), + longitude: "-93.50049".to_string(), } } pub(crate) fn ny_state() -> Geoname { Geoname { - geoname_id: 8, + geoname_id: 5128638, + geoname_type: GeonameType::AdminDivision { level: 1 }, name: "New York".to_string(), - latitude: 43.00035, - longitude: -75.4999, + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), country_code: "US".to_string(), - admin1_code: "NY".to_string(), + admin_division_codes: [(1, "NY".to_string())].into(), population: 19274244, + latitude: "43.00035".to_string(), + longitude: "-75.4999".to_string(), } } + pub(crate) fn st_louis() -> Geoname { + Geoname { + geoname_id: 4407066, + geoname_type: GeonameType::City, + name: "St. Louis".to_string(), + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), + country_code: "US".to_string(), + admin_division_codes: [(1, "MO".to_string()), (2, "510".to_string())].into(), + population: 315685, + latitude: "38.62727".to_string(), + longitude: "-90.19789".to_string(), + } + } + + pub(crate) fn carmel() -> Geoname { + Geoname { + geoname_id: 5334320, + geoname_type: GeonameType::City, + name: "Carmel-by-the-Sea".to_string(), + feature_class: "P".to_string(), + feature_code: "PPL".to_string(), + country_code: "US".to_string(), + admin_division_codes: [(1, "CA".to_string()), (2, "053".to_string())].into(), + population: 3897, + latitude: "36.55524".to_string(), + longitude: "-121.92329".to_string(), + } + } + + pub(crate) fn us() -> Geoname { + Geoname { + geoname_id: 6252001, + geoname_type: GeonameType::Country, + name: "United States".to_string(), + feature_class: "A".to_string(), + feature_code: "PCLI".to_string(), + country_code: "US".to_string(), + admin_division_codes: [(1, "00".to_string())].into(), + population: 327167434, + latitude: "39.76".to_string(), + longitude: "-98.5".to_string(), + } + } + + pub(crate) fn canada() -> Geoname { + Geoname { + geoname_id: 6251999, + geoname_type: GeonameType::Country, + name: "Canada".to_string(), + feature_class: "A".to_string(), + feature_code: "PCLI".to_string(), + country_code: "CA".to_string(), + admin_division_codes: [(1, "00".to_string())].into(), + population: 37058856, + latitude: "60.10867".to_string(), + longitude: "-113.64258".to_string(), + } + } + + pub(crate) fn on() -> Geoname { + Geoname { + geoname_id: 6093943, + geoname_type: GeonameType::AdminDivision { level: 1 }, + name: "Ontario".to_string(), + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), + country_code: "CA".to_string(), + admin_division_codes: [(1, "08".to_string())].into(), + population: 12861940, + latitude: "49.25014".to_string(), + longitude: "-84.49983".to_string(), + } + } + + pub(crate) fn waterloo_on() -> Geoname { + Geoname { + geoname_id: 6176823, + geoname_type: GeonameType::City, + name: "Waterloo".to_string(), + feature_class: "P".to_string(), + feature_code: "PPL".to_string(), + country_code: "CA".to_string(), + admin_division_codes: [(1, "08".to_string()), (2, "3530".to_string())].into(), + population: 104986, + latitude: "43.4668".to_string(), + longitude: "-80.51639".to_string(), + } + } + + pub(crate) fn uk() -> Geoname { + Geoname { + geoname_id: 2635167, + geoname_type: GeonameType::Country, + name: "United Kingdom of Great Britain and Northern Ireland".to_string(), + feature_class: "A".to_string(), + feature_code: "PCLI".to_string(), + country_code: "GB".to_string(), + admin_division_codes: [(1, "00".to_string())].into(), + population: 66488991, + latitude: "54.75844".to_string(), + longitude: "-2.69531".to_string(), + } + } + + pub(crate) fn england() -> Geoname { + Geoname { + geoname_id: 6269131, + geoname_type: GeonameType::AdminDivision { level: 1 }, + name: "England".to_string(), + feature_class: "A".to_string(), + feature_code: "ADM1".to_string(), + country_code: "GB".to_string(), + admin_division_codes: [(1, "ENG".to_string())].into(), + population: 57106398, + latitude: "52.16045".to_string(), + longitude: "-0.70312".to_string(), + } + } + + pub(crate) fn liverpool_metro() -> Geoname { + Geoname { + geoname_id: 3333167, + geoname_type: GeonameType::AdminDivision { level: 2 }, + name: "Liverpool".to_string(), + feature_class: "A".to_string(), + feature_code: "ADM2".to_string(), + country_code: "GB".to_string(), + admin_division_codes: [(1, "ENG".to_string()), (2, "H8".to_string())].into(), + population: 484578, + latitude: "53.41667".to_string(), + longitude: "-2.91667".to_string(), + } + } + + pub(crate) fn liverpool_city() -> Geoname { + Geoname { + geoname_id: 2644210, + geoname_type: GeonameType::City, + name: "Liverpool".to_string(), + feature_class: "P".to_string(), + feature_code: "PPLA2".to_string(), + country_code: "GB".to_string(), + admin_division_codes: [(1, "ENG".to_string()), (2, "H8".to_string())].into(), + population: 864122, + latitude: "53.41058".to_string(), + longitude: "-2.97794".to_string(), + } + } + + pub(crate) fn goessnitz() -> Geoname { + Geoname { + geoname_id: 2918770, + geoname_type: GeonameType::City, + name: "Gößnitz".to_string(), + feature_class: "P".to_string(), + feature_code: "PPL".to_string(), + country_code: "DE".to_string(), + admin_division_codes: [ + (1, "15".to_string()), + (2, "00".to_string()), + (3, "16077".to_string()), + (4, "16077012".to_string()), + ] + .into(), + population: 4104, + latitude: "50.88902".to_string(), + longitude: "12.43292".to_string(), + } + } + + #[test] + fn is_related_to() -> anyhow::Result<()> { + // The geonames in each vec should be pairwise related. + let tests = [ + vec![waterloo_ia(), ia(), us()], + vec![waterloo_al(), al(), us()], + vec![waterloo_on(), on(), canada()], + vec![liverpool_city(), liverpool_metro(), england(), uk()], + ]; + for geonames in tests { + for g in &geonames { + // A geoname should always be related to itself. + assert!( + g.is_related_to(g), + "g.is_related_to(g) should always be true: {:?}", + g + ); + } + for a_and_b in geonames.iter().permutations(2) { + assert!( + a_and_b[0].is_related_to(a_and_b[1]), + "is_related_to: {:?}", + a_and_b + ); + } + } + Ok(()) + } + + #[test] + fn is_not_related_to() -> anyhow::Result<()> { + // The geonames in each vec should not be pairwise related. + let tests = [ + vec![waterloo_ia(), al()], + vec![waterloo_ia(), on()], + vec![waterloo_ia(), canada(), uk()], + vec![waterloo_al(), ia()], + vec![waterloo_al(), on()], + vec![waterloo_al(), canada(), uk()], + vec![waterloo_on(), al()], + vec![waterloo_on(), ia()], + vec![waterloo_on(), us(), uk()], + vec![ + waterloo_ia(), + waterloo_al(), + waterloo_on(), + liverpool_city(), + ], + vec![liverpool_city(), us(), canada()], + vec![liverpool_metro(), us(), canada()], + vec![england(), us(), canada()], + vec![al(), ia(), on(), england()], + vec![us(), canada(), uk()], + ]; + for geonames in tests { + for a_and_b in geonames.iter().permutations(2) { + assert!( + !a_and_b[0].is_related_to(a_and_b[1]), + "!is_related_to: {:?}", + a_and_b + ); + } + } + Ok(()) + } + + #[test] + fn geonames_collate() -> anyhow::Result<()> { + let tests = [ + ["AbC xYz", "ABC XYZ", "abc xyz"].as_slice(), + &["Àęí", "Aei", "àęí", "aei"], + &[ + // "Québec" with single 'é' char + "Qu\u{00e9}bec", + // "Québec" with ASCII 'e' followed by combining acute accent + "Que\u{0301}bec", + "Quebec", + "quebec", + ], + &[ + "Gößnitz", + "Gössnitz", + "Goßnitz", + "Gossnitz", + "gößnitz", + "gössnitz", + "goßnitz", + "gossnitz", + ], + &["St. Louis", "St... Louis", "St Louis"], + &["U.S.A.", "US.A.", "U.SA.", "U.S.A", "USA.", "U.SA", "USA"], + &["Carmel-by-the-Sea", "Carmel by the Sea"], + &[".,-'()[]?<>", ".,-'()[]?<>"], + ]; + for strs in tests { + for a_and_b in strs.iter().permutations(2) { + assert_eq!( + super::geonames_collate(a_and_b[0], a_and_b[1]), + std::cmp::Ordering::Equal, + "Comparing: {:?}", + a_and_b + ); + } + } + Ok(()) + } + + #[test] + fn alternates() -> anyhow::Result<()> { + before_each(); + + let store = new_test_store(); + + // Ingest weather to also ingest geonames. + store.ingest(SuggestIngestionConstraints { + providers: Some(vec![SuggestionProvider::Weather]), + ..SuggestIngestionConstraints::all_providers() + }); + + #[derive(Debug)] + struct Test { + geoname: Geoname, + expected: GeonameAlternates, + } + + impl Test { + fn new GeonameAlternates>( + geoname: Geoname, + expected: F, + ) -> Self { + Test { + expected: expected(&geoname), + geoname, + } + } + } + + let tests = [ + Test::new(nyc(), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("New York".to_string()), + abbreviation: Some("NY".to_string()), + }, + country: Some(AlternateNames { + primary: "United States".to_string(), + localized: Some("United States".to_string()), + abbreviation: Some("US".to_string()), + }), + admin_divisions: [( + 1, + AlternateNames { + primary: ny_state().name.clone(), + localized: Some("New York".to_string()), + abbreviation: Some("NY".to_string()), + }, + )] + .into(), + }), + Test::new(waterloo_on(), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("Waterloo".to_string()), + abbreviation: None, + }, + country: Some(AlternateNames { + primary: "Canada".to_string(), + // There are no alternates for Canada so `localized` should + // be the primary name + localized: Some("Canada".to_string()), + abbreviation: None, + }), + admin_divisions: [( + 1, + AlternateNames { + primary: on().name.clone(), + localized: Some("Ontario".to_string()), + abbreviation: Some("ON".to_string()), + }, + )] + .into(), + }), + Test::new(liverpool_city(), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("Liverpool".to_string()), + abbreviation: None, + }, + country: Some(AlternateNames { + primary: "United Kingdom of Great Britain and Northern Ireland".to_string(), + localized: Some("United Kingdom".to_string()), + abbreviation: Some("UK".to_string()), + }), + admin_divisions: [ + ( + 1, + AlternateNames { + primary: england().name.clone(), + localized: Some("England".to_string()), + abbreviation: None, + }, + ), + ( + 2, + AlternateNames { + primary: liverpool_metro().name.clone(), + localized: Some("Liverpool".to_string()), + abbreviation: Some("LIV".to_string()), + }, + ), + ] + .into(), + }), + Test::new(punctuation_city(0), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Made Up City w Punct in Alternates".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + Test::new(punctuation_city(1), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Made Up City w Punct in Alternates".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + Test::new(punctuation_city(2), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Made Up City w Punct in Alternates".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + Test::new(punctuation_city(3), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Aaa, Bbb-Ccc. Ddd".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + Test::new(punctuation_city(4), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Aaa, Bbb-Ccc. Ddd".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + Test::new(punctuation_city(5), |g| GeonameAlternates { + geoname: AlternateNames { + primary: g.name.clone(), + localized: Some("123 Aaa, Bbb-Ccc. Ddd".to_string()), + abbreviation: None, + }, + country: None, + admin_divisions: [].into(), + }), + ]; + + store.read(|dao| { + for t in tests { + assert_eq!( + dao.fetch_geoname_alternates(&t.geoname)?, + t.expected, + "geoname={:?}", + t.geoname + ); + } + Ok(()) + })?; + + Ok(()) + } + #[test] fn geonames() -> anyhow::Result<()> { before_each(); @@ -828,7 +1965,6 @@ pub(crate) mod tests { struct Test { query: &'static str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, expected: Vec, } @@ -837,7 +1973,6 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: ia(), @@ -848,7 +1983,6 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: ia(), @@ -859,18 +1993,12 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: false, - geoname_type: None, filter: Some(vec![waterloo_ia(), waterloo_al()]), - expected: vec![GeonameMatch { - geoname: ia(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }], + expected: vec![], }, Test { query: "ia", match_name_prefix: false, - geoname_type: None, filter: Some(vec![waterloo_ia()]), expected: vec![GeonameMatch { geoname: ia(), @@ -881,32 +2009,46 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: false, - geoname_type: None, - filter: Some(vec![waterloo_al()]), - expected: vec![], - }, - Test { - query: "ia", - match_name_prefix: false, - geoname_type: Some(GeonameType::City), - filter: None, - expected: vec![], - }, - Test { - query: "ia", - match_name_prefix: false, - geoname_type: Some(GeonameType::Region), - filter: None, + filter: Some(vec![us()]), expected: vec![GeonameMatch { geoname: ia(), match_type: GeonameMatchType::Abbreviation, prefix: false, }], }, + Test { + query: "ia", + match_name_prefix: false, + filter: Some(vec![waterloo_al()]), + expected: vec![], + }, + Test { + query: "ia", + match_name_prefix: false, + filter: Some(vec![canada()]), + expected: vec![], + }, + Test { + query: "ia", + match_name_prefix: false, + filter: Some(vec![uk()]), + expected: vec![], + }, + Test { + query: "iaxyz", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "iaxyz", + match_name_prefix: true, + filter: None, + expected: vec![], + }, Test { query: "iowa", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: ia(), @@ -917,7 +2059,6 @@ pub(crate) mod tests { Test { query: "al", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: al(), @@ -929,7 +2070,6 @@ pub(crate) mod tests { Test { query: "al", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -947,7 +2087,6 @@ pub(crate) mod tests { Test { query: "waterloo", match_name_prefix: false, - geoname_type: None, filter: Some(vec![ia()]), expected: vec![GeonameMatch { geoname: waterloo_ia(), @@ -958,7 +2097,6 @@ pub(crate) mod tests { Test { query: "waterloo", match_name_prefix: false, - geoname_type: None, filter: Some(vec![al()]), expected: vec![GeonameMatch { geoname: waterloo_al(), @@ -969,18 +2107,20 @@ pub(crate) mod tests { Test { query: "waterloo", match_name_prefix: false, - geoname_type: None, filter: Some(vec![ny_state()]), expected: vec![], }, Test { query: "waterloo", match_name_prefix: false, - geoname_type: None, filter: None, - // Waterloo, IA should be first since it has a larger - // population. + // Matches should be returned by population descending. expected: vec![ + GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }, GeonameMatch { geoname: waterloo_ia(), match_type: GeonameMatchType::Name, @@ -996,9 +2136,13 @@ pub(crate) mod tests { Test { query: "water", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![ + GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: true, + }, GeonameMatch { geoname: waterloo_ia(), match_type: GeonameMatchType::Name, @@ -1014,14 +2158,147 @@ pub(crate) mod tests { Test { query: "water", match_name_prefix: false, - geoname_type: None, + filter: None, + expected: vec![], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![us()]), + expected: vec![ + GeonameMatch { + geoname: waterloo_ia(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: waterloo_al(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![al(), us()]), + expected: vec![GeonameMatch { + geoname: waterloo_al(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![us(), al()]), + expected: vec![GeonameMatch { + geoname: waterloo_al(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![ia(), al()]), + expected: vec![], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![canada()]), + expected: vec![GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![on()]), + expected: vec![GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![on(), canada()]), + expected: vec![GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![canada(), on()]), + expected: vec![GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![al(), canada()]), + expected: vec![], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![on(), us()]), + expected: vec![], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![waterloo_al()]), + expected: vec![GeonameMatch { + geoname: waterloo_al(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "waterloo", + match_name_prefix: false, + filter: Some(vec![uk()]), + expected: vec![], + }, + Test { + query: "waterlooxyz", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "waterlooxyz", + match_name_prefix: true, + filter: None, + expected: vec![], + }, + Test { + query: "waterloo xyz", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "waterloo xyz", + match_name_prefix: true, filter: None, expected: vec![], }, Test { query: "ny", match_name_prefix: false, - geoname_type: None, filter: None, // NYC should be first since cities are ordered before regions. expected: vec![ @@ -1037,28 +2314,9 @@ pub(crate) mod tests { }, ], }, - Test { - query: "ny", - match_name_prefix: true, - geoname_type: None, - filter: None, - expected: vec![ - GeonameMatch { - geoname: nyc(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }, - GeonameMatch { - geoname: ny_state(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }, - ], - }, Test { query: "ny", match_name_prefix: false, - geoname_type: None, filter: Some(vec![nyc()]), expected: vec![ GeonameMatch { @@ -1076,7 +2334,6 @@ pub(crate) mod tests { Test { query: "ny", match_name_prefix: false, - geoname_type: None, filter: Some(vec![ny_state()]), expected: vec![ GeonameMatch { @@ -1092,9 +2349,8 @@ pub(crate) mod tests { ], }, Test { - query: "ny", + query: "nyc", match_name_prefix: false, - geoname_type: Some(GeonameType::City), filter: None, expected: vec![GeonameMatch { geoname: nyc(), @@ -1102,21 +2358,9 @@ pub(crate) mod tests { prefix: false, }], }, - Test { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::Region), - filter: None, - expected: vec![GeonameMatch { - geoname: ny_state(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }], - }, Test { query: "NeW YoRk", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -1134,7 +2378,6 @@ pub(crate) mod tests { Test { query: "NY", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -1152,14 +2395,12 @@ pub(crate) mod tests { Test { query: "new", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "new", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -1177,49 +2418,42 @@ pub(crate) mod tests { Test { query: "new york foo", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "new york foo", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "new foo", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "foo new york", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "foo new york", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "foo new", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![], }, Test { query: "roc", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: rochester(), @@ -1231,7 +2465,6 @@ pub(crate) mod tests { Test { query: "roc", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -1247,9 +2480,8 @@ pub(crate) mod tests { ], }, Test { - query: "long name", + query: "123 long name", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: long_name_city(), @@ -1260,7 +2492,6 @@ pub(crate) mod tests { Test { query: LONG_NAME, match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: long_name_city(), @@ -1268,6 +2499,514 @@ pub(crate) mod tests { prefix: false, }], }, + Test { + query: "ac", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "ac", + match_name_prefix: true, + filter: None, + expected: vec![], + }, + Test { + query: "act", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: waco(), + match_type: GeonameMatchType::AirportCode, + prefix: false, + }], + }, + Test { + query: "act", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: waco(), + match_type: GeonameMatchType::AirportCode, + prefix: false, + }], + }, + Test { + query: "us", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: us(), + match_type: GeonameMatchType::Abbreviation, + prefix: false, + }], + }, + Test { + query: "us", + match_name_prefix: false, + filter: Some(vec![waterloo_ia()]), + expected: vec![GeonameMatch { + geoname: us(), + match_type: GeonameMatchType::Abbreviation, + prefix: false, + }], + }, + Test { + query: "us", + match_name_prefix: false, + filter: Some(vec![ia()]), + expected: vec![GeonameMatch { + geoname: us(), + match_type: GeonameMatchType::Abbreviation, + prefix: false, + }], + }, + Test { + query: "canada", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: canada(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "canada", + match_name_prefix: false, + filter: Some(vec![on()]), + expected: vec![GeonameMatch { + geoname: canada(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "canada", + match_name_prefix: false, + filter: Some(vec![waterloo_on(), on()]), + expected: vec![GeonameMatch { + geoname: canada(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "uk", + match_name_prefix: false, + filter: None, + expected: vec![ + // "UK" is listed as both an 'en' alternate and 'abbr' + // alternate. The abbreviation should be first since 'abbr' + // is ordered before 'en'. + GeonameMatch { + geoname: uk(), + match_type: GeonameMatchType::Abbreviation, + prefix: false, + }, + GeonameMatch { + geoname: uk(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "st. louis", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: st_louis(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "st louis", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: st_louis(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "st.", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: st_louis(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "st. l", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: st_louis(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "st l", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: st_louis(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "st.", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "st l", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "carmel-by-the-sea", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: carmel(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "carmel by the sea", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: carmel(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "carmel-", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: carmel(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "carmel-b", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: carmel(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "carmel b", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: carmel(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "carmel-", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "carmel-b", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "carmel b", + match_name_prefix: false, + filter: None, + expected: vec![], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: None, + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![liverpool_metro()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![england()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![uk()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![liverpool_metro(), england()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![liverpool_metro(), uk()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![england(), uk()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "liverpool", + match_name_prefix: false, + filter: Some(vec![liverpool_metro(), england(), uk()]), + expected: vec![ + GeonameMatch { + geoname: liverpool_city(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + GeonameMatch { + geoname: liverpool_metro(), + match_type: GeonameMatchType::Name, + prefix: false, + }, + ], + }, + Test { + query: "gößnitz", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "gössnitz", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "goßnitz", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "gossnitz", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "goessnitz", + match_name_prefix: false, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: false, + }], + }, + Test { + query: "gö", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "göß", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "gößn", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "gös", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "goß", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "goßn", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "gos", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, + Test { + query: "goss", + match_name_prefix: true, + filter: None, + expected: vec![GeonameMatch { + geoname: goessnitz(), + match_type: GeonameMatchType::Name, + prefix: true, + }], + }, ]; store.read(|dao| { @@ -1280,14 +3019,10 @@ pub(crate) mod tests { Some(gs_refs) }; assert_eq!( - dao.fetch_geonames( - t.query, - t.match_name_prefix, - t.geoname_type.clone(), - filters - )?, + dao.fetch_geonames(t.query, t.match_name_prefix, filters)?, t.expected, - "Test: {:?}", + "query={:?} -- Full test: {:?}", + t.query, t ); } @@ -1301,24 +3036,43 @@ pub(crate) mod tests { fn geonames_metrics() -> anyhow::Result<()> { before_each(); - // Add a couple of records with different metrics. We're just testing - // metrics so the other values don't matter. + // Add a some records: a core geonames record and some alternates + // records. The names in each should contribute to metrics. let mut store = TestStore::new( MockRemoteSettingsClient::default() .with_record(geoname_mock_record( "geonames-0", + json!([ + { + "id": 4096497, + "name": "Waterloo", + "feature_class": "P", + "feature_code": "PPL", + "country": "US", + "admin1": "AL", + "admin2": "077", + "population": 200, + "latitude": "34.91814", + "longitude": "-88.0642", + }, + ]), + )) + .with_record(geoname_alternates_mock_record( + "geonames-alternates-0", json!({ - "max_alternate_name_length": 10, - "max_alternate_name_word_count": 5, - "geonames": [] + "language": "en", + "alternates_by_geoname_id": [ + [4096497, ["a b c d e"]], + ], }), )) - .with_record(geoname_mock_record( - "geonames-1", + .with_record(geoname_alternates_mock_record( + "geonames-alternates-1", json!({ - "max_alternate_name_length": 20, - "max_alternate_name_word_count": 2, - "geonames": [] + "language": "en", + "alternates_by_geoname_id": [ + [1, ["abcdefghik lmnopqrstu"]], + ], }), )), ); @@ -1331,43 +3085,61 @@ pub(crate) mod tests { store.read(|dao| { let cache = dao.geoname_cache(); - assert_eq!(cache.max_name_length, 20); - assert_eq!(cache.max_name_word_count, 5); + assert_eq!(cache.keywords_metrics.max_len, 21); // "abcdefghik lmnopqrstu" + assert_eq!(cache.keywords_metrics.max_word_count, 5); // "a b c d e" Ok(()) })?; - // Delete the first record. The metrics should change. + // Delete the first alternates record. The metrics should change. store .client_mut() - .delete_record(geoname_mock_record("geonames-0", json!({}))); + .delete_record(geoname_mock_record("geonames-alternates-0", json!({}))); store.ingest(SuggestIngestionConstraints { providers: Some(vec![SuggestionProvider::Weather]), ..SuggestIngestionConstraints::all_providers() }); store.read(|dao| { let cache = dao.geoname_cache(); - assert_eq!(cache.max_name_length, 20); - assert_eq!(cache.max_name_word_count, 2); + assert_eq!(cache.keywords_metrics.max_len, 21); // "abcdefghik lmnopqrstu" + assert_eq!(cache.keywords_metrics.max_word_count, 2); // "abcdefghik lmnopqrstu" + Ok(()) + })?; + + // Delete the second alternates record. The metrics should change again. + store + .client_mut() + .delete_record(geoname_mock_record("geonames-alternates-1", json!({}))); + store.ingest(SuggestIngestionConstraints { + providers: Some(vec![SuggestionProvider::Weather]), + ..SuggestIngestionConstraints::all_providers() + }); + store.read(|dao| { + let cache = dao.geoname_cache(); + assert_eq!(cache.keywords_metrics.max_len, 8); // "waterloo" + assert_eq!(cache.keywords_metrics.max_word_count, 1); // "waterloo" Ok(()) })?; // Add a new record. The metrics should change again. - store.client_mut().add_record(geoname_mock_record( - "geonames-3", - json!({ - "max_alternate_name_length": 15, - "max_alternate_name_word_count": 3, - "geonames": [] - }), - )); + store + .client_mut() + .add_record(geoname_alternates_mock_record( + "geonames-alternates-2", + json!({ + "language": "en", + "alternates_by_geoname_id": [ + [2, ["abcd efgh iklm"]], + ], + }), + )); store.ingest(SuggestIngestionConstraints { providers: Some(vec![SuggestionProvider::Weather]), ..SuggestIngestionConstraints::all_providers() }); store.read(|dao| { let cache = dao.geoname_cache(); - assert_eq!(cache.max_name_length, 20); - assert_eq!(cache.max_name_word_count, 3); + assert_eq!(cache.keywords_metrics.max_len, 14); // "abcd efgh iklm" + assert_eq!(cache.keywords_metrics.max_word_count, 3); // "abcd efgh iklm" Ok(()) })?; @@ -1388,8 +3160,13 @@ pub(crate) mod tests { // Make sure we have a match. store.read(|dao| { assert_eq!( - dao.fetch_geonames("waterloo", false, None, None)?, + dao.fetch_geonames("waterloo", false, None)?, vec![ + GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }, GeonameMatch { geoname: waterloo_ia(), match_type: GeonameMatchType::Name, @@ -1417,21 +3194,21 @@ pub(crate) mod tests { // The same query shouldn't match anymore and the tables should be // empty. store.read(|dao| { - assert_eq!(dao.fetch_geonames("waterloo", false, None, None)?, vec![],); + assert_eq!(dao.fetch_geonames("waterloo", false, None)?, vec![],); let g_ids = dao.conn.query_rows_and_then( "SELECT id FROM geonames", [], - |row| -> Result { Ok(row.get("id")?) }, + |row| -> Result { Ok(row.get("id")?) }, )?; - assert_eq!(g_ids, Vec::::new()); + assert_eq!(g_ids, Vec::::new()); let alt_g_ids = dao.conn.query_rows_and_then( "SELECT geoname_id FROM geonames_alternates", [], - |row| -> Result { Ok(row.get("geoname_id")?) }, + |row| -> Result { Ok(row.get("geoname_id")?) }, )?; - assert_eq!(alt_g_ids, Vec::::new()); + assert_eq!(alt_g_ids, Vec::::new()); Ok(()) })?; @@ -1485,8 +3262,13 @@ pub(crate) mod tests { // Make sure we have a match. store.read(|dao| { assert_eq!( - dao.fetch_geonames("waterloo", false, None, None)?, + dao.fetch_geonames("waterloo", false, None)?, vec![ + GeonameMatch { + geoname: waterloo_on(), + match_type: GeonameMatchType::Name, + prefix: false, + }, GeonameMatch { geoname: waterloo_ia(), match_type: GeonameMatchType::Name, @@ -1540,7 +3322,6 @@ pub(crate) mod tests { struct Test { query: &'static str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, expected: Vec, } @@ -1552,7 +3333,6 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: false, - geoname_type: None, filter: None, expected: vec![GeonameMatch { geoname: ia(), @@ -1564,43 +3344,17 @@ pub(crate) mod tests { Test { query: "ia", match_name_prefix: false, - geoname_type: None, - filter: Some(vec![waterloo_ia(), waterloo_al()]), + filter: Some(vec![waterloo_ia()]), expected: vec![GeonameMatch { geoname: ia(), match_type: GeonameMatchType::Abbreviation, prefix: false, }], }, - // geoname type: city - Test { - query: "ia", - match_name_prefix: false, - geoname_type: Some(GeonameType::Region), - filter: None, - expected: vec![GeonameMatch { - geoname: ia(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }], - }, - // geoname type: region - Test { - query: "ny", - match_name_prefix: false, - geoname_type: Some(GeonameType::City), - filter: None, - expected: vec![GeonameMatch { - geoname: nyc(), - match_type: GeonameMatchType::Abbreviation, - prefix: false, - }], - }, // prefix matching Test { query: "ny", match_name_prefix: true, - geoname_type: None, filter: None, expected: vec![ GeonameMatch { @@ -1619,12 +3373,7 @@ pub(crate) mod tests { for t in tests { assert_eq!( - store.fetch_geonames( - t.query, - t.match_name_prefix, - t.geoname_type.clone(), - t.filter.clone() - ), + store.fetch_geonames(t.query, t.match_name_prefix, t.filter.clone()), t.expected, "Test: {:?}", t diff --git a/third_party/rust/suggest/src/lib.rs b/third_party/rust/suggest/src/lib.rs index c421187f28f2..febb8aa15067 100644 --- a/third_party/rust/suggest/src/lib.rs +++ b/third_party/rust/suggest/src/lib.rs @@ -26,7 +26,7 @@ mod yelp; pub use config::{SuggestGlobalConfig, SuggestProviderConfig}; pub use error::{Error, SuggestApiError}; -pub use geoname::{Geoname, GeonameMatch, GeonameType}; +pub use geoname::{Geoname, GeonameMatch}; pub use metrics::{LabeledTimingSample, SuggestIngestionMetrics}; pub use provider::{AmpMatchingStrategy, SuggestionProvider, SuggestionProviderConstraints}; pub use query::{QueryWithMetricsResult, SuggestionQuery}; diff --git a/third_party/rust/suggest/src/provider.rs b/third_party/rust/suggest/src/provider.rs index 3ea579b09aee..b4a33037c3f3 100644 --- a/third_party/rust/suggest/src/provider.rs +++ b/third_party/rust/suggest/src/provider.rs @@ -140,11 +140,18 @@ impl SuggestionProvider { )])), Self::Yelp => Some(HashMap::from([( Collection::Other, - HashSet::from([SuggestRecordType::Icon, SuggestRecordType::Geonames]), + HashSet::from([ + SuggestRecordType::Icon, + SuggestRecordType::Geonames, + SuggestRecordType::GeonamesAlternates, + ]), )])), Self::Weather => Some(HashMap::from([( Collection::Other, - HashSet::from([SuggestRecordType::Geonames]), + HashSet::from([ + SuggestRecordType::Geonames, + SuggestRecordType::GeonamesAlternates, + ]), )])), Self::Fakespot => Some(HashMap::from([( Collection::Fakespot, diff --git a/third_party/rust/suggest/src/rs.rs b/third_party/rust/suggest/src/rs.rs index 6d68c3499ed5..3fe7cb9377ff 100644 --- a/third_party/rust/suggest/src/rs.rs +++ b/third_party/rust/suggest/src/rs.rs @@ -37,7 +37,7 @@ use remote_settings::{ Attachment, RemoteSettingsClient, RemoteSettingsError, RemoteSettingsRecord, RemoteSettingsService, }; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use crate::{error::Error, query::full_keywords_to_fts_content, Result}; @@ -200,8 +200,10 @@ pub(crate) enum SuggestRecord { Fakespot, #[serde(rename = "dynamic-suggestions")] Dynamic(DownloadedDynamicRecord), - #[serde(rename = "geonames")] + #[serde(rename = "geonames-2")] // version 2 Geonames, + #[serde(rename = "geonames-alternates")] + GeonamesAlternates, } impl SuggestRecord { @@ -230,6 +232,7 @@ pub enum SuggestRecordType { Fakespot, Dynamic, Geonames, + GeonamesAlternates, } impl From<&SuggestRecord> for SuggestRecordType { @@ -247,6 +250,7 @@ impl From<&SuggestRecord> for SuggestRecordType { SuggestRecord::Fakespot => Self::Fakespot, SuggestRecord::Dynamic(_) => Self::Dynamic, SuggestRecord::Geonames => Self::Geonames, + SuggestRecord::GeonamesAlternates => Self::GeonamesAlternates, } } } @@ -257,6 +261,12 @@ impl fmt::Display for SuggestRecordType { } } +impl ToSql for SuggestRecordType { + fn to_sql(&self) -> rusqlite::Result> { + Ok(ToSqlOutput::from(self.as_str())) + } +} + impl SuggestRecordType { /// Get all record types to iterate over /// @@ -276,6 +286,7 @@ impl SuggestRecordType { Self::Fakespot, Self::Dynamic, Self::Geonames, + Self::GeonamesAlternates, ] } @@ -292,7 +303,8 @@ impl SuggestRecordType { Self::GlobalConfig => "configuration", Self::Fakespot => "fakespot-suggestions", Self::Dynamic => "dynamic-suggestions", - Self::Geonames => "geonames", + Self::Geonames => "geonames-2", + Self::GeonamesAlternates => "geonames-alternates", } } } @@ -608,15 +620,6 @@ pub(crate) struct DownloadedGlobalConfigInner { pub show_less_frequently_cap: i32, } -pub(crate) fn deserialize_f64_or_default<'de, D>( - deserializer: D, -) -> std::result::Result -where - D: Deserializer<'de>, -{ - String::deserialize(deserializer).map(|s| s.parse().ok().unwrap_or_default()) -} - #[cfg(test)] mod test { use super::*; diff --git a/third_party/rust/suggest/src/schema.rs b/third_party/rust/suggest/src/schema.rs index bc51ca666c5e..d14bb36f9a84 100644 --- a/third_party/rust/suggest/src/schema.rs +++ b/third_party/rust/suggest/src/schema.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::db::Sqlite3Extension; +use crate::{db::Sqlite3Extension, geoname::geonames_collate}; use rusqlite::{Connection, Transaction}; use sql_support::{ open_database::{self, ConnectionInitializer}, @@ -23,7 +23,7 @@ use sql_support::{ /// `clear_database()` by adding their names to `conditional_tables`, unless /// they are cleared via a deletion trigger or there's some other good /// reason not to do so. -pub const VERSION: u32 = 38; +pub const VERSION: u32 = 41; /// The current Suggest database schema. pub const SQL: &str = " @@ -48,17 +48,17 @@ CREATE TABLE keywords( PRIMARY KEY (keyword, suggestion_id) ) WITHOUT ROWID; --- Metrics for the `keywords` table per provider. Not all providers use or --- update it. If you modify an existing provider to use this, you will need to --- populate this table somehow with metrics for the provider's existing --- keywords, for example as part of a schema migration. +-- Keywords metrics per record ID and type. Currently we only record metrics for +-- a small number of record types. CREATE TABLE keywords_metrics( record_id TEXT NOT NULL PRIMARY KEY, - provider INTEGER NOT NULL, - max_length INTEGER NOT NULL, + record_type TEXT NOT NULL, + max_len INTEGER NOT NULL, max_word_count INTEGER NOT NULL ) WITHOUT ROWID; +CREATE INDEX keywords_metrics_record_type ON keywords_metrics(record_type); + -- full keywords are what we display to the user when a (partial) keyword matches CREATE TABLE full_keywords( id INTEGER PRIMARY KEY, @@ -196,28 +196,44 @@ CREATE TABLE geonames( id INTEGER PRIMARY KEY, record_id TEXT NOT NULL, name TEXT NOT NULL, - latitude REAL NOT NULL, - longitude REAL NOT NULL, feature_class TEXT NOT NULL, feature_code TEXT NOT NULL, country_code TEXT NOT NULL, - admin1_code TEXT NOT NULL, - population INTEGER NOT NULL + admin1_code TEXT, + admin2_code TEXT, + admin3_code TEXT, + admin4_code TEXT, + population INTEGER, + latitude TEXT, + longitude TEXT ); -CREATE INDEX geonames_feature_class ON geonames(feature_class); -CREATE INDEX geonames_feature_code ON geonames(feature_code); +-- `language` is a lowercase ISO 639 code: 'en', 'de', 'fr', etc. It can also be +-- a geonames pseudo-language like 'abbr' for abbreviations and 'iata' for +-- airport codes. It will be null for names derived from a geoname's primary +-- name (see `Geoname::name` and `Geoname::ascii_name`). +-- `geoname_id` is not defined as a foreign key because the main geonames +-- records are not guaranteed to be ingested before alternates records. CREATE TABLE geonames_alternates( - name TEXT NOT NULL, + id INTEGER PRIMARY KEY, + record_id TEXT NOT NULL, geoname_id INTEGER NOT NULL, - -- The value of the `iso_language` field for the alternate. This will be - -- null for the alternate we artificially create for the `name` in the - -- corresponding geoname record. - iso_language TEXT, - PRIMARY KEY (name, geoname_id), - FOREIGN KEY(geoname_id) REFERENCES geonames(id) ON DELETE CASCADE -) WITHOUT ROWID; -CREATE INDEX geonames_alternates_geoname_id ON geonames_alternates(geoname_id); + language TEXT, + name TEXT NOT NULL COLLATE geonames_collate, + is_preferred INTEGER, + is_short INTEGER +); + +CREATE INDEX geonames_alternates_geoname_id_language + ON geonames_alternates(geoname_id, language); + +CREATE INDEX geonames_alternates_name + ON geonames_alternates(name); + +CREATE TRIGGER geonames_alternates_delete AFTER DELETE ON geonames BEGIN + DELETE FROM geonames_alternates + WHERE geoname_id = old.id; +END; CREATE TABLE geonames_metrics( record_id TEXT NOT NULL PRIMARY KEY, @@ -255,6 +271,11 @@ impl<'a> SuggestConnectionInitializer<'a> { } Ok(()) } + + fn create_custom_functions(&self, conn: &Connection) -> open_database::Result<()> { + conn.create_collation("geonames_collate", geonames_collate)?; + Ok(()) + } } impl ConnectionInitializer for SuggestConnectionInitializer<'_> { @@ -266,7 +287,7 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> { sql_support::setup_sqlite_defaults(conn)?; conn.execute("PRAGMA foreign_keys = ON", ())?; sql_support::debug_tools::define_debug_functions(conn)?; - + self.create_custom_functions(conn)?; Ok(()) } @@ -276,6 +297,10 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> { } fn upgrade_from(&self, tx: &Transaction<'_>, version: u32) -> open_database::Result<()> { + // Custom functions are per connection. `prepare` usually handles + // creating them but on upgrade it's not called before this method is. + self.create_custom_functions(tx)?; + match version { 1..=15 => { // Treat databases with these older schema versions as corrupt, @@ -662,6 +687,94 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> { )?; Ok(()) } + 38 => { + // This migration makes changes to geonames. + tx.execute_batch( + r#" + DROP INDEX geonames_alternates_geoname_id; + DROP TABLE geonames_alternates; + + DROP INDEX geonames_feature_class; + DROP INDEX geonames_feature_code; + DROP TABLE geonames; + + CREATE TABLE geonames( + id INTEGER PRIMARY KEY, + record_id TEXT NOT NULL, + name TEXT NOT NULL, + feature_class TEXT NOT NULL, + feature_code TEXT NOT NULL, + country_code TEXT NOT NULL, + admin1_code TEXT, + admin2_code TEXT, + admin3_code TEXT, + admin4_code TEXT, + population INTEGER, + latitude TEXT, + longitude TEXT + ); + + CREATE TABLE geonames_alternates( + record_id TEXT NOT NULL, + geoname_id INTEGER NOT NULL, + language TEXT, + name TEXT NOT NULL COLLATE geonames_collate, + PRIMARY KEY(geoname_id, language, name) + ); + CREATE INDEX geonames_alternates_geoname_id ON geonames_alternates(geoname_id); + CREATE INDEX geonames_alternates_name ON geonames_alternates(name); + + CREATE TRIGGER geonames_alternates_delete AFTER DELETE ON geonames BEGIN + DELETE FROM geonames_alternates + WHERE geoname_id = old.id; + END; + "#, + )?; + Ok(()) + } + 39 => { + // This migration makes changes to keywords metrics. + clear_database(tx)?; + tx.execute_batch( + r#" + DROP TABLE keywords_metrics; + CREATE TABLE keywords_metrics( + record_id TEXT NOT NULL PRIMARY KEY, + record_type TEXT NOT NULL, + max_len INTEGER NOT NULL, + max_word_count INTEGER NOT NULL + ) WITHOUT ROWID; + CREATE INDEX keywords_metrics_record_type ON keywords_metrics(record_type); + "#, + )?; + Ok(()) + } + 40 => { + // This migration makes changes to geonames. + clear_database(tx)?; + tx.execute_batch( + r#" + DROP INDEX geonames_alternates_geoname_id; + DROP INDEX geonames_alternates_name; + DROP TABLE geonames_alternates; + + CREATE TABLE geonames_alternates( + id INTEGER PRIMARY KEY, + record_id TEXT NOT NULL, + geoname_id INTEGER NOT NULL, + language TEXT, + name TEXT NOT NULL COLLATE geonames_collate, + is_preferred INTEGER, + is_short INTEGER + ); + CREATE INDEX geonames_alternates_geoname_id_language + ON geonames_alternates(geoname_id, language); + CREATE INDEX geonames_alternates_name + ON geonames_alternates(name); + "#, + )?; + Ok(()) + } _ => Err(open_database::Error::IncompatibleVersion(version)), } } diff --git a/third_party/rust/suggest/src/store.rs b/third_party/rust/suggest/src/store.rs index 0766f96e44ea..024669ba3f9d 100644 --- a/third_party/rust/suggest/src/store.rs +++ b/third_party/rust/suggest/src/store.rs @@ -9,7 +9,7 @@ use std::{ sync::Arc, }; -use error_support::{breadcrumb, handle_error}; +use error_support::{breadcrumb, handle_error, trace}; use once_cell::sync::OnceCell; use parking_lot::Mutex; use remote_settings::{self, RemoteSettingsError, RemoteSettingsServer, RemoteSettingsService}; @@ -20,7 +20,7 @@ use crate::{ config::{SuggestGlobalConfig, SuggestProviderConfig}, db::{ConnectionType, IngestedRecord, Sqlite3Extension, SuggestDao, SuggestDb}, error::Error, - geoname::{Geoname, GeonameMatch, GeonameType}, + geoname::{Geoname, GeonameAlternates, GeonameMatch}, metrics::{MetricsContext, SuggestIngestionMetrics, SuggestQueryMetrics}, provider::{SuggestionProvider, SuggestionProviderConstraints, DEFAULT_INGEST_PROVIDERS}, rs::{ @@ -306,36 +306,26 @@ impl SuggestStore { /// Fetches geonames stored in the database. A geoname represents a /// geographic place. /// - /// `query` is a string that will be matched directly against geoname names. - /// It is not a query string in the usual Suggest sense. `match_name_prefix` - /// determines whether prefix matching is performed on names excluding - /// abbreviations and airport codes. When `true`, names that start with - /// `query` will match. When false, names that equal `query` will match. - /// - /// `geoname_type` restricts returned geonames to a [`GeonameType`]. - /// - /// `filter` restricts returned geonames to certain cities or regions. - /// Cities can be restricted to regions by including the regions in - /// `filter`, and regions can be restricted to those containing certain - /// cities by including the cities in `filter`. This is especially useful - /// since city and region names are not unique. `filter` is disjunctive: If - /// any item in `filter` matches a geoname, the geoname will be filtered in. - /// - /// The query can match a single geoname in more than one way. For example, - /// it can match both a full name and an abbreviation. The returned vec of - /// [`GeonameMatch`] values will include all matches for a geoname, one - /// match per `match_type` per geoname. In other words, a matched geoname - /// can map to more than one `GeonameMatch`. + /// See `fetch_geonames` in `geoname.rs` for documentation. #[handle_error(Error)] pub fn fetch_geonames( &self, query: &str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, ) -> SuggestApiResult> { - self.inner - .fetch_geonames(query, match_name_prefix, geoname_type, filter) + self.inner.fetch_geonames(query, match_name_prefix, filter) + } + + /// Fetches a geoname's names stored in the database. + /// + /// See `fetch_geoname_alternates` in `geoname.rs` for documentation. + #[handle_error(Error)] + pub fn fetch_geoname_alternates( + &self, + geoname: &Geoname, + ) -> SuggestApiResult { + self.inner.fetch_geoname_alternates(geoname) } } @@ -569,18 +559,22 @@ impl SuggestStoreInner { &self, query: &str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, ) -> Result> { self.dbs()?.reader.read(|dao| { dao.fetch_geonames( query, match_name_prefix, - geoname_type, filter.as_ref().map(|f| f.iter().collect()), ) }) } + + pub fn fetch_geoname_alternates(&self, geoname: &Geoname) -> Result { + self.dbs()? + .reader + .read(|dao| dao.fetch_geoname_alternates(geoname)) + } } impl SuggestStoreInner @@ -664,7 +658,7 @@ where context: &mut MetricsContext, ) -> Result<()> { for record in &changes.new { - log::trace!("Ingesting record ID: {}", record.id.as_str()); + trace!("Ingesting record ID: {}", record.id.as_str()); self.process_record(dao, record, constraints, context)?; } for record in &changes.updated { @@ -672,20 +666,20 @@ where // Suggestions in particular don't have a stable identifier, and // determining which suggestions in the record actually changed is // more complicated than dropping and re-ingesting all of them. - log::trace!("Reingesting updated record ID: {}", record.id.as_str()); + trace!("Reingesting updated record ID: {}", record.id.as_str()); dao.delete_record_data(&record.id)?; self.process_record(dao, record, constraints, context)?; } for record in &changes.unchanged { if self.should_reprocess_record(dao, record, constraints)? { - log::trace!("Reingesting unchanged record ID: {}", record.id.as_str()); + trace!("Reingesting unchanged record ID: {}", record.id.as_str()); self.process_record(dao, record, constraints, context)?; } else { - log::trace!("Skipping unchanged record ID: {}", record.id.as_str()); + trace!("Skipping unchanged record ID: {}", record.id.as_str()); } } for record in &changes.deleted { - log::trace!("Deleting record ID: {:?}", record.id); + trace!("Deleting record ID: {:?}", record.id); dao.delete_record_data(&record.id)?; } dao.update_ingested_records( @@ -776,7 +770,10 @@ where )?; } } - SuggestRecord::Geonames => self.process_geoname_record(dao, record, context)?, + SuggestRecord::Geonames => self.process_geonames_record(dao, record, context)?, + SuggestRecord::GeonamesAlternates => { + self.process_geonames_alternates_record(dao, record, context)? + } } Ok(()) } @@ -1062,11 +1059,10 @@ pub(crate) mod tests { &self, query: &str, match_name_prefix: bool, - geoname_type: Option, filter: Option>, ) -> Vec { self.inner - .fetch_geonames(query, match_name_prefix, geoname_type, filter) + .fetch_geonames(query, match_name_prefix, filter) .expect("Error fetching geonames") } } diff --git a/third_party/rust/suggest/src/suggestion.rs b/third_party/rust/suggest/src/suggestion.rs index 28be46d0ea41..2fad295c310d 100644 --- a/third_party/rust/suggest/src/suggestion.rs +++ b/third_party/rust/suggest/src/suggestion.rs @@ -5,7 +5,7 @@ use chrono::Local; -use crate::db::DEFAULT_SUGGESTION_SCORE; +use crate::{db::DEFAULT_SUGGESTION_SCORE, geoname::Geoname}; /// The template parameter for a timestamp in a "raw" sponsored suggestion URL. const TIMESTAMP_TEMPLATE: &str = "%YYYYMMDDHH%"; @@ -86,11 +86,7 @@ pub enum Suggestion { score: f64, }, Weather { - city: Option, - region: Option, - country: Option, - latitude: Option, - longitude: Option, + city: Option, score: f64, }, Fakespot { diff --git a/third_party/rust/suggest/src/testing/mod.rs b/third_party/rust/suggest/src/testing/mod.rs index 50715796838d..6cd2383b1320 100644 --- a/third_party/rust/suggest/src/testing/mod.rs +++ b/third_party/rust/suggest/src/testing/mod.rs @@ -156,8 +156,6 @@ impl Suggestion { pub fn before_each() { static ONCE: Once = Once::new(); ONCE.call_once(|| { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")) - .is_test(true) - .init(); + error_support::init_for_tests_with_level(error_support::Level::Trace); }); } diff --git a/third_party/rust/suggest/src/weather.rs b/third_party/rust/suggest/src/weather.rs index 5d94b68897c0..7c20083ca972 100644 --- a/third_party/rust/suggest/src/weather.rs +++ b/third_party/rust/suggest/src/weather.rs @@ -12,13 +12,13 @@ use std::{cmp::Ordering, collections::HashSet}; use crate::{ config::SuggestProviderConfig, db::{ - KeywordInsertStatement, KeywordMetricsInsertStatement, SuggestDao, + KeywordInsertStatement, KeywordsMetrics, KeywordsMetricsUpdater, SuggestDao, SuggestionInsertStatement, DEFAULT_SUGGESTION_SCORE, }, - geoname::{GeonameMatch, GeonameType}, + geoname::GeonameMatch, metrics::MetricsContext, provider::SuggestionProvider, - rs::{Client, Record, SuggestRecordId}, + rs::{Client, Record, SuggestRecordId, SuggestRecordType}, store::SuggestStoreInner, suggestion::Suggestion, util::filter_map_chunks, @@ -39,14 +39,6 @@ pub(crate) struct DownloadedWeatherAttachment { /// Score for weather suggestions. If there are multiple weather records, we /// use the `score` from the most recently ingested record. pub score: Option, - /// The max length of all keywords in the attachment. Used for keyword - /// metrics. We pre-compute this to avoid doing duplicate work on all user's - /// machines. - pub max_keyword_length: u32, - /// The max word count of all keywords in the attachment. Used for keyword - /// metrics. We pre-compute this to avoid doing duplicate work on all user's - /// machines. - pub max_keyword_word_count: u32, } /// This data is used to service every query handled by the weather provider, so @@ -57,10 +49,8 @@ pub struct WeatherCache { min_keyword_length: i32, /// Cached value of the same name from `SuggestProviderConfig::Weather`. score: f64, - /// Max length of all weather keywords. - max_keyword_length: usize, - /// Max word count across all weather keywords. - max_keyword_word_count: usize, + /// Cached weather keywords metrics. + keywords_metrics: KeywordsMetrics, } impl SuggestDao<'_> { @@ -74,28 +64,42 @@ impl SuggestDao<'_> { // The first step in parsing the query is lowercasing and splitting it // into words. We want to avoid that work for strings that are so long - // they can't possibly match. The longest possible weather query is two - // geonames + one weather keyword + at least two spaces between those - // three components, say, 10 extra characters total for spaces and - // punctuation. There's no point in an analogous min length check since - // weather suggestions can be matched on city alone and many city names - // are only a few characters long ("nyc"). + // they can't possibly match. We'll stipulate that weather queries will + // include the following parts at most: + // + // * 3 geonames max: city + one admin division like a state + country + // * 1 weather keyword + // * 3 spaces between the previous geonames and keyword + // * 10 extra chars to allow for extra spaces and punctuation + // + // This will exclude some valid queries because the logic below allows + // for multiple weather keywords, and a city may have more than one + // admin division, but we don't expect many users to type such long + // queries. + // + // There's no point in an analogous min length check since weather + // suggestions can be matched on city alone and many city names are only + // a few characters long ("nyc"). + let g_cache = self.geoname_cache(); let w_cache = self.weather_cache(); - let max_query_len = 2 * g_cache.max_name_length + w_cache.max_keyword_length + 10; + let max_query_len = + 3 * g_cache.keywords_metrics.max_len + w_cache.keywords_metrics.max_len + 10; if max_query_len < query.keyword.len() { return Ok(vec![]); } - let max_chunk_size = - std::cmp::max(g_cache.max_name_word_count, w_cache.max_keyword_word_count); + let max_chunk_size = std::cmp::max( + g_cache.keywords_metrics.max_word_count, + w_cache.keywords_metrics.max_word_count, + ); // Lowercase, strip punctuation, and split the query into words. let kw_lower = query.keyword.to_lowercase(); let words: Vec<_> = kw_lower .split_whitespace() .flat_map(|w| { - w.split(|c| !char::is_alphabetic(c)) + w.split(|c| !char::is_alphanumeric(c)) .filter(|s| !s.is_empty()) }) .collect(); @@ -103,107 +107,70 @@ impl SuggestDao<'_> { let mut matches = // Step 2: Parse the query words into a list of token paths. filter_map_chunks::(&words, max_chunk_size, |chunk, chunk_i, path| { - // Match the chunk to token types that haven't already been matched - // in this path. `all_tokens` will remain `None` until a token is - // matched. + // Find all token types that match the chunk. let mut all_tokens: Option> = None; for tt in [ - TokenType::City, - TokenType::Region, + TokenType::Geoname, TokenType::WeatherKeyword, ] { - if !path.iter().any(|t| t.token_type() == tt) { - let mut tokens = self.match_weather_tokens(tt, path, chunk, chunk_i == 0)?; - if !tokens.is_empty() { - let mut ts = all_tokens.take().unwrap_or_default(); - ts.append(&mut tokens); - all_tokens.replace(ts); - } + let mut tokens = self.match_weather_tokens(tt, path, chunk, chunk_i == 0)?; + if !tokens.is_empty() { + let mut ts = all_tokens.take().unwrap_or_default(); + ts.append(&mut tokens); + all_tokens.replace(ts); } } // If no tokens were matched, `all_tokens` will be `None`. Ok(all_tokens) })? .into_iter() - // Step 3: Map each token path to a city-region-keyword tuple (each - // optional). Paths are vecs, so they're ordered, so we may end up - // with duplicate tuples after this step. e.g., the paths - // `[, ]` and `[, ]` map to the - // same `(, , None)` tuple. - .map(|path| { - path.into_iter() - .fold((None, None, None), |mut match_tuple, token| { - match token { - Token::City(c) => { - match_tuple.0 = Some(c); - } - Token::Region(r) => { - match_tuple.1 = Some(r); - } - Token::WeatherKeyword(kw) => { - match_tuple.2 = Some(kw); - } - } - match_tuple - }) - }) - // Step 4: Discard tuples that don't have the right combination of - // tokens or that are otherwise invalid. Along with step 2, this is - // the core of the matching logic. In general, allow a tuple if it - // has (a) a city name typed in full or (b) a weather keyword at - // least as long as the config's min keyword length, since that - // indicates a weather intent. - .filter(|(city_match, region_match, kw_match)| { - match (city_match, region_match, kw_match) { - (None, None, Some(_)) => true, - (None, _, None) | (None, Some(_), Some(_)) => false, - (Some(city), region, kw) => { - (city.match_type.is_name() && !city.prefix) - // Allow city abbreviations without a weather - // keyword but only if the region was typed in full. - || (city.match_type.is_abbreviation() - && !city.prefix - && region.as_ref().map(|r| !r.prefix).unwrap_or(false)) - || kw.as_ref().map(|k| k.is_min_keyword_length).unwrap_or(false) - } + // Step 3: Map each token path to a `TokenPath`, which is just a + // convenient representation of the path. + .map(TokenPath::from) + // Step 4: Filter in paths with the right combination of tokens. + // Along with step 2, this is the core of the matching logic. + .filter(|tp| { + if let Some(cm) = &tp.city_match { + // city name typed in full ("new york") + (cm.match_type.is_name() && !cm.prefix) + // city abbreviation typed in full + another related + // geoname typed in full ("ny new york") + || (cm.match_type.is_abbreviation() + && !cm.prefix + && tp.any_other_geoname_typed_in_full) + // any kind of city + weather keyword ("ny weather", + // "weather new y") + || tp.keyword_match + .as_ref() + .map(|kwm| kwm.is_min_keyword_length).unwrap_or(false) + } else { + // weather keyword by itself ("weather") + tp.keyword_match.is_some() && !tp.any_other_geoname_matched } }) - // Step 5: Map each tuple to a city-region tuple: Convert geoname - // matches to their `Geoname` values and discard keywords. - // Discarding keywords is important because we'll collect the tuples - // in a set in the next step in order to dedupe city-regions. - .map(|(city, region, _)| { - (city.map(|c| c.geoname), region.map(|r| r.geoname)) - }) - // Step 6: Dedupe the city-regions by collecting them in a set. + // Step 5: Map each path to its city, an `Option`. Paths + // without cities will end up as `None` values. + .map(|tp| tp.city_match.map(|cm| cm.geoname)) + // Step 6: Dedupe. We'll end up with an `Option` for each + // unique matching city + one `None` value if any keywords by + // themselves were matched. .collect::>() .into_iter() .collect::>(); // Sort the matches so cities with larger populations are first. - matches.sort_by( - |(city1, region1), (city2, region2)| match (&city1, &city2) { - (Some(_), None) => Ordering::Less, - (None, Some(_)) => Ordering::Greater, - (Some(c1), Some(c2)) => c2.population.cmp(&c1.population), - (None, None) => match (®ion1, ®ion2) { - (Some(_), None) => Ordering::Less, - (None, Some(_)) => Ordering::Greater, - (Some(r1), Some(r2)) => r2.population.cmp(&r1.population), - (None, None) => Ordering::Equal, - }, - }, - ); + matches.sort_by(|city1, city2| match (&city1, &city2) { + (Some(_), None) => Ordering::Less, + (None, Some(_)) => Ordering::Greater, + (Some(c1), Some(c2)) => c2.population.cmp(&c1.population), + (None, None) => Ordering::Equal, + }); // Finally, map matches to suggestions. Ok(matches - .iter() - .map(|(city, _)| Suggestion::Weather { - city: city.as_ref().map(|c| c.name.clone()), - region: city.as_ref().map(|c| c.admin1_code.clone()), - country: city.as_ref().map(|c| c.country_code.clone()), - latitude: city.as_ref().map(|c| c.latitude), - longitude: city.as_ref().map(|c| c.longitude), + .into_iter() + .map(|city| Suggestion::Weather { + city, score: w_cache.score, }) .collect()) @@ -217,48 +184,25 @@ impl SuggestDao<'_> { is_first_chunk: bool, ) -> Result> { match token_type { - TokenType::City => { - // Fetch matching cities, and filter them to regions we've + TokenType::Geoname => { + // Fetch matching geonames, and filter them to geonames we've // already matched in this path. - let regions: Vec<_> = path + let geonames_in_path: Vec<_> = path .iter() - .filter_map(|t| t.region().map(|m| &m.geoname)) + .filter_map(|t| t.geoname_match().map(|gm| &gm.geoname)) .collect(); Ok(self .fetch_geonames( candidate, !is_first_chunk, - Some(GeonameType::City), - if regions.is_empty() { + if geonames_in_path.is_empty() { None } else { - Some(regions) + Some(geonames_in_path) }, )? .into_iter() - .map(Token::City) - .collect()) - } - TokenType::Region => { - // Fetch matching regions, and filter them to cities we've - // already matched in this patch. - let cities: Vec<_> = path - .iter() - .filter_map(|t| t.city().map(|m| &m.geoname)) - .collect(); - Ok(self - .fetch_geonames( - candidate, - !is_first_chunk, - Some(GeonameType::Region), - if cities.is_empty() { - None - } else { - Some(cities) - }, - )? - .into_iter() - .map(Token::Region) + .map(Token::Geoname) .collect()) } TokenType::WeatherKeyword => { @@ -328,9 +272,8 @@ impl SuggestDao<'_> { self.scope.err_if_interrupted()?; let mut suggestion_insert = SuggestionInsertStatement::new(self.conn)?; let mut keyword_insert = KeywordInsertStatement::new(self.conn)?; - let mut keyword_metrics_insert = KeywordMetricsInsertStatement::new(self.conn)?; - let mut max_len = 0; - let mut max_word_count = 0; + let mut metrics_updater = KeywordsMetricsUpdater::new(); + for attach in attachments { let suggestion_id = suggestion_insert.execute( record_id, @@ -341,49 +284,29 @@ impl SuggestDao<'_> { )?; for (i, keyword) in attach.keywords.iter().enumerate() { keyword_insert.execute(suggestion_id, keyword, None, i)?; + metrics_updater.update(keyword); } self.put_provider_config(SuggestionProvider::Weather, &attach.into())?; - max_len = std::cmp::max(max_len, attach.max_keyword_length as usize); - max_word_count = std::cmp::max(max_word_count, attach.max_keyword_word_count as usize); } - // Update keyword metrics. - keyword_metrics_insert.execute( + metrics_updater.finish( + self.conn, record_id, - SuggestionProvider::Weather, - max_len, - max_word_count, + SuggestRecordType::Weather, + &mut self.weather_cache, )?; - // We just made some insertions that might invalidate the data in the - // cache. Clear it so it's repopulated the next time it's accessed. - self.weather_cache.take(); - Ok(()) } fn weather_cache(&self) -> &WeatherCache { self.weather_cache.get_or_init(|| { - let mut cache = WeatherCache::default(); - - // keyword metrics - if let Ok((len, word_count)) = self.conn.query_row_and_then( - r#" - SELECT - max(max_length) AS len, max(max_word_count) AS word_count - FROM - keywords_metrics - WHERE - provider = :provider - "#, - named_params! { - ":provider": SuggestionProvider::Weather - }, - |row| -> Result<(usize, usize)> { Ok((row.get("len")?, row.get("word_count")?)) }, - ) { - cache.max_keyword_length = len; - cache.max_keyword_word_count = word_count; - } + let mut cache = WeatherCache { + keywords_metrics: self + .get_keywords_metrics(SuggestRecordType::Weather) + .unwrap_or_default(), + ..WeatherCache::default() + }; // provider config if let Ok(Some(SuggestProviderConfig::Weather { @@ -428,40 +351,24 @@ impl From<&DownloadedWeatherAttachment> for SuggestProviderConfig { #[derive(Clone, Debug, Eq, Hash, PartialEq)] enum TokenType { - City, - Region, + Geoname, WeatherKeyword, } #[derive(Clone, Debug)] +#[allow(clippy::large_enum_variant)] enum Token { - City(GeonameMatch), - Region(GeonameMatch), + Geoname(GeonameMatch), WeatherKeyword(WeatherKeywordMatch), } impl Token { - fn city(&self) -> Option<&GeonameMatch> { + fn geoname_match(&self) -> Option<&GeonameMatch> { match self { - Self::City(g) => Some(g), + Self::Geoname(gm) => Some(gm), _ => None, } } - - fn region(&self) -> Option<&GeonameMatch> { - match self { - Self::Region(g) => Some(g), - _ => None, - } - } - - fn token_type(&self) -> TokenType { - match self { - Self::City(_) => TokenType::City, - Self::Region(_) => TokenType::Region, - Self::WeatherKeyword(_) => TokenType::WeatherKeyword, - } - } } #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] @@ -470,6 +377,38 @@ struct WeatherKeywordMatch { is_min_keyword_length: bool, } +#[derive(Default)] +struct TokenPath { + keyword_match: Option, + city_match: Option, + any_other_geoname_matched: bool, + any_other_geoname_typed_in_full: bool, +} + +impl From> for TokenPath { + fn from(tokens: Vec) -> Self { + let mut tp = Self::default(); + for t in tokens { + match t { + Token::WeatherKeyword(kwm) => { + tp.keyword_match = Some(kwm); + } + Token::Geoname(gm) => { + if gm.geoname.feature_class == "P" { + tp.city_match = Some(gm); + } else { + tp.any_other_geoname_matched = true; + if !gm.prefix { + tp.any_other_geoname_typed_in_full = true; + } + } + } + } + } + tp + } +} + #[cfg(test)] mod tests { use super::*; @@ -480,11 +419,7 @@ mod tests { impl From for Suggestion { fn from(g: Geoname) -> Self { Suggestion::Weather { - city: Some(g.name), - region: Some(g.admin1_code), - country: Some(g.country_code), - latitude: Some(g.latitude), - longitude: Some(g.longitude), + city: Some(g), score: 0.24, } } @@ -499,8 +434,6 @@ mod tests { json!({ "min_keyword_length": 3, "keywords": ["ab", "xyz", "weather"], - "max_keyword_length": "weather".len(), - "max_keyword_word_count": 1, "score": 0.24 }), ), @@ -530,8 +463,6 @@ mod tests { // min_keyword_length > 0 means prefixes are allowed. "min_keyword_length": 5, "keywords": ["ab", "xyz", "cdefg", "weather"], - "max_keyword_length": "weather".len(), - "max_keyword_word_count": 1, "score": 0.24 }), ), @@ -551,13 +482,11 @@ mod tests { "xcdefg", "cdefgx", "x cdefg", - "cdefg x", "weatherx", "xweather", "xweat", "weatx", "x weather", - " weather x", "weather foo", "foo weather", // too short @@ -574,11 +503,15 @@ mod tests { let matches = [ "cdefg", + // full keyword ("cdefg") + prefix of another keyword ("xyz") + "cdefg x", "weath", "weathe", "weather", "WeAtHeR", " weather ", + // full keyword ("weather") + prefix of another keyword ("xyz") + " weather x", ]; for q in matches { assert_eq!( @@ -586,11 +519,7 @@ mod tests { vec![Suggestion::Weather { score: 0.24, city: None, - region: None, - country: None, - latitude: None, - longitude: None, - },] + }] ); } @@ -608,8 +537,6 @@ mod tests { // min_keyword_length == 0 means prefixes are not allowed. "min_keyword_length": 0, "keywords": ["weather"], - "max_keyword_length": "weather".len(), - "max_keyword_word_count": 1, "score": 0.24 }), ), @@ -632,11 +559,7 @@ mod tests { vec![Suggestion::Weather { score: 0.24, city: None, - region: None, - country: None, - latitude: None, - longitude: None, - },] + }] ); } @@ -659,8 +582,6 @@ mod tests { // not two. "keywords": ["ab", "xyz", "weather", "weather near me"], "min_keyword_length": 5, - "max_keyword_length": "weather".len(), - "max_keyword_word_count": 1, "score": 0.24 }), )); @@ -706,8 +627,15 @@ mod tests { ), ( "weather a", - // The made-up long-name city starts with A. - vec![geoname::tests::long_name_city().into()], + vec![ + // A suggestion without a city is returned because the query + // also matches a keyword ("weather") + a prefix of another + // keyword ("ab"). + Suggestion::Weather { + score: 0.24, + city: None, + }, + ], ), ( "weather ac", @@ -912,8 +840,8 @@ mod tests { ( "waterloo", vec![ - // Waterloo, IA should be first since its population is - // larger than Waterloo, AL. + // Matches should be returned by population descending. + geoname::tests::waterloo_on().into(), geoname::tests::waterloo_ia().into(), geoname::tests::waterloo_al().into(), ], @@ -980,7 +908,10 @@ mod tests { "ny ny", vec![geoname::tests::nyc().into()], ), - ("ny ny ny", vec![]), + ( + "ny ny ny", + vec![geoname::tests::nyc().into()], + ), ( "ny n", vec![], @@ -1121,6 +1052,7 @@ mod tests { ( "weather water", vec![ + geoname::tests::waterloo_on().into(), geoname::tests::waterloo_ia().into(), geoname::tests::waterloo_al().into(), ], @@ -1128,21 +1060,95 @@ mod tests { ( "waterloo w", vec![ + geoname::tests::waterloo_on().into(), geoname::tests::waterloo_ia().into(), geoname::tests::waterloo_al().into(), ], ), - ("weather w w", vec![]), - ("weather w water", vec![]), - ("weather w waterloo", vec![]), - ("weather water w", vec![]), - ("weather waterloo water", vec![]), - ("weather water water", vec![]), - ("weather water waterloo", vec![]), + ( + // "w" matches "waco", "waterloo", and "weather" + "weather w w", + vec![ + geoname::tests::waco().into(), + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + Suggestion::Weather { + score: 0.24, + city: None, + }, + ], + ), + ("weather w water", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), + ("weather w waterloo", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), + ("weather water w", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), + ("weather waterloo water", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), + ("weather water water", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), + ("weather water waterloo", vec![ + geoname::tests::waterloo_on().into(), + geoname::tests::waterloo_ia().into(), + geoname::tests::waterloo_al().into(), + ]), ("waterloo foo", vec![]), ("waterloo weather foo", vec![]), ("foo waterloo", vec![]), ("foo waterloo weather", vec![]), + ("weather waterloo foo", vec![]), + ("weather foo waterloo", vec![]), + ("weather water foo", vec![]), + ("weather foo water", vec![]), + ( + "waterloo on", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo ont", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo ont.", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo ontario", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo canada", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo on canada", + vec![geoname::tests::waterloo_on().into()], + ), + ( + "waterloo on us", + vec![], + ), + ( + "waterloo al canada", + vec![], + ), ( "ny", vec![], @@ -1187,13 +1193,38 @@ mod tests { "weather roc", vec![geoname::tests::rochester().into()], ), + ( + "liverpool", + vec![geoname::tests::liverpool_city().into()], + ), + ( + "liverpool eng", + vec![geoname::tests::liverpool_city().into()], + ), + ( + "liverpool england", + vec![geoname::tests::liverpool_city().into()], + ), + ( + "liverpool uk", + vec![geoname::tests::liverpool_city().into()], + ), + ( + "liverpool england uk", + vec![geoname::tests::liverpool_city().into()], + ), ( geoname::tests::LONG_NAME, vec![geoname::tests::long_name_city().into()], ), + ( + " waterloo iowa", + vec![geoname::tests::waterloo_ia().into()], + ), ( " WaTeRlOo ", vec![ + geoname::tests::waterloo_on().into(), geoname::tests::waterloo_ia().into(), geoname::tests::waterloo_al().into(), ], @@ -1487,21 +1518,21 @@ mod tests { .with_record(SuggestionProvider::Weather.record( "weather-0", json!({ - "max_keyword_length": 10, - "max_keyword_word_count": 5, "min_keyword_length": 3, "score": 0.24, - "keywords": [] + "keywords": [ + "a b c d ef" + ], }), )) .with_record(SuggestionProvider::Weather.record( "weather-1", json!({ - "max_keyword_length": 20, - "max_keyword_word_count": 2, "min_keyword_length": 3, "score": 0.24, - "keywords": [] + "keywords": [ + "abcdefghik lmnopqrst" + ], }), )), ); @@ -1513,8 +1544,8 @@ mod tests { store.read(|dao| { let cache = dao.weather_cache(); - assert_eq!(cache.max_keyword_length, 20); - assert_eq!(cache.max_keyword_word_count, 5); + assert_eq!(cache.keywords_metrics.max_len, 20); + assert_eq!(cache.keywords_metrics.max_word_count, 5); Ok(()) })?; @@ -1528,8 +1559,8 @@ mod tests { }); store.read(|dao| { let cache = dao.weather_cache(); - assert_eq!(cache.max_keyword_length, 20); - assert_eq!(cache.max_keyword_word_count, 2); + assert_eq!(cache.keywords_metrics.max_len, 20); + assert_eq!(cache.keywords_metrics.max_word_count, 2); Ok(()) })?; @@ -1539,11 +1570,11 @@ mod tests { .add_record(SuggestionProvider::Weather.record( "weather-3", json!({ - "max_keyword_length": 15, - "max_keyword_word_count": 3, "min_keyword_length": 3, "score": 0.24, - "keywords": [] + "keywords": [ + "abcde fghij klmno" + ] }), )); store.ingest(SuggestIngestionConstraints { @@ -1552,8 +1583,8 @@ mod tests { }); store.read(|dao| { let cache = dao.weather_cache(); - assert_eq!(cache.max_keyword_length, 20); - assert_eq!(cache.max_keyword_word_count, 3); + assert_eq!(cache.keywords_metrics.max_len, 20); + assert_eq!(cache.keywords_metrics.max_word_count, 3); Ok(()) })?; diff --git a/third_party/rust/sync15/.cargo-checksum.json b/third_party/rust/sync15/.cargo-checksum.json index bd1c7825bd88..74145ed8321a 100644 --- a/third_party/rust/sync15/.cargo-checksum.json +++ b/third_party/rust/sync15/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"c8f39fc4260580442b66db092b699c11c8a6398bd38a9354d5c996de5cad4ae7","README.md":"6d4ff5b079ac5340d18fa127f583e7ad793c5a2328b8ecd12c3fc723939804f2","build.rs":"aa971160d67ce8626b26e15c04c34b730f594c45c817aae34cfc9f3ea14ae284","src/bso/content.rs":"92935258745bdf0c3915a555cb6884a7fa69faa1290ec2c1815f6e2f3c0f0562","src/bso/crypto.rs":"27602dcccb37d3a55620ee4e16b705da455d49af575de115c7c79c0178eb1d6d","src/bso/mod.rs":"2da81e81940efe3ad663925a25c03d0ea40584d70e25143dacdba6a1a73e31a9","src/bso/test_utils.rs":"4ec5a2df5e1c0ec14dc770681e959bdcef6ef04f6fde435999197f46a8ae4831","src/client/coll_state.rs":"cad3d1052f7bfe465844bd4125482e3363593f804e583984a1d412b448da1cbf","src/client/coll_update.rs":"dac04a90c29dd969f8b4250414609c9b6d61daf2dfa4ae77d1c4a165ba970b05","src/client/collection_keys.rs":"c27b2277a3a52033b58ab01490fc2ea7007494195dd5e6dc2c6931a4ca96795a","src/client/mod.rs":"8f588d4a035cf79d96f2500f06d5651c1a7c566127c456ffa5429811ddce3fd6","src/client/request.rs":"e878c5b43298b6eb682748474963f9fb8d053b4dc690bbb27107f5fa0ee74e01","src/client/state.rs":"2eaa44fc96e3b4b094380984ce1e2bb11bd2705b061d6cb5be557071aeebd1d5","src/client/status.rs":"f445a8765dac9789444e23b5145148413407bb1d18a15ef56682243997f591bf","src/client/storage_client.rs":"45955046f582db319dcee378f70582a89dfd665ac831456a7243acab7bb0b11b","src/client/sync.rs":"b29abb512ec9d163f7883b71f78c9202802dcb17cad1fc5dc08087fb0bb66704","src/client/sync_multiple.rs":"67a0e6b9049e5b1b1b248febe392b53eb54bb77e9ddddfba62da975389adf3aa","src/client/token.rs":"682863b3eae3aa377397ce052ced7f07d83426072ab311a8851dae9dc8966f68","src/client/util.rs":"71cc70ee41f821f53078675e636e9fad9c6046fa1a989e37f5487e340a2277d6","src/client_types.rs":"3c3cac1540b92482f43660d9e43bdde8481c4cc1a98253a68c80e791231f5976","src/clients_engine/engine.rs":"31c0b6934152f3921af83dadf5d2b22205f49a501427cd736c62f782595cece3","src/clients_engine/mod.rs":"461729e6f89b66b2cbd89b041a03d4d6a8ba582284ed4f3015cb13e1a0c6da97","src/clients_engine/record.rs":"1721e8873da96a019986bbae9df1559c49bf40a16c8cd478904f367652b1e449","src/clients_engine/ser.rs":"be6a19c45eb8002ff8e7cf746d2f97d9cecd1740f9817a8f1d624825475fd777","src/device_type.rs":"dc2d4296d25e31471c8e68488f1043ff239b902036cd6aea8a686cf79b4ed335","src/enc_payload.rs":"aa3eea7df49b24cd59831680a47c417b73a3e36e6b0f3f4baf14ca66bd68be6b","src/engine/bridged_engine.rs":"b4e3071a0259ac55303364e57f9cd685916b80dc302030bba07790e55ceecb66","src/engine/mod.rs":"d0d031d80fbdd90686c443b8c44720ab2ab0aff2c1106e0fdd7d60c46361fe8b","src/engine/request.rs":"5923025fb9550178339f880a1bf8526d8e853e7a0b2bce6d9d687cc808ac0085","src/engine/sync_engine.rs":"531b35d72ce9e04c3e543c0468c1e450fba2c0dc3d33d68d9b1c0a5c1ad7dd34","src/error.rs":"a45cfe02e6301f473c34678b694943c1a04308b8c292c6e0448bf495194c3b5e","src/key_bundle.rs":"abd0781f3be8c8e7c691f18bb71f3433b633803c48da9794e15ac6301ed60d6c","src/lib.rs":"f59f8817978d943518dfa03ab31fc0f6b1fc72ee9943a97aef1537e2769649f5","src/record_types.rs":"02bb3d352fb808131d298f9b90d9c95b7e9e0138b97c5401f3b9fdacc5562f44","src/server_timestamp.rs":"63916817796e83fe31fbd598bac025dfa71ec9e1808d09073db258c78a3331cd","src/sync15.udl":"464047a67a7877bc671f9f3aca13f3039cf34beb51756bcdb86015d789a8f400","src/telemetry.rs":"f332b3849824db6b131a7c2dfe20f56075c6a66ad72f6697bc283d914126b423","uniffi.toml":"d9a5a5cb0eee5218f5eee4d8d89214cc1d7fb5b49323fd17becdf4adb706a6aa"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"a244821aa5f4d338564b745368788a19401f1ce78da0d6cefeac0e16f776f8d4","README.md":"6d4ff5b079ac5340d18fa127f583e7ad793c5a2328b8ecd12c3fc723939804f2","build.rs":"aa971160d67ce8626b26e15c04c34b730f594c45c817aae34cfc9f3ea14ae284","src/bso/content.rs":"c34a689d5d910bc612c5ebfe34db00d5bf6710bfb657d6770e63e62c3cfedbe4","src/bso/crypto.rs":"27602dcccb37d3a55620ee4e16b705da455d49af575de115c7c79c0178eb1d6d","src/bso/mod.rs":"2da81e81940efe3ad663925a25c03d0ea40584d70e25143dacdba6a1a73e31a9","src/bso/test_utils.rs":"4ec5a2df5e1c0ec14dc770681e959bdcef6ef04f6fde435999197f46a8ae4831","src/client/coll_state.rs":"db1b5a3d2a274698218b18e9c7552bf2868b8a860815ac677b91ecc4f3ea8afc","src/client/coll_update.rs":"dac04a90c29dd969f8b4250414609c9b6d61daf2dfa4ae77d1c4a165ba970b05","src/client/collection_keys.rs":"c27b2277a3a52033b58ab01490fc2ea7007494195dd5e6dc2c6931a4ca96795a","src/client/mod.rs":"8f588d4a035cf79d96f2500f06d5651c1a7c566127c456ffa5429811ddce3fd6","src/client/request.rs":"2b5d2c77279d4d922b845020ffa0c6f34f84400fffff772cd4ab3a79f23e45a0","src/client/state.rs":"7efbff1fb0b545d45e2c5b1b4b0f42748eaec91b51fb4c41cbc31cce67903f6c","src/client/status.rs":"f445a8765dac9789444e23b5145148413407bb1d18a15ef56682243997f591bf","src/client/storage_client.rs":"ca74d26cf177a16697627d919add5b7e33f22f5e7357a5c5c546edb6687dd8f8","src/client/sync.rs":"ffcca4a2417ce4a6404363f3c1446def32f1297c14c27750ed69e6c03e23b9c1","src/client/sync_multiple.rs":"6d91cae760d7553f19443df9dc38cbdfb66b996a9a7b3d7a15f4179233c7dff9","src/client/token.rs":"ddfeb461f1be1b775a185c9b0cb372744032cf62ddb30666c672e73f761fab5d","src/client/util.rs":"71cc70ee41f821f53078675e636e9fad9c6046fa1a989e37f5487e340a2277d6","src/client_types.rs":"3c3cac1540b92482f43660d9e43bdde8481c4cc1a98253a68c80e791231f5976","src/clients_engine/engine.rs":"b6556f16eaa83e922686d838fc8ec53498da274445762250c10b69d268f20eda","src/clients_engine/mod.rs":"461729e6f89b66b2cbd89b041a03d4d6a8ba582284ed4f3015cb13e1a0c6da97","src/clients_engine/record.rs":"736870c81dff89a05c0703eef52beda83f45fe9f8d989dfb6e13b88781f1198f","src/clients_engine/ser.rs":"be6a19c45eb8002ff8e7cf746d2f97d9cecd1740f9817a8f1d624825475fd777","src/device_type.rs":"dc2d4296d25e31471c8e68488f1043ff239b902036cd6aea8a686cf79b4ed335","src/enc_payload.rs":"aa3eea7df49b24cd59831680a47c417b73a3e36e6b0f3f4baf14ca66bd68be6b","src/engine/bridged_engine.rs":"00220c64abc42e5c37e87efd6dbfe5c4c48507b9960e9ba722ac93e038ccfd30","src/engine/mod.rs":"d0d031d80fbdd90686c443b8c44720ab2ab0aff2c1106e0fdd7d60c46361fe8b","src/engine/request.rs":"5923025fb9550178339f880a1bf8526d8e853e7a0b2bce6d9d687cc808ac0085","src/engine/sync_engine.rs":"531b35d72ce9e04c3e543c0468c1e450fba2c0dc3d33d68d9b1c0a5c1ad7dd34","src/error.rs":"1a2164a6ee6376feabcc02ff66cc0841aca70e436cce69eb0ea893b020225217","src/key_bundle.rs":"a68b484ec8702a269645e892aa0b3161943388dac6b160e87393617139fad22a","src/lib.rs":"f59f8817978d943518dfa03ab31fc0f6b1fc72ee9943a97aef1537e2769649f5","src/record_types.rs":"02bb3d352fb808131d298f9b90d9c95b7e9e0138b97c5401f3b9fdacc5562f44","src/server_timestamp.rs":"63916817796e83fe31fbd598bac025dfa71ec9e1808d09073db258c78a3331cd","src/sync15.udl":"464047a67a7877bc671f9f3aca13f3039cf34beb51756bcdb86015d789a8f400","src/telemetry.rs":"7261f0241587c8533239b6f19345d5849f6242bab62fe46e9dab5b57614a52db","uniffi.toml":"d9a5a5cb0eee5218f5eee4d8d89214cc1d7fb5b49323fd17becdf4adb706a6aa"},"package":null} \ No newline at end of file diff --git a/third_party/rust/sync15/Cargo.toml b/third_party/rust/sync15/Cargo.toml index 3d732bdbff57..4e7dd8918db4 100644 --- a/third_party/rust/sync15/Cargo.toml +++ b/third_party/rust/sync15/Cargo.toml @@ -51,7 +51,6 @@ path = "src/lib.rs" [dependencies] anyhow = "1.0" lazy_static = "1.4" -log = "0.4" serde_derive = "1" serde_json = "1" serde_path_to_error = "0.1" @@ -98,9 +97,9 @@ optional = true path = "../viaduct" optional = true -[dev-dependencies.env_logger] -version = "0.10" -default-features = false +[dev-dependencies.error-support] +path = "../support/error" +features = ["testing"] [dev-dependencies.nss] path = "../support/rc_crypto/nss" diff --git a/third_party/rust/sync15/src/bso/content.rs b/third_party/rust/sync15/src/bso/content.rs index da5beb528ab8..4f3e09385f39 100644 --- a/third_party/rust/sync15/src/bso/content.rs +++ b/third_party/rust/sync15/src/bso/content.rs @@ -10,6 +10,7 @@ //! * Turn arbitrary objects with an `id` field into an OutgoingBso. use super::{IncomingBso, IncomingContent, IncomingKind, OutgoingBso, OutgoingEnvelope}; +use crate::error::{trace, warn}; use crate::Guid; use error_support::report_error; use serde::Serialize; @@ -65,7 +66,7 @@ impl IncomingBso { } Err(e) => { // payload isn't valid json. - log::warn!("Invalid incoming cleartext {}: {}", self.envelope.id, e); + warn!("Invalid incoming cleartext {}: {}", self.envelope.id, e); IncomingContent { envelope: self.envelope, kind: IncomingKind::Malformed, @@ -140,7 +141,7 @@ where Some(serde_json::Value::String(content_id)) => { // It exists in the payload! We treat a mismatch as malformed. if content_id != id { - log::trace!( + trace!( "malformed incoming record: envelope id: {} payload id: {}", content_id, id @@ -152,7 +153,7 @@ where return IncomingKind::Malformed; } if !id.is_valid_for_sync_server() { - log::trace!("malformed incoming record: id is not valid: {}", id); + trace!("malformed incoming record: id is not valid: {}", id); report_error!( "incoming-invalid-bad-payload-id", "ID in the payload is invalid" @@ -163,14 +164,14 @@ where Some(v) => { // It exists in the payload but is not a string - they can't possibly be // the same as the envelope uses a String, so must be malformed. - log::trace!("malformed incoming record: id is not a string: {}", v); + trace!("malformed incoming record: id is not a string: {}", v); report_error!("incoming-invalid-wrong_type", "ID is not a string"); return IncomingKind::Malformed; } None => { // Doesn't exist in the payload - add it before trying to deser a T. if !id.is_valid_for_sync_server() { - log::trace!("malformed incoming record: id is not valid: {}", id); + trace!("malformed incoming record: id is not valid: {}", id); report_error!( "incoming-invalid-bad-envelope-id", "ID in envelope is not valid" @@ -254,7 +255,7 @@ mod tests { } #[test] fn test_content_deser() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let json = json!({ "id": "test", "payload": json!({"data": 1}).to_string(), @@ -271,7 +272,7 @@ mod tests { #[test] fn test_content_deser_empty_id() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let json = json!({ "id": "", "payload": json!({"data": 1}).to_string(), @@ -286,7 +287,7 @@ mod tests { #[test] fn test_content_deser_invalid() { - env_logger::try_init().ok(); + error_support::init_for_tests(); // And a non-empty but still invalid guid. let json = json!({ "id": "X".repeat(65), @@ -299,7 +300,7 @@ mod tests { #[test] fn test_content_deser_not_string() { - env_logger::try_init().ok(); + error_support::init_for_tests(); // A non-string id. let json = json!({ "id": "0", @@ -312,7 +313,7 @@ mod tests { #[test] fn test_content_ser_with_id() { - env_logger::try_init().ok(); + error_support::init_for_tests(); // When serializing, expect the ID to be in the top-level payload (ie, // in the envelope) but should not appear in the cleartext `payload` part of // the payload. @@ -332,7 +333,7 @@ mod tests { #[test] fn test_content_ser_with_envelope() { - env_logger::try_init().ok(); + error_support::init_for_tests(); // When serializing, expect the ID to be in the top-level payload (ie, // in the envelope) but should not appear in the cleartext `payload` let val = TestStruct { @@ -353,7 +354,7 @@ mod tests { #[test] #[should_panic] fn test_content_ser_no_ids() { - env_logger::try_init().ok(); + error_support::init_for_tests(); #[derive(Serialize)] struct StructWithNoId { data: u32, @@ -365,14 +366,14 @@ mod tests { #[test] #[should_panic] fn test_content_ser_not_object() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let _ = OutgoingBso::from_content_with_id(json!("string")); } #[test] #[should_panic] fn test_content_ser_mismatched_ids() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let val = TestStruct { id: Guid::new("test"), data: 1, @@ -384,7 +385,7 @@ mod tests { #[test] #[should_panic] fn test_content_empty_id() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let val = TestStruct { id: Guid::new(""), data: 1, @@ -395,7 +396,7 @@ mod tests { #[test] #[should_panic] fn test_content_invalid_id() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let val = TestStruct { id: Guid::new(&"X".repeat(65)), data: 1, diff --git a/third_party/rust/sync15/src/client/coll_state.rs b/third_party/rust/sync15/src/client/coll_state.rs index cb5bdefcdebc..d4fba5bd65c6 100644 --- a/third_party/rust/sync15/src/client/coll_state.rs +++ b/third_party/rust/sync15/src/client/coll_state.rs @@ -6,6 +6,7 @@ use super::request::InfoConfiguration; use super::{CollectionKeys, GlobalState}; use crate::engine::{CollSyncIds, EngineSyncAssociation, SyncEngine}; use crate::error; +use crate::error::{info, trace, warn}; use crate::KeyBundle; use crate::ServerTimestamp; @@ -111,7 +112,7 @@ impl<'state> LocalCollStateMachine<'state> { LocalCollState::SyncIdChanged { ids } => { let assoc = EngineSyncAssociation::Connected(ids); - log::info!("Resetting {} engine", engine.collection_name()); + info!("Resetting {} engine", engine.collection_name()); engine.reset(&assoc)?; Ok(LocalCollState::Unknown { assoc }) } @@ -132,14 +133,14 @@ impl<'state> LocalCollStateMachine<'state> { // 10 goes around. let mut count = 0; loop { - log::trace!("LocalCollState in {:?}", s); + trace!("LocalCollState in {:?}", s); match s { LocalCollState::Ready { coll_state } => return Ok(Some(coll_state)), LocalCollState::Declined | LocalCollState::NoSuchCollection => return Ok(None), _ => { count += 1; if count > 10 { - log::warn!("LocalCollStateMachine appears to be looping"); + warn!("LocalCollStateMachine appears to be looping"); return Ok(None); } // should we have better loop detection? Our limit of 10 diff --git a/third_party/rust/sync15/src/client/request.rs b/third_party/rust/sync15/src/client/request.rs index 45b72cce24e6..3c2a21c8ed9c 100644 --- a/third_party/rust/sync15/src/client/request.rs +++ b/third_party/rust/sync15/src/client/request.rs @@ -4,7 +4,7 @@ use super::storage_client::Sync15ClientResponse; use crate::bso::OutgoingEncryptedBso; -use crate::error::{self, Error as ErrorKind, Result}; +use crate::error::{self, debug, info, warn, Error as ErrorKind, Result}; use crate::ServerTimestamp; use serde_derive::*; use std::collections::HashMap; @@ -262,7 +262,7 @@ where || self.batch_limits.can_never_add(payload_length) || payload_length >= self.max_payload_bytes { - log::warn!( + warn!( "Single record too large to submit to server ({} b)", payload_length ); @@ -299,7 +299,7 @@ where if item_len >= self.max_request_bytes { self.queued.truncate(item_start); - log::warn!( + warn!( "Single record too large to submit to server ({} b)", item_len ); @@ -311,11 +311,9 @@ where let can_send_record = self.queued.len() < self.max_request_bytes; if !can_post_record || !can_send_record || !can_batch_record { - log::debug!( + debug!( "PostQueue flushing! (can_post = {}, can_send = {}, can_batch = {})", - can_post_record, - can_send_record, - can_batch_record + can_post_record, can_send_record, can_batch_record ); // "unwrite" the record. self.queued.truncate(item_start); @@ -353,7 +351,7 @@ where BatchState::InBatch(ref s) => Some(s.clone()), }; - log::info!( + info!( "Posting {} records of {} bytes", self.post_limits.cur_records, self.queued.len() @@ -397,7 +395,7 @@ where } if want_commit { - log::debug!("Committed batch {:?}", self.batch); + debug!("Committed batch {:?}", self.batch); self.batch = BatchState::NoBatch; self.on_response.handle_response(resp, false)?; return Ok(()); @@ -426,7 +424,7 @@ where match &self.batch { BatchState::Unsupported => { - log::warn!("Server changed its mind about supporting batching mid-batch..."); + warn!("Server changed its mind about supporting batching mid-batch..."); } BatchState::InBatch(ref cur_id) => { diff --git a/third_party/rust/sync15/src/client/state.rs b/third_party/rust/sync15/src/client/state.rs index 4206dd2ae365..2fd446d52a76 100644 --- a/third_party/rust/sync15/src/client/state.rs +++ b/third_party/rust/sync15/src/client/state.rs @@ -8,7 +8,7 @@ use super::request::{InfoCollections, InfoConfiguration}; use super::storage_client::{SetupStorageClient, Sync15ClientResponse}; use super::CollectionKeys; use crate::bso::OutgoingEncryptedBso; -use crate::error::{self, Error as ErrorKind, ErrorResponse}; +use crate::error::{self, debug, info, trace, warn, Error as ErrorKind, ErrorResponse}; use crate::record_types::{MetaGlobalEngine, MetaGlobalRecord}; use crate::EncryptedPayload; use crate::{Guid, KeyBundle, ServerTimestamp}; @@ -96,7 +96,7 @@ struct EngineStateOutput { fn compute_engine_states(input: EngineStateInput) -> EngineStateOutput { use super::util::*; - log::debug!("compute_engine_states: input {:?}", input); + debug!("compute_engine_states: input {:?}", input); let (must_enable, must_disable) = partition_by_value(&input.user_changes); let have_remote = input.remote.is_some(); let RemoteEngineState { @@ -107,7 +107,7 @@ fn compute_engine_states(input: EngineStateInput) -> EngineStateOutput { let both_declined_and_remote = set_intersection(&info_collections, &remote_declined); if !both_declined_and_remote.is_empty() { // Should we wipe these too? - log::warn!( + warn!( "Remote state contains engines which are in both info/collections and meta/global's declined: {:?}", both_declined_and_remote, ); @@ -137,7 +137,7 @@ fn compute_engine_states(input: EngineStateInput) -> EngineStateOutput { declined: result_declined, }; // No PII here and this helps debug problems. - log::debug!("compute_engine_states: output {:?}", output); + debug!("compute_engine_states: output {:?}", output); output } @@ -208,7 +208,7 @@ fn fixup_meta_global(global: &mut MetaGlobalRecord) -> bool { let should_have_engine = !global.declined.iter().any(|c| c == name); if had_engine != should_have_engine { if should_have_engine { - log::debug!("SyncID for engine {:?} was missing", name); + debug!("SyncID for engine {:?} was missing", name); global.engines.insert( name.to_string(), MetaGlobalEngine { @@ -217,7 +217,7 @@ fn fixup_meta_global(global: &mut MetaGlobalRecord) -> bool { }, ); } else { - log::debug!("SyncID for engine {:?} was present, but shouldn't be", name); + debug!("SyncID for engine {:?} was present, but shouldn't be", name); global.engines.remove(name); } changed_any = true; @@ -353,7 +353,7 @@ impl<'a> SetupStateMachine<'a> { if global.storage_version < STORAGE_VERSION { Ok(FreshStartRequired { config }) } else { - log::info!("Have info/collections and meta/global. Computing new engine states"); + info!("Have info/collections and meta/global. Computing new engine states"); let initial_global_declined: HashSet = global.declined.iter().cloned().collect(); let result = compute_engine_states(EngineStateInput { @@ -370,7 +370,7 @@ impl<'a> SetupStateMachine<'a> { // If the declined engines differ from remote, fix that. let fixed_declined = if result.declined != initial_global_declined { global.declined = result.declined.iter().cloned().collect(); - log::info!( + info!( "Uploading new declined {:?} to meta/global with timestamp {:?}", global.declined, global_timestamp, @@ -381,7 +381,7 @@ impl<'a> SetupStateMachine<'a> { }; // If there are missing syncIds, we need to fix those as well let fixed_ids = if fixup_meta_global(&mut global) { - log::info!( + info!( "Uploading corrected meta/global with timestamp {:?}", global_timestamp, ); @@ -393,14 +393,14 @@ impl<'a> SetupStateMachine<'a> { if fixed_declined || fixed_ids { global_timestamp = self.client.put_meta_global(global_timestamp, &global)?; - log::debug!("new global_timestamp: {:?}", global_timestamp); + debug!("new global_timestamp: {:?}", global_timestamp); } // Update the set of changes needed. if self.changes_needed.is_some() { // Should never happen (we prevent state machine // loops elsewhere) but if it did, the info is stale // anyway. - log::warn!("Already have a set of changes needed, Overwriting..."); + warn!("Already have a set of changes needed, Overwriting..."); } self.changes_needed = Some(result.changes_needed); Ok(InitialWithMetaGlobal { @@ -487,11 +487,11 @@ impl<'a> SetupStateMachine<'a> { FreshStartRequired { config } => { // Wipe the server. - log::info!("Fresh start: wiping remote"); + info!("Fresh start: wiping remote"); self.client.wipe_all_remote()?; // Upload a fresh `meta/global`... - log::info!("Uploading meta/global"); + info!("Uploading meta/global"); let computed = compute_engine_states(EngineStateInput { local_declined: self.pgs.get_declined().iter().cloned().collect(), user_changes: self.engine_updates.cloned().unwrap_or_default(), @@ -531,7 +531,7 @@ impl<'a> SetupStateMachine<'a> { loop { self.interruptee.err_if_interrupted()?; let label = &s.label(); - log::trace!("global state: {:?}", label); + trace!("global state: {:?}", label); match s { Ready { state } => { self.sequence.push(label); @@ -757,7 +757,7 @@ mod tests { #[test] fn test_state_machine_ready_from_empty() { nss::ensure_initialized(); - let _ = env_logger::try_init(); + error_support::init_for_tests(); let root_key = KeyBundle::new_random().unwrap(); let keys = CollectionKeys { timestamp: ServerTimestamp(123_400), @@ -815,7 +815,7 @@ mod tests { #[test] fn test_from_previous_state_declined() { nss::ensure_initialized(); - let _ = env_logger::try_init(); + error_support::init_for_tests(); // The state-machine sequence where we didn't use the previous state // (ie, where the state machine restarted) let sm_seq_restarted = vec![ diff --git a/third_party/rust/sync15/src/client/storage_client.rs b/third_party/rust/sync15/src/client/storage_client.rs index e7f07c2dc0b1..ca38c18876d9 100644 --- a/third_party/rust/sync15/src/client/storage_client.rs +++ b/third_party/rust/sync15/src/client/storage_client.rs @@ -8,7 +8,7 @@ use super::request::{ use super::token; use crate::bso::{IncomingBso, IncomingEncryptedBso, OutgoingBso, OutgoingEncryptedBso}; use crate::engine::{CollectionPost, CollectionRequest}; -use crate::error::{self, Error, ErrorResponse}; +use crate::error::{self, debug, info, trace, warn, Error, ErrorResponse}; use crate::record_types::MetaGlobalRecord; use crate::{CollectionName, Guid, ServerTimestamp}; use serde_json::Value; @@ -37,7 +37,7 @@ fn parse_seconds(seconds_str: &str) -> Option { let secs = seconds_str.parse::().ok()?.ceil(); // Note: u32 doesn't impl TryFrom :( if !secs.is_finite() || secs < 0.0 || secs > f64::from(u32::MAX) { - log::warn!("invalid backoff value: {}", secs); + warn!("invalid backoff value: {}", secs); None } else { Some(secs as u32) @@ -77,10 +77,9 @@ impl Sync15ClientResponse { .get(header_names::X_LAST_MODIFIED) .and_then(|s| ServerTimestamp::from_str(s).ok()) .ok_or(Error::MissingServerTimestamp)?; - log::info!( + info!( "Successful request to \"{}\", incoming x-last-modified={:?}", - route, - last_modified + route, last_modified ); Sync15ClientResponse::Success { @@ -91,7 +90,7 @@ impl Sync15ClientResponse { } } else { let status = resp.status; - log::info!("Request \"{}\" was an error (status={})", route, status); + info!("Request \"{}\" was an error (status={})", route, status); match status { 404 => Sync15ClientResponse::Error(ErrorResponse::NotFound { route }), 401 => Sync15ClientResponse::Error(ErrorResponse::Unauthorized { route }), @@ -110,7 +109,7 @@ impl Sync15ClientResponse { // This should never happen as callers are expected to have // already special-cased this response, so warn if it does. // (or maybe we could panic?) - log::warn!("Converting success response into an error"); + warn!("Converting success response into an error"); ErrorResponse::RequestFailed { status, route } } Sync15ClientResponse::Error(e) => e, @@ -225,10 +224,9 @@ impl SetupStorageClient for Sync15StorageClient { route, status, } => { - log::debug!( + debug!( "Got meta global with modified = {}; last-modified = {}", - record.envelope.modified, - last_modified + record.envelope.modified, last_modified ); Sync15ClientResponse::Success { record: serde_json::from_str(&record.payload)?, @@ -332,7 +330,7 @@ impl Sync15StorageClient { where for<'a> T: serde::de::Deserialize<'a>, { - log::trace!( + trace!( "request: {} {} ({:?})", req.method, req.url.path(), @@ -410,7 +408,7 @@ impl Sync15StorageClient { pub(crate) fn wipe_remote_engine(&self, engine: &str) -> error::Result<()> { let s = self.tsc.api_endpoint()? + "/"; let url = Url::parse(&s)?.join(&format!("storage/{}", engine))?; - log::debug!("Wiping: {:?}", url); + debug!("Wiping: {:?}", url); let req = self.build_request(Method::Delete, url)?; match self.exec_request::(req, false) { Ok(Sync15ClientResponse::Error(ErrorResponse::NotFound { .. })) diff --git a/third_party/rust/sync15/src/client/sync.rs b/third_party/rust/sync15/src/client/sync.rs index b25220032f56..9f07fe43c49a 100644 --- a/third_party/rust/sync15/src/client/sync.rs +++ b/third_party/rust/sync15/src/client/sync.rs @@ -5,7 +5,7 @@ use super::{CollectionUpdate, GlobalState, LocalCollStateMachine, Sync15StorageClient}; use crate::clients_engine; use crate::engine::SyncEngine; -use crate::error::Error; +use crate::error::{info, warn, Error}; use crate::telemetry; use crate::KeyBundle; use interrupt_support::Interruptee; @@ -22,14 +22,14 @@ pub fn synchronize_with_clients_engine( interruptee: &dyn Interruptee, ) -> Result<(), Error> { let collection = engine.collection_name(); - log::info!("Syncing collection {}", collection); + info!("Syncing collection {}", collection); // our global state machine is ready - get the collection machine going. let coll_state = match LocalCollStateMachine::get_state(engine, global_state, root_sync_key)? { Some(coll_state) => coll_state, None => { // XXX - this is either "error" or "declined". - log::warn!( + warn!( "can't setup for the {} collection - hopefully it works later", collection ); @@ -44,7 +44,7 @@ pub fn synchronize_with_clients_engine( // We assume an "engine" manages exactly one "collection" with the engine's name. match engine.get_collection_request(coll_state.last_modified)? { None => { - log::info!("skipping incoming for {} - not needed.", collection); + info!("skipping incoming for {} - not needed.", collection); } Some(collection_request) => { // Ideally we would "batch" incoming records (eg, fetch just 1000 at a time) @@ -64,7 +64,7 @@ pub fn synchronize_with_clients_engine( // For this reason, an engine can't really trust a server timestamp until the // very end when we know we've staged them all. let incoming = super::fetch_incoming(client, &coll_state, collection_request)?; - log::info!("Downloaded {} remote changes", incoming.len()); + info!("Downloaded {} remote changes", incoming.len()); engine.stage_incoming(incoming, telem_engine)?; interruptee.err_if_interrupted()?; } @@ -74,7 +74,7 @@ pub fn synchronize_with_clients_engine( // It *might* even make sense to only call `apply()` when something was staged, // but that's not clear - see the discussion at // https://github.com/mozilla/application-services/pull/5441/files/f36274f455a6299f10e7ce56b167882c369aa806#r1189267540 - log::info!("Applying changes"); + info!("Applying changes"); let outgoing = engine.apply(coll_state.last_modified, telem_engine)?; interruptee.err_if_interrupted()?; @@ -83,7 +83,7 @@ pub fn synchronize_with_clients_engine( // engine about the successful server batch commit. // Most stuff below should be called per-batch rather than at the successful end of all // batches, but that's not trivial. - log::info!("Uploading {} outgoing changes", outgoing.len()); + info!("Uploading {} outgoing changes", outgoing.len()); let upload_info = CollectionUpdate::new_from_changeset( client, &coll_state, @@ -92,7 +92,7 @@ pub fn synchronize_with_clients_engine( fully_atomic, )? .upload()?; - log::info!( + info!( "Upload success ({} records success, {} records failed)", upload_info.successful_ids.len(), upload_info.failed_ids.len() @@ -109,6 +109,6 @@ pub fn synchronize_with_clients_engine( engine.sync_finished()?; - log::info!("Sync finished!"); + info!("Sync finished!"); Ok(()) } diff --git a/third_party/rust/sync15/src/client/sync_multiple.rs b/third_party/rust/sync15/src/client/sync_multiple.rs index 6040c6aa8b65..dbc4ad4351fe 100644 --- a/third_party/rust/sync15/src/client/sync_multiple.rs +++ b/third_party/rust/sync15/src/client/sync_multiple.rs @@ -10,7 +10,7 @@ use super::status::{ServiceStatus, SyncResult}; use super::storage_client::{BackoffListener, Sync15StorageClient, Sync15StorageClientInit}; use crate::clients_engine::{self, CommandProcessor, CLIENTS_TTL_REFRESH}; use crate::engine::{EngineSyncAssociation, SyncEngine}; -use crate::error::Error; +use crate::error::{debug, info, trace, warn, Error}; use crate::telemetry; use crate::KeyBundle; use interrupt_support::Interruptee; @@ -125,7 +125,7 @@ pub fn sync_multiple_with_command_processor( interruptee: &dyn Interruptee, req_info: Option>, ) -> SyncResult { - log::info!("Syncing {} engines", engines.len()); + info!("Syncing {} engines", engines.len()); let mut sync_result = SyncResult { service_status: ServiceStatus::OtherError, result: Ok(()), @@ -152,16 +152,15 @@ pub fn sync_multiple_with_command_processor( }; match driver.sync() { Ok(()) => { - log::debug!( + debug!( "sync was successful, final status={:?}", sync_result.service_status ); } Err(e) => { - log::warn!( + warn!( "sync failed: {}, final status={:?}", - e, - sync_result.service_status, + e, sync_result.service_status, ); sync_result.result = Err(e); } @@ -170,7 +169,7 @@ pub fn sync_multiple_with_command_processor( // ignoring it during the sync sync_result.set_sync_after(backoff.get_required_wait(false).unwrap_or_default()); mem_cached_state.next_sync_after = sync_result.next_sync_after; - log::trace!("Sync result: {:?}", sync_result); + trace!("Sync result: {:?}", sync_result); sync_result } @@ -202,17 +201,17 @@ struct SyncMultipleDriver<'info, 'res, 'pgs, 'mcs> { impl SyncMultipleDriver<'_, '_, '_, '_> { /// The actual worker for sync_multiple. fn sync(mut self) -> result::Result<(), Error> { - log::info!("Loading/initializing persisted state"); + info!("Loading/initializing persisted state"); let mut pgs = self.prepare_persisted_state(); - log::info!("Preparing client info"); + info!("Preparing client info"); let client_info = self.prepare_client_info()?; if self.was_interrupted() { return Ok(()); } - log::info!("Entering sync state machine"); + info!("Entering sync state machine"); // Advance the state machine to the point where it can perform a full // sync. This may involve uploading meta/global, crypto/keys etc. let mut global_state = self.run_state_machine(&client_info, &mut pgs)?; @@ -226,7 +225,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { self.result.service_status = ServiceStatus::Ok; let clients_engine = if let Some(command_processor) = self.command_processor { - log::info!("Synchronizing clients engine"); + info!("Synchronizing clients engine"); let should_refresh = self.mem_cached_state.should_refresh_client(); let mut engine = clients_engine::Engine::new(command_processor, self.interruptee); if let Err(e) = engine.sync( @@ -258,16 +257,16 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { None }; - log::info!("Synchronizing engines"); + info!("Synchronizing engines"); let telem_sync = self.sync_engines(&client_info, &mut global_state, clients_engine.as_ref()); self.result.telemetry.sync(telem_sync); - log::info!("Finished syncing engines."); + info!("Finished syncing engines."); if !self.saw_auth_error { - log::trace!("Updating persisted global state"); + trace!("Updating persisted global state"); self.mem_cached_state.last_client_info = Some(client_info); self.mem_cached_state.last_global_state = Some(global_state); } @@ -277,7 +276,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { fn was_interrupted(&mut self) -> bool { if self.interruptee.was_interrupted() { - log::info!("Interrupted, bailing out"); + info!("Interrupted, bailing out"); self.result.service_status = ServiceStatus::Interrupted; true } else { @@ -299,14 +298,14 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { .get_required_wait(self.ignore_soft_backoff) .is_some() { - log::warn!("Got backoff, bailing out of sync early"); + warn!("Got backoff, bailing out of sync early"); break; } if global_state.global.declined.iter().any(|e| e == &*name) { - log::info!("The {} engine is declined. Skipping", name); + info!("The {} engine is declined. Skipping", name); continue; } - log::info!("Syncing {} engine!", name); + info!("Syncing {} engine!", name); let mut telem_engine = telemetry::Engine::new(&*name); let result = super::sync::synchronize_with_clients_engine( @@ -321,9 +320,9 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { ); match result { - Ok(()) => log::info!("Sync of {} was successful!", name), + Ok(()) => info!("Sync of {} was successful!", name), Err(ref e) => { - log::warn!("Sync of {} failed! {:?}", name, e); + warn!("Sync of {} failed! {:?}", name, e); let this_status = ServiceStatus::from_err(e); // The only error which forces us to discard our state is an // auth error. @@ -364,7 +363,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { self.interruptee, ); - log::info!("Advancing state machine to ready (full)"); + info!("Advancing state machine to ready (full)"); let res = state_machine.run_to_ready(last_state); // Grab this now even though we don't need it until later to avoid a // lifetime issue @@ -376,7 +375,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { // Now that we've gone through the state machine, engine the declined list in // the sync_result self.result.declined = Some(pgs.get_declined().to_vec()); - log::debug!( + debug!( "Declined engines list after state machine set to: {:?}", self.result.declined, ); @@ -406,14 +405,14 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { return Ok(()); } for e in &changes.remote_wipes { - log::info!("Engine {:?} just got disabled locally, wiping server", e); + info!("Engine {:?} just got disabled locally, wiping server", e); client.wipe_remote_engine(e)?; } for s in self.engines { let name = s.collection_name(); if changes.local_resets.contains(&*name) { - log::info!("Resetting engine {}, as it was declined remotely", name); + info!("Resetting engine {}, as it was declined remotely", name); s.reset(&EngineSyncAssociation::Disconnected)?; } } @@ -429,17 +428,17 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { // reuse the client or the memory cached state. We do keep the disk // state as currently that's only the declined list. if client_info.client_init != *self.storage_init { - log::info!("Discarding all state as the account might have changed"); + info!("Discarding all state as the account might have changed"); *self.mem_cached_state = MemoryCachedState::default(); ClientInfo::new(self.storage_init)? } else { - log::debug!("Reusing memory-cached client_info"); + debug!("Reusing memory-cached client_info"); // we can reuse it (which should be the common path) client_info } } None => { - log::debug!("mem_cached_state was stale or missing, need setup"); + debug!("mem_cached_state was stale or missing, need setup"); // We almost certainly have no other state here, but to be safe, we // throw away any memory state we do have. self.mem_cached_state.clear_sensitive_info(); @@ -460,7 +459,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { Some(persisted_string) if !persisted_string.is_empty() => { match serde_json::from_str::(persisted_string) { Ok(state) => { - log::trace!("Read persisted state: {:?}", state); + trace!("Read persisted state: {:?}", state); // Note that we don't set `result.declined` from the // data in state - it remains None, which explicitly // indicates "we don't have updated info". @@ -479,7 +478,7 @@ impl SyncMultipleDriver<'_, '_, '_, '_> { } } _ => { - log::info!( + info!( "The application didn't give us persisted state - \ this is only expected on the very first run for a given user." ); diff --git a/third_party/rust/sync15/src/client/token.rs b/third_party/rust/sync15/src/client/token.rs index edaa5e561a4c..fed19ae271a4 100644 --- a/third_party/rust/sync15/src/client/token.rs +++ b/third_party/rust/sync15/src/client/token.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::error::{self, Error as ErrorKind, Result}; +use crate::error::{self, debug, trace, warn, Error as ErrorKind, Result}; use crate::ServerTimestamp; use rc_crypto::hawk; use serde_derive::*; @@ -99,7 +99,7 @@ impl TokenServerFetcher { impl TokenFetcher for TokenServerFetcher { fn fetch_token(&self) -> Result { - log::debug!("Fetching token from {}", self.server_url); + debug!("Fetching token from {}", self.server_url); let resp = Request::get(self.server_url.clone()) .header( header_names::AUTHORIZATION, @@ -109,9 +109,9 @@ impl TokenFetcher for TokenServerFetcher { .send()?; if !resp.is_success() { - log::warn!("Non-success status when fetching token: {}", resp.status); + warn!("Non-success status when fetching token: {}", resp.status); // TODO: the body should be JSON and contain a status parameter we might need? - log::trace!(" Response body {}", resp.text()); + trace!(" Response body {}", resp.text()); // XXX - shouldn't we "chain" these errors - ie, a BackoffError could // have a TokenserverHttpError as its cause? if let Some(res) = resp.headers.get_as::(header_names::RETRY_AFTER) { @@ -288,10 +288,9 @@ impl TokenProviderImpl { if prev == tc.token.api_endpoint { TokenState::Token(tc) } else { - log::warn!( + warn!( "api_endpoint changed from {} to {}", - prev, - tc.token.api_endpoint + prev, tc.token.api_endpoint ); TokenState::NodeReassigned } @@ -331,7 +330,7 @@ impl TokenProviderImpl { } TokenState::Backoff(ref until, ref existing_endpoint) => { if let Ok(remaining) = until.duration_since(self.fetcher.now()) { - log::debug!("enforcing existing backoff - {:?} remains", remaining); + debug!("enforcing existing backoff - {:?} remains", remaining); None } else { // backoff period is over diff --git a/third_party/rust/sync15/src/clients_engine/engine.rs b/third_party/rust/sync15/src/clients_engine/engine.rs index d2e7b38b9c1a..436afa5b9dc6 100644 --- a/third_party/rust/sync15/src/clients_engine/engine.rs +++ b/third_party/rust/sync15/src/clients_engine/engine.rs @@ -11,7 +11,8 @@ use crate::client::{ }; use crate::client_types::{ClientData, RemoteClient}; use crate::engine::CollectionRequest; -use crate::{error::Result, Guid, KeyBundle}; +use crate::error::{debug, info, warn, Result}; +use crate::{Guid, KeyBundle}; use interrupt_support::Interruptee; use super::{ @@ -67,18 +68,18 @@ impl<'a> Driver<'a> { let client: ClientRecord = match content.kind { IncomingKind::Malformed => { - log::debug!("Error unpacking record"); + debug!("Error unpacking record"); continue; } IncomingKind::Tombstone => { - log::debug!("Record has been deleted; skipping..."); + debug!("Record has been deleted; skipping..."); continue; } IncomingKind::Content(client) => client, }; if client.id == self.command_processor.settings().fxa_device_id { - log::debug!("Found my record on the server"); + debug!("Found my record on the server"); // If we see our own client record, apply any incoming commands, // remove them from the list, and reupload the record. Any // commands that we don't understand also go back in the list. @@ -94,10 +95,10 @@ impl<'a> Driver<'a> { match status { CommandStatus::Applied => {} CommandStatus::Ignored => { - log::debug!("Ignored command {:?}", c); + debug!("Ignored command {:?}", c); } CommandStatus::Unsupported => { - log::warn!("Don't know how to apply command {:?}", c); + warn!("Don't know how to apply command {:?}", c); current_client_record.commands.push(c.clone()); } } @@ -120,7 +121,7 @@ impl<'a> Driver<'a> { // We periodically upload our own client record, even if it // doesn't change, to keep it fresh. if should_refresh_client || client != current_client_record { - log::debug!("Will update our client record on the server"); + debug!("Will update our client record on the server"); let envelope = OutgoingEnvelope { id: content.envelope.id, ttl: Some(CLIENTS_TTL), @@ -276,7 +277,7 @@ impl Engine<'_> { root_sync_key: &KeyBundle, should_refresh_client: bool, ) -> Result<()> { - log::info!("Syncing collection clients"); + info!("Syncing collection clients"); let coll_keys = CollectionKeys::from_encrypted_payload( global_state.keys.clone(), @@ -314,13 +315,13 @@ impl Engine<'_> { )? .upload()?; - log::info!( + info!( "Upload success ({} records success, {} records failed)", upload_info.successful_ids.len(), upload_info.failed_ids.len() ); - log::info!("Finished syncing clients"); + info!("Finished syncing clients"); Ok(()) } diff --git a/third_party/rust/sync15/src/clients_engine/record.rs b/third_party/rust/sync15/src/clients_engine/record.rs index 0ce0be5c52f4..97d9f6577a1b 100644 --- a/third_party/rust/sync15/src/clients_engine/record.rs +++ b/third_party/rust/sync15/src/clients_engine/record.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use crate::error::error; use serde_derive::*; use super::Command; @@ -98,12 +99,12 @@ impl CommandRecord { match &self.args[0] { Some(name) => Some(name.into()), None => { - log::error!("Incoming '{cmd_name}' command has null argument"); + error!("Incoming '{cmd_name}' command has null argument"); None } } } else { - log::error!( + error!( "Incoming '{cmd_name}' command has wrong number of arguments ({})", self.args.len() ); @@ -121,7 +122,7 @@ impl CommandRecord { if self.args.is_empty() { Some(Command::ResetAll) } else { - log::error!("Invalid arguments for 'resetAll' command"); + error!("Invalid arguments for 'resetAll' command"); None } } diff --git a/third_party/rust/sync15/src/engine/bridged_engine.rs b/third_party/rust/sync15/src/engine/bridged_engine.rs index d1166fda3852..e1781eb2ecc0 100644 --- a/third_party/rust/sync15/src/engine/bridged_engine.rs +++ b/third_party/rust/sync15/src/engine/bridged_engine.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use crate::error::debug; use crate::{telemetry, ServerTimestamp}; use anyhow::Result; @@ -144,7 +145,7 @@ impl BridgedEngine for A { let engine = self.engine(); let assoc = engine.get_sync_assoc()?; if matches!(assoc, EngineSyncAssociation::Connected(c) if c.coll == sync_id) { - log::debug!("ensure_current_sync_id is current"); + debug!("ensure_current_sync_id is current"); } else { let new_coll_ids = CollSyncIds { global: Guid::empty(), diff --git a/third_party/rust/sync15/src/error.rs b/third_party/rust/sync15/src/error.rs index e4a043b8ac1f..423314c9c662 100644 --- a/third_party/rust/sync15/src/error.rs +++ b/third_party/rust/sync15/src/error.rs @@ -4,6 +4,10 @@ use interrupt_support::Interrupted; +// reexport logging helpers. +#[allow(unused_imports)] // some only used with certain features. +pub use error_support::{debug, error, info, trace, warn}; + /// This enum is to discriminate `StorageHttpError`, and not used as an error. #[cfg(feature = "sync-client")] #[derive(Debug, Clone)] diff --git a/third_party/rust/sync15/src/key_bundle.rs b/third_party/rust/sync15/src/key_bundle.rs index e330df7ab6c0..2032c2e8f531 100644 --- a/third_party/rust/sync15/src/key_bundle.rs +++ b/third_party/rust/sync15/src/key_bundle.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::error::{Error, Result}; +use crate::error::{warn, Error, Result}; use base64::{ engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}, Engine, @@ -108,7 +108,7 @@ impl KeyBundle { // robust and avoids an allocation. let mut decoded_hmac = vec![0u8; 32]; if base16::decode_slice(hmac_base16, &mut decoded_hmac).is_err() { - log::warn!("Garbage HMAC verification string: contained non base16 characters"); + warn!("Garbage HMAC verification string: contained non base16 characters"); return Err(Error::HmacMismatch); } let iv = STANDARD.decode(iv_base64)?; diff --git a/third_party/rust/sync15/src/telemetry.rs b/third_party/rust/sync15/src/telemetry.rs index 75d80120b416..6b0ab056eb16 100644 --- a/third_party/rust/sync15/src/telemetry.rs +++ b/third_party/rust/sync15/src/telemetry.rs @@ -9,6 +9,7 @@ use crate::error::Error; #[cfg(feature = "sync-client")] use crate::error::ErrorResponse; +use crate::error::warn; use std::collections::HashMap; use std::time; @@ -458,10 +459,9 @@ impl Engine { if self.failure.is_none() { self.failure = Some(failure); } else { - log::warn!( + warn!( "engine already has recorded a failure of {:?} - ignoring {:?}", - &self.failure, - &failure + &self.failure, &failure ); } } @@ -766,7 +766,7 @@ impl SyncTelemetryPing { pub fn uid(&mut self, uid: String) { if let Some(ref existing) = self.uid { if *existing != uid { - log::warn!("existing uid ${} being replaced by {}", existing, uid); + warn!("existing uid ${} being replaced by {}", existing, uid); } } self.uid = Some(uid); diff --git a/third_party/rust/tabs/.cargo-checksum.json b/third_party/rust/tabs/.cargo-checksum.json index 74b4a3c115bc..b716e8a8a145 100644 --- a/third_party/rust/tabs/.cargo-checksum.json +++ b/third_party/rust/tabs/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"ffc7a4b8f8d8df651cdf9de08c1da761554c5bd615c215ba6ebbdd8920b6b04c","README.md":"c48b8f391ef822c4f3971b5f453a1e7b43bea232752d520460d2f04803aead1a","build.rs":"33e61b811b19ed2b58e319cc65d5988bed258d2c4fea2d706301184c59847a0f","src/error.rs":"6e5fd48a3f228d37977881a3657f8635b1b37e3b16d91ac2d8476174172a2a74","src/lib.rs":"2e2a7173ec3bf46065a60c34fbdf91254ff720d9d15955cb87b9019dafca7690","src/schema.rs":"510218d465c7d26d6b9f342cc33c14ab83044a67561ef924c33dadb060761972","src/storage.rs":"e3ee12bbaecb754eced07b2f4bcd034b84161c5dcd6dc5cbe62ebc47a92f44d2","src/store.rs":"30d854aa7ad1ee3a3cac683a1ae0b9fb3833c8d90537beafcd3e4b24f6e7c6e8","src/sync/bridge.rs":"18d3a7913a030b598d4b6cbd5b7e2ab4cef4cc7ea964f5bc84d7fb2f28787529","src/sync/engine.rs":"73007423f2a22314a034ac660aa65bd9c50e8aa850c445a66604486280067843","src/sync/mod.rs":"09ba3c87f1174a243bf5aaa481effd18929d54359ceb9b23ccb2c32ee3482f34","src/sync/record.rs":"eef6751c209d039958afbe245ddb006cfdf6b8b6b47f925f69c552b832b87922","src/tabs.udl":"abb9f81705ee7ac277a1696b224404388a793301f973718322e9aa07538f1bc4","uniffi.toml":"70a41bac1bbbde7a571f1b023f22636337ca3bffd6891dd67596fe13ab98b2f6"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"522f36d0417f7e62fbbff6876eb85eb215d5ee0fb4276785654b72c26b667e71","README.md":"c48b8f391ef822c4f3971b5f453a1e7b43bea232752d520460d2f04803aead1a","build.rs":"33e61b811b19ed2b58e319cc65d5988bed258d2c4fea2d706301184c59847a0f","src/error.rs":"6e5fd48a3f228d37977881a3657f8635b1b37e3b16d91ac2d8476174172a2a74","src/lib.rs":"2e2a7173ec3bf46065a60c34fbdf91254ff720d9d15955cb87b9019dafca7690","src/schema.rs":"698118cabf04cea702dfd2201457afd4238116245438fb50738b5e0a393e3f6c","src/storage.rs":"9edc80923123572482b67ad10e3caab2696840e9e646e1502936f87026a3660e","src/store.rs":"30d854aa7ad1ee3a3cac683a1ae0b9fb3833c8d90537beafcd3e4b24f6e7c6e8","src/sync/bridge.rs":"815d36559e4a061652678a9e798b73de12be05b22495a65e2726a0a4bdca6922","src/sync/engine.rs":"5caa2a9120dec144e8403a9641ad6d357897b1f2c32775271e163f02887281de","src/sync/mod.rs":"09ba3c87f1174a243bf5aaa481effd18929d54359ceb9b23ccb2c32ee3482f34","src/sync/record.rs":"eef6751c209d039958afbe245ddb006cfdf6b8b6b47f925f69c552b832b87922","src/tabs.udl":"abb9f81705ee7ac277a1696b224404388a793301f973718322e9aa07538f1bc4","uniffi.toml":"70a41bac1bbbde7a571f1b023f22636337ca3bffd6891dd67596fe13ab98b2f6"},"package":null} \ No newline at end of file diff --git a/third_party/rust/tabs/Cargo.toml b/third_party/rust/tabs/Cargo.toml index 407207605f12..86daf55e5096 100644 --- a/third_party/rust/tabs/Cargo.toml +++ b/third_party/rust/tabs/Cargo.toml @@ -34,7 +34,6 @@ path = "src/lib.rs" [dependencies] anyhow = "1.0" lazy_static = "1.4" -log = "0.4" serde = "1" serde_derive = "1" serde_json = "1" @@ -77,10 +76,9 @@ version = "0.29.0" [dev-dependencies] tempfile = "3.1" -[dev-dependencies.env_logger] -version = "0.10.0" -features = ["humantime"] -default-features = false +[dev-dependencies.error-support] +path = "../support/error" +features = ["testing"] [build-dependencies.uniffi] version = "0.29.0" diff --git a/third_party/rust/tabs/src/schema.rs b/third_party/rust/tabs/src/schema.rs index 20c5dbdfe3f2..2b4c0af71786 100644 --- a/third_party/rust/tabs/src/schema.rs +++ b/third_party/rust/tabs/src/schema.rs @@ -78,7 +78,7 @@ impl MigrationLogic for TabsMigrationLogic { } fn init(&self, db: &Transaction<'_>) -> MigrationResult<()> { - log::debug!("Creating schemas"); + error_support::debug!("Creating schemas"); init_schema(db)?; Ok(()) } diff --git a/third_party/rust/tabs/src/storage.rs b/third_party/rust/tabs/src/storage.rs index d47934dd4e1c..8518609ddad1 100644 --- a/third_party/rust/tabs/src/storage.rs +++ b/third_party/rust/tabs/src/storage.rs @@ -17,6 +17,7 @@ use crate::schema; use crate::sync::record::TabsRecord; use crate::DeviceType; use crate::{PendingCommand, RemoteCommand, Timestamp}; +use error_support::{error, info, trace, warn}; use rusqlite::{ types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef}, Connection, OpenFlags, @@ -96,7 +97,7 @@ impl TabsStorage { { if let Err(err) = conn.close() { // Log the error, but continue with shutdown - log::error!("Failed to close the connection: {:?}", err); + error!("Failed to close the connection: {:?}", err); } } } @@ -124,7 +125,7 @@ impl TabsStorage { &crate::schema::TabsMigrationLogic, ) { Ok(conn) => { - log::info!("tabs storage is opening an existing database"); + info!("tabs storage is opening an existing database"); self.db_connection = DbConnection::Open(conn); match self.db_connection { DbConnection::Open(ref conn) => Ok(Some(conn)), @@ -134,7 +135,7 @@ impl TabsStorage { Err(open_database::Error::SqlError(rusqlite::Error::SqliteFailure(code, _))) if code.code == rusqlite::ErrorCode::CannotOpen => { - log::info!("tabs storage could not open an existing database and hasn't been asked to create one"); + info!("tabs storage could not open an existing database and hasn't been asked to create one"); Ok(None) } Err(e) => Err(e.into()), @@ -157,7 +158,7 @@ impl TabsStorage { flags, &crate::schema::TabsMigrationLogic, )?; - log::info!("tabs storage is creating a database connection"); + info!("tabs storage is creating a database connection"); self.db_connection = DbConnection::Open(conn); match self.db_connection { DbConnection::Open(ref conn) => Ok(conn), @@ -168,7 +169,7 @@ impl TabsStorage { pub fn update_local_state(&mut self, local_state: Vec) { let num_tabs = local_state.len(); self.local_tabs.borrow_mut().replace(local_state); - log::info!("update_local_state has {num_tabs} tab entries"); + info!("update_local_state has {num_tabs} tab entries"); } // We try our best to fit as many tabs in a payload as possible, this includes @@ -202,7 +203,7 @@ impl TabsStorage { // Sort the tabs so when we trim tabs it's the oldest tabs sanitized_tabs.sort_by(|a, b| b.last_used.cmp(&a.last_used)); trim_tabs_length(&mut sanitized_tabs, MAX_PAYLOAD_SIZE); - log::info!( + info!( "prepare_local_tabs_for_upload found {} tabs", sanitized_tabs.len() ); @@ -210,7 +211,7 @@ impl TabsStorage { } // It's a less than ideal outcome if at startup (or any time) we are asked to // sync tabs before the app has told us what the tabs are, so make noise. - log::warn!("prepare_local_tabs_for_upload - have no local tabs"); + warn!("prepare_local_tabs_for_upload - have no local tabs"); None } @@ -279,7 +280,7 @@ impl TabsStorage { // so we really should consider just dropping it? (Sadly though, it does seem // possible it's actually a very recently connected client, so we keep it) // We should get rid of this eventually - https://github.com/mozilla/application-services/issues/5199 - log::info!( + info!( "Storing tabs from a client that doesn't appear in the devices list: {}", id, ); @@ -375,7 +376,7 @@ impl TabsStorage { ":ttl": client_ttl_ms, }, )?; - log::info!( + info!( "removed {} stale clients (threshold was {})", num_removed, last_sync - client_ttl_ms @@ -401,7 +402,7 @@ impl TabsStorage { for remote_tab in new_remote_tabs { let record = &remote_tab.0; let last_modified = remote_tab.1; - log::info!( + info!( "inserting tab for device {}, last modified at {}", record.id, last_modified.as_millis() @@ -484,8 +485,8 @@ impl TabsStorage { ) -> Result { let connection = self.open_or_create()?; let RemoteCommand::CloseTab { url } = command; - log::info!("Adding remote command for {device_id} at {time_requested}"); - log::trace!("command is {command:?}"); + info!("Adding remote command for {device_id} at {time_requested}"); + trace!("command is {command:?}"); // tx maybe not needed for single write? let tx = connection.unchecked_transaction()?; let changes = tx.execute_cached( @@ -510,7 +511,7 @@ impl TabsStorage { ) -> Result { let connection = self.open_or_create()?; let RemoteCommand::CloseTab { url } = command; - log::info!("removing remote tab close details: client={device_id}"); + info!("removing remote tab close details: client={device_id}"); let tx = connection.unchecked_transaction()?; let changes = tx.execute_cached( "DELETE FROM remote_tab_commands @@ -547,9 +548,7 @@ impl TabsStorage { let command = match row.get::<_, CommandKind>(1) { Ok(c) => c, Err(e) => { - log::error!( - "do_get_pending_commands: ignoring error fetching command: {e:?}" - ); + error!("do_get_pending_commands: ignoring error fetching command: {e:?}"); return Ok(None); } }; @@ -577,8 +576,8 @@ impl TabsStorage { pub fn set_pending_command_sent(&mut self, command: &PendingCommand) -> Result { let connection = self.open_or_create()?; let RemoteCommand::CloseTab { url } = &command.command; - log::info!("setting remote tab sent: client={}", command.device_id); - log::trace!("command: {command:?}"); + info!("setting remote tab sent: client={}", command.device_id); + trace!("command: {command:?}"); let tx = connection.unchecked_transaction()?; let ts = Timestamp::now(); let changes = tx.execute_cached( @@ -657,7 +656,7 @@ impl TabsStorage { }, )?; - log::info!( + info!( "deleted {} pending tab closures because they were not in the new tabs", conn.changes() ); @@ -671,7 +670,7 @@ impl TabsStorage { ) AND (SELECT last_modified FROM tabs WHERE guid = device_id) - time_requested >= {REMOTE_COMMAND_TTL_MS} "); tx.execute_cached(&sql, [])?; - log::info!("deleted {} records because they timed out", conn.changes()); + info!("deleted {} records because they timed out", conn.changes()); // Commit changes and clean up temp tx.commit()?; @@ -780,7 +779,7 @@ mod tests { #[test] fn test_open_if_exists_no_file() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let dir = tempfile::tempdir().unwrap(); let db_name = dir.path().join("test_open_for_read_no_file.db"); let mut storage = TabsStorage::new(db_name.clone()); @@ -794,7 +793,7 @@ mod tests { #[test] fn test_tabs_meta() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let dir = tempfile::tempdir().unwrap(); let db_name = dir.path().join("test_tabs_meta.db"); let mut db = TabsStorage::new(db_name); @@ -829,7 +828,7 @@ mod tests { #[test] fn test_prepare_local_tabs_for_upload() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_prepare_local_tabs_for_upload"); assert_eq!(storage.prepare_local_tabs_for_upload(), None); storage.update_local_state(vec![ @@ -888,7 +887,7 @@ mod tests { } #[test] fn test_trimming_tab_title() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_prepare_local_tabs_for_upload"); assert_eq!(storage.prepare_local_tabs_for_upload(), None); storage.update_local_state(vec![RemoteTab { @@ -913,7 +912,7 @@ mod tests { } #[test] fn test_utf8_safe_title_trim() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_prepare_local_tabs_for_upload"); assert_eq!(storage.prepare_local_tabs_for_upload(), None); storage.update_local_state(vec![ @@ -957,7 +956,7 @@ mod tests { } #[test] fn test_trim_tabs_length() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_prepare_local_tabs_for_upload"); assert_eq!(storage.prepare_local_tabs_for_upload(), None); let mut too_many_tabs: Vec = Vec::new(); @@ -986,7 +985,7 @@ mod tests { } #[test] fn test_remove_stale_clients() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let dir = tempfile::tempdir().unwrap(); let db_name = dir.path().join("test_remove_stale_clients.db"); let mut storage = TabsStorage::new(db_name); @@ -1063,7 +1062,7 @@ mod tests { #[test] fn test_add_pending_dupe_simple() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_add_pending_dupe_simple"); let command = RemoteCommand::close_tab("https://example1.com"); // returns a bool to say if it's new or not. @@ -1083,7 +1082,7 @@ mod tests { #[test] fn test_add_pending_remote_close() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_add_pending_remote_close"); storage.open_or_create().unwrap(); assert!(storage.open_if_exists().unwrap().is_some()); @@ -1139,7 +1138,7 @@ mod tests { #[test] fn test_remote_tabs_filters_pending_closures() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_remote_tabs_filters_pending_closures"); let records = vec![ @@ -1251,7 +1250,7 @@ mod tests { #[test] fn test_remove_old_pending_closures_timed_removal() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_remove_old_pending_closures_timed_removal"); @@ -1337,7 +1336,7 @@ mod tests { } #[test] fn test_remove_old_pending_closures_no_tab_removal() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_remove_old_pending_closures_no_tab_removal"); let db = storage.open_if_exists().unwrap().unwrap(); @@ -1423,7 +1422,7 @@ mod tests { #[test] fn test_remove_pending_command() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_remove_pending_command"); storage.open_or_create().unwrap(); assert!(storage.open_if_exists().unwrap().is_some()); @@ -1463,7 +1462,7 @@ mod tests { #[test] fn test_sent_command() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_sent_command"); let command = RemoteCommand::close_tab("https://example1.com"); storage @@ -1496,7 +1495,7 @@ mod tests { #[test] fn test_remove_pending_closures_only_affects_target_device() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let mut storage = TabsStorage::new_with_mem_path("test_remove_pending_closures_target_device"); let now = Timestamp::now(); diff --git a/third_party/rust/tabs/src/sync/bridge.rs b/third_party/rust/tabs/src/sync/bridge.rs index e43136f4cfbf..9c4cda6a23c6 100644 --- a/third_party/rust/tabs/src/sync/bridge.rs +++ b/third_party/rust/tabs/src/sync/bridge.rs @@ -140,7 +140,7 @@ mod tests { // A copy of the normal "engine" tests but which go via the bridge #[test] fn test_sync_via_bridge() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let store = Arc::new(TabsStore::new_with_mem_path("test-bridge_incoming")); @@ -282,7 +282,7 @@ mod tests { #[test] fn test_sync_meta() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let store = Arc::new(TabsStore::new_with_mem_path("test-meta")); let bridge = store.bridged_engine(); diff --git a/third_party/rust/tabs/src/sync/engine.rs b/third_party/rust/tabs/src/sync/engine.rs index 768f26af88f3..52a7568c9aa6 100644 --- a/third_party/rust/tabs/src/sync/engine.rs +++ b/third_party/rust/tabs/src/sync/engine.rs @@ -7,6 +7,8 @@ use crate::storage::{ClientRemoteTabs, RemoteTab, TABS_CLIENT_TTL}; use crate::store::TabsStore; use crate::sync::record::{TabsRecord, TabsRecordTab}; use anyhow::Result; +use error_support::{debug, info, trace, warn}; + use std::collections::HashMap; use std::sync::{Arc, Mutex, RwLock, Weak}; use sync15::bso::{IncomingBso, OutgoingBso, OutgoingEnvelope}; @@ -124,7 +126,7 @@ impl TabsEngine { pub fn set_last_sync(&self, last_sync: ServerTimestamp) -> Result<()> { let mut storage = self.store.storage.lock().unwrap(); - log::debug!("Updating last sync to {}", last_sync); + debug!("Updating last sync to {}", last_sync); let last_sync_millis = last_sync.as_millis(); Ok(storage.put_meta(schema::LAST_SYNC_META_KEY, &last_sync_millis)?) } @@ -175,7 +177,7 @@ impl SyncEngine for TabsEngine { Some(record) => record, None => { // Invalid record or a "tombstone" which tabs don't have. - log::warn!("Ignoring incoming invalid tab"); + warn!("Ignoring incoming invalid tab"); incoming_telemetry.failed(1); continue; } @@ -231,7 +233,7 @@ impl SyncEngine for TabsEngine { last_modified: 0, // ignored for outgoing records. remote_tabs: local_tabs.to_vec(), }; - log::trace!("outgoing {:?}", local_record); + trace!("outgoing {:?}", local_record); let envelope = OutgoingEnvelope { id: local_id.as_str().into(), ttl: Some(TABS_CLIENT_TTL), @@ -248,7 +250,7 @@ impl SyncEngine for TabsEngine { } fn set_uploaded(&self, new_timestamp: ServerTimestamp, ids: Vec) -> Result<()> { - log::info!("sync uploaded {} records", ids.len()); + info!("sync uploaded {} records", ids.len()); self.set_last_sync(new_timestamp)?; Ok(()) } @@ -330,7 +332,7 @@ pub mod test { #[test] fn test_incoming_tabs() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let engine = TabsEngine::new(Arc::new(TabsStore::new_with_mem_path("test-incoming"))); @@ -413,7 +415,7 @@ pub mod test { #[test] fn test_no_incoming_doesnt_write() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let engine = TabsEngine::new(Arc::new(TabsStore::new_with_mem_path( "test_no_incoming_doesnt_write", @@ -487,7 +489,7 @@ pub mod test { #[test] fn test_apply_timestamp() { - env_logger::try_init().ok(); + error_support::init_for_tests(); let engine = TabsEngine::new(Arc::new(TabsStore::new_with_mem_path( "test-apply-timestamp", diff --git a/third_party/rust/tinyvec/.cargo-checksum.json b/third_party/rust/tinyvec/.cargo-checksum.json new file mode 100644 index 000000000000..a5a48395be22 --- /dev/null +++ b/third_party/rust/tinyvec/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"73712444deeadd5183a00d1bbf56b4fcd6396db0872020895f854631b6c6c309","Cargo.lock":"87e2a8a777227ec1bb50603f8bfbcc176c5a04dc6659d41b72e58cd56b843834","Cargo.toml":"d8ab8a7e7531a4ff6581880f1ab17beb32e2fb9c25772e68353da1c0cced01a5","LICENSE-APACHE.md":"3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","LICENSE-MIT.md":"4736b5d379253afa45744afc79ddb475912b213e939bdf7cb97d9a8b6f700e5f","LICENSE-ZLIB.md":"682b4c81b85e83ce6cc6e1ace38fdd97aeb4de0e972bd2b44aa0916c54af8c96","README.md":"0d8e58e1e52ebafe3f9a4a580d1b1f795c06b79aedad1197387205ef1590a173","benches/macros.rs":"b92679a63e1d39fd949c061fa97dfba933f3e1a6e6722e710cfe4fbfd6315ba9","benches/smallvec.rs":"3b86c05238638d9a894eaecd5a4e9875e2d1b3580cd880869f32a9c0ddab5576","debug_metadata/README.md":"ad8c829e14e40bf784808e7885009b1c016e94f0d578955df86efd245ce90d5e","debug_metadata/tinyvec.natvis":"bbddce08aacef999928071124cc0a8da7c66da4d45e1e79c69f5b617e704cce7","rustfmt.toml":"8a55552a7ab9bcd89add7014f0aeb9f80b491ddacc5f67f6988940f5d46c82b0","src/array.rs":"ab9e9abca8a76b1bec9e55f83f64c9db54980780a2dc88c13868f450caef5d0e","src/array/const_generic_impl.rs":"d0f8ae529b5c9f92da0aa67d5ae24a6e7fc3287ce6d3e576794455de44502a4c","src/array/generated_impl.rs":"8c94c274aae0909b7de75beff4215af8dfc8635cce0c09d75eb57e577c3cca68","src/array/generic_array_impl.rs":"cd8fd8f940e07badd47ab1d80b38e112f5ec09c559155e8857b6d95a85a06ead","src/arrayvec.rs":"bb3d6db2ea7bb362a379d169cc4423679f4a860a1c0744940b4ff653a9d8a372","src/arrayvec_drain.rs":"384738b646a766021886f7ccc32e7f42d5283c10b38b8c438ab049ca1139b0b8","src/lib.rs":"eef8d98214da0f56c1251411dd518e83abb72bb7dee6af5a71b5ab365afdaf68","src/slicevec.rs":"66b8fac4d3856378e3ad81ea9f97440a785f3659c923182435b80e8a7b0b9cbb","src/tinyvec.rs":"ad58bd2e1cdad8616fa96ebf84150c6fd3b3062f93c446347bde7e51ee4d18f0","tests/arrayvec.rs":"873c6a179ccc07ebd424028896483cd6661baac563447ff84cbf97cb100b60d5","tests/debugger_visualizer.rs":"27ffba7de85967678c9483c6e77a35c895c0cb8f594d188ccab34116d518af32","tests/tinyvec.rs":"4bdbe191ebe71c565d0b8cdf4177240016e1caf58b56f0ff5e5777a0028d09ef"},"package":"09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71"} \ No newline at end of file diff --git a/third_party/rust/tinyvec/CHANGELOG.md b/third_party/rust/tinyvec/CHANGELOG.md new file mode 100644 index 000000000000..f86a8b1567e8 --- /dev/null +++ b/third_party/rust/tinyvec/CHANGELOG.md @@ -0,0 +1,104 @@ +# Changelog + +## 1.9 + +* Adds a `latest_stable_rust` cargo feature, which will automatically pull in + other cargo features related to the latest Stable version of rust. +* Adds `ArrayVec::try_from_array_len` +* Adds `TinyVec::into_vec` and `TinyVec::into_boxed_slice` +* Adds support for `generic-array` crate +* Adds support for the `borsh` crate + +## 1.8.1 + +* [e00E](https://github.com/e00E) updated the rustc features so that they all + correctly depend on the lower version feature. + [pr 199](https://github.com/Lokathor/tinyvec/pull/199) + +## 1.8 + +* [Fuuzetsu](https://github.com/Fuuzetsu) added the `ArrayVec::as_inner` method. + [pr 197](https://github.com/Lokathor/tinyvec/pull/197) + +## 1.7 + +* [Fuuzetsu](https://github.com/Fuuzetsu) added the `rustc_1_61` cargo feature, which adds the `retain_mut` method. + [pr 198](https://github.com/Lokathor/tinyvec/pull/198) + +## 1.6.1 + +* [e00E](https://github.com/e00E) fixed the Arbitrary impl to work on Stable + without using a feature gate. + [pr 180](https://github.com/Lokathor/tinyvec/pull/180) + +## 1.6.0 + +* [i509VCB](https://github.com/i509VCB) added the `try_` functions for fallable reallocation. + [pr 158](https://github.com/Lokathor/tinyvec/pull/158) +* [ajtribick](https://github.com/ajtribick) added more error impls to `TryFromSliceError`. + [pr 160](https://github.com/Lokathor/tinyvec/pull/160) +* The `std` feature now automatically enables the `alloc` feature as well. + +## 1.5.1 + +* [madsmtm](https://github.com/madsmtm) fixed an error with the `alloc` feature on very old rustc versions. + [pr 154](https://github.com/Lokathor/tinyvec/pull/154) + +## 1.5.0 + +* [eeeebbbbrrrr](https://github.com/eeeebbbbrrrr) added an impl for [std::io::Write](https://doc.rust-lang.org/std/io/trait.Write.html) to `TinyVec` when the element type is `u8`. + This is gated behind the new `std` feature. + [pr 152](https://github.com/Lokathor/tinyvec/pull/152) + +## 1.4.0 + +* [saethlin](https://github.com/saethlin) stabilized the usage of const generics and array map with the `rustc_1_55` feature. + [pr 149](https://github.com/Lokathor/tinyvec/pull/149) + +## 1.3.1 + +* Improved the performance of the `clone_from` method [pr 144](https://github.com/Lokathor/tinyvec/pull/144) + +## 1.3.0 + +* [jeffa5](https://github.com/jeffa5) added arbitrary implementations for `TinyVec` and `ArrayVec` [pr 146](https://github.com/Lokathor/tinyvec/pull/146). +* [elomatreb](https://github.com/elomatreb) implemented `DoubleEndedIterator` for `TinyVecIterator` [pr 145](https://github.com/Lokathor/tinyvec/pull/145). + +## 1.2.0 + +* [Cryptjar](https://github.com/Cryptjar) removed the `A:Array` bound on the struct of `ArrayVec`, + and added the `from_array_empty` method, which is a `const fn` constructor + [pr 141](https://github.com/Lokathor/tinyvec/pull/141). + +## 1.1.1 + +* [saethlin](https://github.com/saethlin) contributed many PRs ( + [127](https://github.com/Lokathor/tinyvec/pull/127), + [128](https://github.com/Lokathor/tinyvec/pull/128), + [129](https://github.com/Lokathor/tinyvec/pull/129), + [131](https://github.com/Lokathor/tinyvec/pull/131), + [132](https://github.com/Lokathor/tinyvec/pull/132) + ) to help in several benchmarks. + +## 1.1.0 + +* [slightlyoutofphase](https://github.com/slightlyoutofphase) + added "array splat" style syntax to the `array_vec!` and `tiny_vec!` macros. + You can now write `array_vec![true; 5]` and get a length 5 array vec full of `true`, + just like normal array initialization allows. Same goes for `tiny_vec!`. + ([pr 118](https://github.com/Lokathor/tinyvec/pull/118)) +* [not-a-seagull](https://github.com/not-a-seagull) + added `ArrayVec::into_inner` so that you can get the array out of an `ArrayVec`. + ([pr 124](https://github.com/Lokathor/tinyvec/pull/124)) + +## 1.0.2 + +* Added license files for the MIT and Apache-2.0 license options. + +## 1.0.1 + +* Display additional features in the [docs.rs/tinyvec](https://docs.rs/tinyvec) documentation. + +## 1.0.0 + +Initial Stable Release. diff --git a/third_party/rust/tinyvec/Cargo.lock b/third_party/rust/tinyvec/Cargo.lock new file mode 100644 index 000000000000..a92987393186 --- /dev/null +++ b/third_party/rust/tinyvec/Cargo.lock @@ -0,0 +1,647 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "borsh" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" +dependencies = [ + "cfg_aliases", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "debugger_test" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95bb55f592fbb86947bee426d831de84bd65602a54f5cdcb10bfa70a62e52a0" +dependencies = [ + "anyhow", + "log", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "debugger_test_parser" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe536452a777752b9316f0c840afbb94a2411684d4f15c081449ea801ef9e75" +dependencies = [ + "anyhow", + "log", + "regex", +] + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "generic-array" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703" +dependencies = [ + "typenum", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_test" +version = "1.0.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab" +dependencies = [ + "serde", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +dependencies = [ + "arbitrary", + "borsh", + "criterion", + "debugger_test", + "debugger_test_parser", + "generic-array", + "serde", + "serde_test", + "smallvec", + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.53", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/third_party/rust/tinyvec/Cargo.toml b/third_party/rust/tinyvec/Cargo.toml new file mode 100644 index 000000000000..db45dc0ba520 --- /dev/null +++ b/third_party/rust/tinyvec/Cargo.toml @@ -0,0 +1,158 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "tinyvec" +version = "1.9.0" +authors = ["Lokathor "] +build = false +exclude = [ + "/.github", + "/*.py", + "/*.sh", + "/src-backup", +] +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "`tinyvec` provides 100% safe vec-like data structures." +readme = "README.md" +keywords = [ + "vec", + "no_std", + "no-std", +] +categories = [ + "data-structures", + "no-std", +] +license = "Zlib OR Apache-2.0 OR MIT" +repository = "https://github.com/Lokathor/tinyvec" + +[package.metadata.docs.rs] +features = [ + "alloc", + "std", + "grab_spare_slice", + "latest_stable_rust", + "serde", + "borsh", +] +rustdoc-args = [ + "--cfg", + "docs_rs", +] + +[package.metadata.playground] +features = [ + "alloc", + "std", + "grab_spare_slice", + "latest_stable_rust", + "serde", + "borsh", +] + +[features] +alloc = ["tinyvec_macros"] +debugger_visualizer = [] +default = [] +experimental_write_impl = [] +grab_spare_slice = [] +latest_stable_rust = ["rustc_1_61"] +nightly_slice_partition_dedup = [] +real_blackbox = ["criterion/real_blackbox"] +rustc_1_40 = [] +rustc_1_55 = ["rustc_1_40"] +rustc_1_57 = ["rustc_1_55"] +rustc_1_61 = ["rustc_1_57"] +std = ["alloc"] + +[lib] +name = "tinyvec" +path = "src/lib.rs" + +[[test]] +name = "arrayvec" +path = "tests/arrayvec.rs" + +[[test]] +name = "debugger_visualizer" +path = "tests/debugger_visualizer.rs" +test = false +required-features = ["debugger_visualizer"] + +[[test]] +name = "tinyvec" +path = "tests/tinyvec.rs" +required-features = [ + "alloc", + "std", +] + +[[bench]] +name = "macros" +path = "benches/macros.rs" +harness = false +required-features = ["alloc"] + +[[bench]] +name = "smallvec" +path = "benches/smallvec.rs" +harness = false +required-features = [ + "alloc", + "real_blackbox", +] + +[dependencies.arbitrary] +version = "1" +optional = true + +[dependencies.borsh] +version = "1.2.0" +optional = true +default-features = false + +[dependencies.generic-array] +version = "1.1.1" +optional = true +default-features = false + +[dependencies.serde] +version = "1.0" +optional = true +default-features = false + +[dependencies.tinyvec_macros] +version = "0.1" +optional = true + +[dev-dependencies.criterion] +version = "0.3.0" + +[dev-dependencies.debugger_test] +version = "0.1" + +[dev-dependencies.debugger_test_parser] +version = "0.1" + +[dev-dependencies.serde_test] +version = "1.0" + +[dev-dependencies.smallvec] +version = "1" + +[profile.bench] +debug = 2 diff --git a/third_party/rust/tinyvec/LICENSE-APACHE.md b/third_party/rust/tinyvec/LICENSE-APACHE.md new file mode 100644 index 000000000000..75b52484ea47 --- /dev/null +++ b/third_party/rust/tinyvec/LICENSE-APACHE.md @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor 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, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/third_party/rust/tinyvec/LICENSE-MIT.md b/third_party/rust/tinyvec/LICENSE-MIT.md new file mode 100644 index 000000000000..62d1fe61fab1 --- /dev/null +++ b/third_party/rust/tinyvec/LICENSE-MIT.md @@ -0,0 +1,5 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/tinyvec/LICENSE-ZLIB.md b/third_party/rust/tinyvec/LICENSE-ZLIB.md new file mode 100644 index 000000000000..aa2dabe6345a --- /dev/null +++ b/third_party/rust/tinyvec/LICENSE-ZLIB.md @@ -0,0 +1,11 @@ +Copyright (c) 2019 Daniel "Lokathor" Gee. + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/third_party/rust/tinyvec/README.md b/third_party/rust/tinyvec/README.md new file mode 100644 index 000000000000..740959e28007 --- /dev/null +++ b/third_party/rust/tinyvec/README.md @@ -0,0 +1,34 @@ +[![License:Zlib](https://img.shields.io/badge/License-Zlib-brightgreen.svg)](https://opensource.org/licenses/Zlib) +![Minimum Rust Version](https://img.shields.io/badge/Min%20Rust-1.47-green.svg) +[![crates.io](https://img.shields.io/crates/v/tinyvec.svg)](https://crates.io/crates/tinyvec) +[![docs.rs](https://docs.rs/tinyvec/badge.svg)](https://docs.rs/tinyvec/) + +![Unsafe-Zero-Percent](https://img.shields.io/badge/Unsafety-0%25-brightgreen.svg) + +# tinyvec + +A 100% safe crate of vec-like types. +Not just safe at the public API boundary, fully safe for all internal code too: `#![forbid(unsafe_code)]` + +The provided types are as follows: +* `ArrayVec` is an array-backed vec-like data structure. It panics on overflow. +* `SliceVec` is similar, but using a `&mut [T]` as the data backing. +* `TinyVec` (`alloc` feature) is an enum that's either an `Inline(ArrayVec)` or a `Heap(Vec)`. + If a `TinyVec` is `Inline` and would overflow its array it automatically transitions to `Heap` and continues whatever it was doing. + +To attain this "100% safe code" status there is one compromise: the element type of the vecs must implement `Default`. + +For more API details, please see [the docs.rs documentation](https://docs.rs/tinyvec/) + +## `tinyvec` Alternatives? + +Maybe you don't want to use `tinyvec`, there's other crates you might use instead! + +* [arrayvec](https://docs.rs/arrayvec) is a crate with array-backed structures. +* [smallvec](https://docs.rs/smallvec) is a crate where the array-backed data can be moved to the heap on overflow. + +The main difference is that both of those crates use `unsafe` code. +This mostly allows them to get rid of the `Default` limitation for elements that `tinyvec` imposes. +The `smallvec` and `arrayvec` crates are generally correct, but there's been occasional bugs leading to UB. +With `tinyvec`, any uncaught bugs *can't* lead to UB, because the crate is safe code all the way through. +If you want that absolute level of assurance against UB, use `tinyvec`. diff --git a/third_party/rust/tinyvec/benches/macros.rs b/third_party/rust/tinyvec/benches/macros.rs new file mode 100644 index 000000000000..16be57b7cb4b --- /dev/null +++ b/third_party/rust/tinyvec/benches/macros.rs @@ -0,0 +1,52 @@ +use criterion::{criterion_group, criterion_main, Criterion}; + +use tinyvec::tiny_vec; + +fn bench_tinyvec_macro(c: &mut Criterion) { + let mut g = c.benchmark_group("tinyvec_macro"); + + g.bench_function("0 of 32", |b| { + b.iter(|| tiny_vec!([u8; 32])); + }); + + g.bench_function("16 of 32", |b| { + b.iter(|| { + tiny_vec!([u8; 32]=> + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + ) + }); + }); + + g.bench_function("32 of 32", |b| { + b.iter(|| { + tiny_vec!([u8; 32]=> + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + ) + }); + }); + + g.bench_function("33 of 32", |b| { + b.iter(|| { + tiny_vec!([u8; 32]=> + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, + ) + }); + }); + + g.bench_function("64 of 32", |b| { + b.iter(|| { + tiny_vec!([u8; 32]=> + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + ) + }); + }); +} + +criterion_group!(benches, bench_tinyvec_macro); +criterion_main!(benches); diff --git a/third_party/rust/tinyvec/benches/smallvec.rs b/third_party/rust/tinyvec/benches/smallvec.rs new file mode 100644 index 000000000000..d5872ea8b67a --- /dev/null +++ b/third_party/rust/tinyvec/benches/smallvec.rs @@ -0,0 +1,503 @@ +//! Benchmarks that compare TinyVec to SmallVec +//! +//! All the following commentary is based on the latest nightly at the time: +//! rustc 1.55.0 (c8dfcfe04 2021-09-06). +//! +//! Some of these benchmarks are just a few instructions, so we put our own for +//! loop inside the criterion::Bencher::iter call. This seems to improve the +//! stability of measurements, and it has the wonderful side effect of making +//! the emitted assembly easier to follow. Some of these benchmarks are totally +//! inlined so that there are no calls at all in the hot path, so finding +//! this for loop is an easy way to find your way around the emitted assembly. +//! +//! The clear method is cheaper to call for arrays of elements without a Drop +//! impl, so wherever possible we reuse a single object in the benchmark loop, +//! with a clear + black_box on each iteration in an attempt to not make that +//! visible to the optimizer. +//! +//! We always call black_box(&v), instead of v = black_box(v) because the latter +//! does a move of the inline array, which is linear in the size of the array +//! and thus varies based on the array type being benchmarked, and this move can +//! be more expensive than the function we're trying to benchmark. +//! +//! We also black_box the input to each method call. This has a significant +//! effect on the assembly emitted, for example if we do not black_box the range +//! we iterate over in the ::push benchmarks, the loop is unrolled. It's not +//! entirely clear if it's better to black_box the iterator that yields the +//! items being pushed, or to black_box at a deeper level: v.push(black_box(i)) +//! for example. Anecdotally, it seems like the latter approach produces +//! unreasonably bad assembly. + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use smallvec::SmallVec; +use std::iter::FromIterator; +use tinyvec::TinyVec; + +const ITERS: usize = 10_000; + +macro_rules! tinyvec_benches { + ($c:expr, $type:ty ; $len:expr) => {{ + let mut g = $c.benchmark_group(concat!( + "TinyVec_", + stringify!($type), + "_", + stringify!($len) + )); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::default" + ), + |b| { + b.iter(|| { + for _ in 0..ITERS { + let v: TinyVec<[$type; $len]> = TinyVec::default(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::clone" + ), + |b| { + b.iter(|| { + let outer: TinyVec<[$type; $len]> = + black_box(TinyVec::from_iter(0..=($len as usize - 1) as _)); + for _ in 0..ITERS { + let v = outer.clone(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::clear" + ), + |b| { + b.iter(|| { + let mut v: TinyVec<[$type; $len]> = TinyVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::push" + ), + |b| { + b.iter(|| { + let mut v: TinyVec<[$type; $len]> = TinyVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + for i in black_box(0..=($len as usize - 1) as _) { + v.push(i); + } + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::from_iter" + ), + |b| { + b.iter(|| { + for _ in 0..ITERS { + let v: TinyVec<[$type; $len]> = + TinyVec::from_iter(black_box(0..=($len as usize - 1) as _)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::from_slice" + ), + |b| { + b.iter(|| { + let data: &[$type] = &[0, 1, 2, 3, 4, 5, 6, 7]; + for _ in 0..ITERS { + let v: TinyVec<[$type; $len]> = TinyVec::from(black_box(data)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::extend" + ), + |b| { + b.iter(|| { + let mut v: TinyVec<[$type; $len]> = black_box(TinyVec::default()); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + v.extend(black_box(0..=($len as usize - 1) as _)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::extend_from_slice" + ), + |b| { + b.iter(|| { + let data: &[$type] = black_box(&[0, 1, 2, 3, 4, 5, 6, 7]); + let mut v: TinyVec<[$type; $len]> = black_box(TinyVec::default()); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + v.extend_from_slice(data); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::insert" + ), + |b| { + b.iter(|| { + let mut v: TinyVec<[$type; $len]> = TinyVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + for i in black_box(0..=($len as usize - 1) as _) { + v.insert(i as usize, i); + } + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "TinyVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::remove" + ), + |b| { + b.iter(|| { + let outer: TinyVec<[$type; $len]> = + black_box(TinyVec::from_iter(0..=($len as usize - 1) as _)); + for _ in 0..ITERS { + let mut v = outer.clone(); + for i in black_box((0..=($len as usize - 1) as _).rev()) { + v.remove(i); + } + black_box(&v); + } + }); + }, + ); + }}; +} + +fn tinyvec_benches(c: &mut Criterion) { + tinyvec_benches!(c, u8; 8); + tinyvec_benches!(c, u8; 16); + tinyvec_benches!(c, u8; 32); + tinyvec_benches!(c, u8; 64); + tinyvec_benches!(c, u8; 128); + tinyvec_benches!(c, u8; 256); + tinyvec_benches!(c, u64; 2); + tinyvec_benches!(c, u64; 4); + tinyvec_benches!(c, u64; 8); + tinyvec_benches!(c, u64; 16); + tinyvec_benches!(c, u64; 32); +} + +macro_rules! smallvec_benches { + ($c:expr, $type:ty ; $len:expr) => {{ + let mut g = $c.benchmark_group(concat!( + "SmallVec_", + stringify!($type), + "_", + stringify!($len) + )); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::default" + ), + |b| { + b.iter(|| { + for _ in 0..ITERS { + let v: SmallVec<[$type; $len]> = SmallVec::default(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::clone" + ), + |b| { + b.iter(|| { + let outer: SmallVec<[$type; $len]> = + black_box(SmallVec::from_iter(0..=($len as usize - 1) as _)); + for _ in 0..ITERS { + let v = outer.clone(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::clear" + ), + |b| { + b.iter(|| { + let mut v: SmallVec<[$type; $len]> = SmallVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::push" + ), + |b| { + b.iter(|| { + let mut v: SmallVec<[$type; $len]> = SmallVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + for i in black_box(0..=($len as usize - 1) as _) { + v.push(i); + } + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::from_iter" + ), + |b| { + b.iter(|| { + for _ in 0..ITERS { + let v: SmallVec<[$type; $len]> = + SmallVec::from_iter(black_box(0..=($len as usize - 1) as _)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::from_slice" + ), + |b| { + b.iter(|| { + let data: &[$type] = &[0, 1, 2, 3, 4, 5, 6, 7]; + for _ in 0..ITERS { + let v: SmallVec<[$type; $len]> = SmallVec::from(black_box(data)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::extend" + ), + |b| { + b.iter(|| { + let mut v: SmallVec<[$type; $len]> = black_box(SmallVec::default()); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + v.extend(black_box(0..=($len as usize - 1) as _)); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::extend_from_slice" + ), + |b| { + b.iter(|| { + let data: &[$type] = black_box(&[0, 1, 2, 3, 4, 5, 6, 7]); + let mut v: SmallVec<[$type; $len]> = black_box(SmallVec::default()); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + v.extend_from_slice(data); + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::insert" + ), + |b| { + b.iter(|| { + let mut v: SmallVec<[$type; $len]> = SmallVec::default(); + for _ in 0..ITERS { + v.clear(); + black_box(&v); + for i in black_box(0..=($len as usize - 1) as _) { + v.insert(i as usize, i); + } + black_box(&v); + } + }); + }, + ); + + g.bench_function( + concat!( + "SmallVec<[", + stringify!($type), + "; ", + stringify!($len), + "]>::remove" + ), + |b| { + b.iter(|| { + let outer: SmallVec<[$type; $len]> = + black_box(SmallVec::from_iter(0..=($len as usize - 1) as _)); + for _ in 0..ITERS { + let mut v = outer.clone(); + for i in black_box((0..=($len as usize - 1) as _).rev()) { + v.remove(i); + } + black_box(&v); + } + }); + }, + ); + }}; +} + +fn smallvec_benches(c: &mut Criterion) { + smallvec_benches!(c, u8; 8); + smallvec_benches!(c, u8; 16); + smallvec_benches!(c, u8; 32); + smallvec_benches!(c, u8; 64); + smallvec_benches!(c, u8; 128); + smallvec_benches!(c, u8; 256); + smallvec_benches!(c, u64; 2); + smallvec_benches!(c, u64; 4); + smallvec_benches!(c, u64; 8); + smallvec_benches!(c, u64; 16); + smallvec_benches!(c, u64; 32); +} + +criterion_group!(benches, tinyvec_benches, smallvec_benches); +criterion_main!(benches); diff --git a/third_party/rust/tinyvec/debug_metadata/README.md b/third_party/rust/tinyvec/debug_metadata/README.md new file mode 100644 index 000000000000..f051efa67584 --- /dev/null +++ b/third_party/rust/tinyvec/debug_metadata/README.md @@ -0,0 +1,111 @@ +## Debugger Visualizers + +Many languages and debuggers enable developers to control how a type is +displayed in a debugger. These are called "debugger visualizations" or "debugger +views". + +The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using +the `Natvis` framework. To use Natvis, developers write XML documents using the natvis +schema that describe how debugger types should be displayed with the `.natvis` extension. +(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) +The Natvis files provide patterns which match type names a description of how to display +those types. + +The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) +or locally at `\Xml\Schemas\1033\natvis.xsd`. + +The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. +Pretty printers are written as python scripts that describe how a type should be displayed +when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) +The pretty printers provide patterns, which match type names, and for matching +types, describe how to display those types. (For writing a pretty printer, see: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter). + +### Embedding Visualizers + +Through the use of the currently unstable `#[debugger_visualizer]` attribute, the `tinyvec` +crate can embed debugger visualizers into the crate metadata. + +Currently the two types of visualizers supported are Natvis and Pretty printers. + +For Natvis files, when linking an executable with a crate that includes Natvis files, +the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. + +For pretty printers, the compiler will encode the contents of the pretty printer +in the `.debug_gdb_scripts` section of the `ELF` generated. + +### Testing Visualizers + +The `tinyvec` crate supports testing debugger visualizers defined for this crate. The entry point for +these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and +`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a +single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, +see https://crates.io/crates/debugger_test. The CI pipeline for the `tinyvec` crate has been updated +to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. + +The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the +function under the debugger specified by the `debugger` meta item. + +This proc macro attribute has 3 required values: + +1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. +2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger +commands to run. +3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of +statements that must exist in the debugger output. Pattern matching through regular expressions is also +supported by using the `pattern:` prefix for each expected statement. + +#### Example: + +```rust +#[debugger_test( + debugger = "cdb", + commands = "command1\ncommand2\ncommand3", + expected_statements = "statement1\nstatement2\nstatement3")] +fn test() { + +} +``` + +Using a multiline string is also supported, with a single debugger command/expected statement per line: + +```rust +#[debugger_test( + debugger = "cdb", + commands = " +command1 +command2 +command3", + expected_statements = " +statement1 +pattern:statement[0-9]+ +statement3")] +fn test() { + +} +``` + +In the example above, the second expected statement uses pattern matching through a regular expression +by using the `pattern:` prefix. + +#### Testing Locally + +Currently, only Natvis visualizations have been defined for the `tinyvec` crate via `debug_metadata/tinyvec.natvis`, +which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. +To run these tests locally, first ensure the debugging tools for Windows are installed or install them following +the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). +Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI +pipeline. + +#### Note + +When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively +and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to +how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger +and attaches it to the current test process. If tests are running in parallel, the test will try to attach +a debugger to the current process which may already have a debugger attached causing the test to fail. + +For example: + +``` +cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 +``` diff --git a/third_party/rust/tinyvec/debug_metadata/tinyvec.natvis b/third_party/rust/tinyvec/debug_metadata/tinyvec.natvis new file mode 100644 index 000000000000..7efccecedb68 --- /dev/null +++ b/third_party/rust/tinyvec/debug_metadata/tinyvec.natvis @@ -0,0 +1,24 @@ + + + {{ len={len} }} + + len + $T2 + + len + ($T1*)data + + + + + + {{ len={len} }} + + len + + len + data.data_ptr + + + + \ No newline at end of file diff --git a/third_party/rust/tinyvec/rustfmt.toml b/third_party/rust/tinyvec/rustfmt.toml new file mode 100644 index 000000000000..3833df6c8e71 --- /dev/null +++ b/third_party/rust/tinyvec/rustfmt.toml @@ -0,0 +1,14 @@ + +# Stable +edition = "2018" +fn_params_layout = "Compressed" +max_width = 80 +tab_spaces = 2 +use_field_init_shorthand = true +use_try_shorthand = true +use_small_heuristics = "Max" + +# Unstable +format_code_in_doc_comments = true +wrap_comments = true +imports_granularity = "Crate" diff --git a/third_party/rust/tinyvec/src/array.rs b/third_party/rust/tinyvec/src/array.rs new file mode 100644 index 000000000000..79bbc7cfbfdd --- /dev/null +++ b/third_party/rust/tinyvec/src/array.rs @@ -0,0 +1,54 @@ +/// A trait for types that are an array. +/// +/// An "array", for our purposes, has the following properties: +/// * Owns some number of elements. +/// * The element type can be generic, but must implement [`Default`]. +/// * The capacity is fixed at compile time, based on the implementing type. +/// * You can get a shared or mutable slice to the elements. +/// +/// You are generally **not** expected to need to implement this yourself. It is +/// already implemented for all the major array lengths (`0..=32` and the powers +/// of 2 up to 4,096), or for all array lengths with the feature `rustc_1_55`. +/// +/// **Additional lengths can easily be added upon request.** +/// +/// ## Safety Reminder +/// +/// Just a reminder: this trait is 100% safe, which means that `unsafe` code +/// **must not** rely on an instance of this trait being correct. +pub trait Array { + /// The type of the items in the thing. + type Item: Default; + + /// The number of slots in the thing. + const CAPACITY: usize; + + /// Gives a shared slice over the whole thing. + /// + /// A correct implementation will return a slice with a length equal to the + /// `CAPACITY` value. + fn as_slice(&self) -> &[Self::Item]; + + /// Gives a unique slice over the whole thing. + /// + /// A correct implementation will return a slice with a length equal to the + /// `CAPACITY` value. + fn as_slice_mut(&mut self) -> &mut [Self::Item]; + + /// Create a default-initialized instance of ourself, similar to the + /// [`Default`] trait, but implemented for the same range of sizes as + /// [`Array`]. + fn default() -> Self; +} + +#[cfg(all(feature = "generic-array", not(feature = "rustc_1_55")))] +core::compile_error!("generic-array requires `rustc_1_55` feature"); + +#[cfg(feature = "rustc_1_55")] +mod const_generic_impl; + +#[cfg(not(feature = "rustc_1_55"))] +mod generated_impl; + +#[cfg(feature = "generic-array")] +mod generic_array_impl; diff --git a/third_party/rust/tinyvec/src/array/const_generic_impl.rs b/third_party/rust/tinyvec/src/array/const_generic_impl.rs new file mode 100644 index 000000000000..0b145f168b02 --- /dev/null +++ b/third_party/rust/tinyvec/src/array/const_generic_impl.rs @@ -0,0 +1,23 @@ +use super::Array; + +impl Array for [T; N] { + type Item = T; + const CAPACITY: usize = N; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [(); N].map(|_| Default::default()) + } +} diff --git a/third_party/rust/tinyvec/src/array/generated_impl.rs b/third_party/rust/tinyvec/src/array/generated_impl.rs new file mode 100644 index 000000000000..d72169c5b1bd --- /dev/null +++ b/third_party/rust/tinyvec/src/array/generated_impl.rs @@ -0,0 +1,9616 @@ +// Generated file, to regenerate run +// ./gen-array-impls.sh > src/array/generated_impl.rs +// from the repo root + +use super::Array; + +impl Array for [T; 0] { + type Item = T; + const CAPACITY: usize = 0; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [] + } +} + +impl Array for [T; 1] { + type Item = T; + const CAPACITY: usize = 1; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [T::default()] + } +} + +impl Array for [T; 2] { + type Item = T; + const CAPACITY: usize = 2; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [T::default(), T::default()] + } +} + +impl Array for [T; 3] { + type Item = T; + const CAPACITY: usize = 3; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [T::default(), T::default(), T::default()] + } +} + +impl Array for [T; 4] { + type Item = T; + const CAPACITY: usize = 4; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [T::default(), T::default(), T::default(), T::default()] + } +} + +impl Array for [T; 5] { + type Item = T; + const CAPACITY: usize = 5; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [T::default(), T::default(), T::default(), T::default(), T::default()] + } +} + +impl Array for [T; 6] { + type Item = T; + const CAPACITY: usize = 6; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 7] { + type Item = T; + const CAPACITY: usize = 7; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 8] { + type Item = T; + const CAPACITY: usize = 8; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 9] { + type Item = T; + const CAPACITY: usize = 9; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 10] { + type Item = T; + const CAPACITY: usize = 10; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 11] { + type Item = T; + const CAPACITY: usize = 11; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 12] { + type Item = T; + const CAPACITY: usize = 12; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 13] { + type Item = T; + const CAPACITY: usize = 13; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 14] { + type Item = T; + const CAPACITY: usize = 14; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 15] { + type Item = T; + const CAPACITY: usize = 15; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 16] { + type Item = T; + const CAPACITY: usize = 16; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 17] { + type Item = T; + const CAPACITY: usize = 17; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 18] { + type Item = T; + const CAPACITY: usize = 18; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 19] { + type Item = T; + const CAPACITY: usize = 19; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 20] { + type Item = T; + const CAPACITY: usize = 20; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 21] { + type Item = T; + const CAPACITY: usize = 21; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 22] { + type Item = T; + const CAPACITY: usize = 22; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 23] { + type Item = T; + const CAPACITY: usize = 23; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 24] { + type Item = T; + const CAPACITY: usize = 24; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 25] { + type Item = T; + const CAPACITY: usize = 25; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 26] { + type Item = T; + const CAPACITY: usize = 26; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 27] { + type Item = T; + const CAPACITY: usize = 27; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 28] { + type Item = T; + const CAPACITY: usize = 28; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 29] { + type Item = T; + const CAPACITY: usize = 29; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 30] { + type Item = T; + const CAPACITY: usize = 30; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 31] { + type Item = T; + const CAPACITY: usize = 31; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 32] { + type Item = T; + const CAPACITY: usize = 32; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 33] { + type Item = T; + const CAPACITY: usize = 33; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 64] { + type Item = T; + const CAPACITY: usize = 64; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 128] { + type Item = T; + const CAPACITY: usize = 128; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 256] { + type Item = T; + const CAPACITY: usize = 256; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 512] { + type Item = T; + const CAPACITY: usize = 512; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 1024] { + type Item = T; + const CAPACITY: usize = 1024; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 2048] { + type Item = T; + const CAPACITY: usize = 2048; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} + +impl Array for [T; 4096] { + type Item = T; + const CAPACITY: usize = 4096; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + [ + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + T::default(), + ] + } +} diff --git a/third_party/rust/tinyvec/src/array/generic_array_impl.rs b/third_party/rust/tinyvec/src/array/generic_array_impl.rs new file mode 100644 index 000000000000..29dbd858c33c --- /dev/null +++ b/third_party/rust/tinyvec/src/array/generic_array_impl.rs @@ -0,0 +1,26 @@ +use core::default; + +use super::Array; +use generic_array::{ArrayLength, GenericArray}; + +impl Array for GenericArray { + type Item = T; + const CAPACITY: usize = N::USIZE; + + #[inline(always)] + #[must_use] + fn as_slice(&self) -> &[T] { + &*self + } + + #[inline(always)] + #[must_use] + fn as_slice_mut(&mut self) -> &mut [T] { + &mut *self + } + + #[inline(always)] + fn default() -> Self { + ::default() + } +} diff --git a/third_party/rust/tinyvec/src/arrayvec.rs b/third_party/rust/tinyvec/src/arrayvec.rs new file mode 100644 index 000000000000..0f8d71806d19 --- /dev/null +++ b/third_party/rust/tinyvec/src/arrayvec.rs @@ -0,0 +1,2079 @@ +use super::*; +use core::convert::{TryFrom, TryInto}; + +#[cfg(feature = "serde")] +use core::marker::PhantomData; +#[cfg(feature = "serde")] +use serde::de::{ + Deserialize, Deserializer, Error as DeserializeError, SeqAccess, Visitor, +}; +#[cfg(feature = "serde")] +use serde::ser::{Serialize, SerializeSeq, Serializer}; + +/// Helper to make an `ArrayVec`. +/// +/// You specify the backing array type, and optionally give all the elements you +/// want to initially place into the array. +/// +/// ```rust +/// use tinyvec::*; +/// +/// // The backing array type can be specified in the macro call +/// let empty_av = array_vec!([u8; 16]); +/// let some_ints = array_vec!([i32; 4] => 1, 2, 3); +/// +/// // Or left to inference +/// let empty_av: ArrayVec<[u8; 10]> = array_vec!(); +/// let some_ints: ArrayVec<[u8; 10]> = array_vec!(5, 6, 7, 8); +/// ``` +#[macro_export] +macro_rules! array_vec { + ($array_type:ty => $($elem:expr),* $(,)?) => { + { + let mut av: $crate::ArrayVec<$array_type> = Default::default(); + $( av.push($elem); )* + av + } + }; + ($array_type:ty) => { + $crate::ArrayVec::<$array_type>::default() + }; + ($($elem:expr),*) => { + $crate::array_vec!(_ => $($elem),*) + }; + ($elem:expr; $n:expr) => { + $crate::ArrayVec::from([$elem; $n]) + }; + () => { + $crate::array_vec!(_) + }; +} + +/// An array-backed, vector-like data structure. +/// +/// * `ArrayVec` has a fixed capacity, equal to the minimum of the array size +/// and `u16::MAX`. Note that not all capacities are necessarily supported by +/// default. See comments in [`Array`]. +/// * `ArrayVec` has a variable length, as you add and remove elements. Attempts +/// to fill the vec beyond its capacity will cause a panic. +/// * All of the vec's array slots are always initialized in terms of Rust's +/// memory model. When you remove a element from a location, the old value at +/// that location is replaced with the type's default value. +/// +/// The overall API of this type is intended to, as much as possible, emulate +/// the API of the [`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) +/// type. +/// +/// ## Construction +/// +/// You can use the `array_vec!` macro similarly to how you might use the `vec!` +/// macro. Specify the array type, then optionally give all the initial values +/// you want to have. +/// ```rust +/// # use tinyvec::*; +/// let some_ints = array_vec!([i32; 4] => 1, 2, 3); +/// assert_eq!(some_ints.len(), 3); +/// ``` +/// +/// The [`default`](ArrayVec::new) for an `ArrayVec` is to have a default +/// array with length 0. The [`new`](ArrayVec::new) method is the same as +/// calling `default` +/// ```rust +/// # use tinyvec::*; +/// let some_ints = ArrayVec::<[i32; 7]>::default(); +/// assert_eq!(some_ints.len(), 0); +/// +/// let more_ints = ArrayVec::<[i32; 7]>::new(); +/// assert_eq!(some_ints, more_ints); +/// ``` +/// +/// If you have an array and want the _whole thing_ so count as being "in" the +/// new `ArrayVec` you can use one of the `from` implementations. If you want +/// _part of_ the array then you can use +/// [`from_array_len`](ArrayVec::from_array_len): +/// ```rust +/// # use tinyvec::*; +/// let some_ints = ArrayVec::from([5, 6, 7, 8]); +/// assert_eq!(some_ints.len(), 4); +/// +/// let more_ints = ArrayVec::from_array_len([5, 6, 7, 8], 2); +/// assert_eq!(more_ints.len(), 2); +/// +/// let no_ints: ArrayVec<[u8; 5]> = ArrayVec::from_array_empty([1, 2, 3, 4, 5]); +/// assert_eq!(no_ints.len(), 0); +/// ``` +#[repr(C)] +pub struct ArrayVec { + len: u16, + pub(crate) data: A, +} + +impl Clone for ArrayVec +where + A: Array + Clone, + A::Item: Clone, +{ + #[inline] + fn clone(&self) -> Self { + Self { data: self.data.clone(), len: self.len } + } + + #[inline] + fn clone_from(&mut self, o: &Self) { + let iter = self + .data + .as_slice_mut() + .iter_mut() + .zip(o.data.as_slice()) + .take(self.len.max(o.len) as usize); + for (dst, src) in iter { + dst.clone_from(src) + } + if let Some(to_drop) = + self.data.as_slice_mut().get_mut((o.len as usize)..(self.len as usize)) + { + to_drop.iter_mut().for_each(|x| drop(core::mem::take(x))); + } + self.len = o.len; + } +} + +impl Copy for ArrayVec +where + A: Array + Copy, + A::Item: Copy, +{ +} + +impl Default for ArrayVec { + #[inline] + fn default() -> Self { + Self { len: 0, data: A::default() } + } +} + +impl Deref for ArrayVec { + type Target = [A::Item]; + #[inline(always)] + #[must_use] + fn deref(&self) -> &Self::Target { + &self.data.as_slice()[..self.len as usize] + } +} + +impl DerefMut for ArrayVec { + #[inline(always)] + #[must_use] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data.as_slice_mut()[..self.len as usize] + } +} + +impl> Index for ArrayVec { + type Output = >::Output; + #[inline(always)] + #[must_use] + fn index(&self, index: I) -> &Self::Output { + &self.deref()[index] + } +} + +impl> IndexMut for ArrayVec { + #[inline(always)] + #[must_use] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + &mut self.deref_mut()[index] + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] +impl Serialize for ArrayVec +where + A::Item: Serialize, +{ + #[must_use] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for element in self.iter() { + seq.serialize_element(element)?; + } + seq.end() + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] +impl<'de, A: Array> Deserialize<'de> for ArrayVec +where + A::Item: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(ArrayVecVisitor(PhantomData)) + } +} + +#[cfg(feature = "borsh")] +#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))] +impl borsh::BorshSerialize for ArrayVec +where + ::Item: borsh::BorshSerialize, +{ + fn serialize( + &self, writer: &mut W, + ) -> borsh::io::Result<()> { + ::serialize(&self.len(), writer)?; + for elem in self.iter() { + <::Item as borsh::BorshSerialize>::serialize(elem, writer)?; + } + Ok(()) + } +} + +#[cfg(feature = "borsh")] +#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))] +impl borsh::BorshDeserialize for ArrayVec +where + ::Item: borsh::BorshDeserialize, +{ + fn deserialize_reader( + reader: &mut R, + ) -> borsh::io::Result { + let len = ::deserialize_reader(reader)?; + let mut new_arrayvec = Self::default(); + + for idx in 0..len { + let value = + <::Item as borsh::BorshDeserialize>::deserialize_reader( + reader, + )?; + if idx >= new_arrayvec.capacity() { + return Err(borsh::io::Error::new( + borsh::io::ErrorKind::InvalidData, + "invalid ArrayVec length", + )); + } + new_arrayvec.push(value) + } + + Ok(new_arrayvec) + } +} + +#[cfg(feature = "arbitrary")] +#[cfg_attr(docs_rs, doc(cfg(feature = "arbitrary")))] +impl<'a, A> arbitrary::Arbitrary<'a> for ArrayVec +where + A: Array, + A::Item: arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let max_len = A::CAPACITY.min(u16::MAX as usize) as u16; + let len = u.int_in_range::(0..=max_len)?; + let mut self_: Self = Default::default(); + for _ in 0..len { + self_.push(u.arbitrary()?); + } + Ok(self_) + } + + fn size_hint(depth: usize) -> (usize, Option) { + arbitrary::size_hint::recursion_guard(depth, |depth| { + let max_len = A::CAPACITY.min(u16::MAX as usize); + let inner = A::Item::size_hint(depth).1; + (0, inner.map(|inner| 2 + max_len * inner)) + }) + } +} + +impl ArrayVec { + /// Move all values from `other` into this vec. + /// + /// ## Panics + /// * If the vec overflows its capacity + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 10] => 1, 2, 3); + /// let mut av2 = array_vec!([i32; 10] => 4, 5, 6); + /// av.append(&mut av2); + /// assert_eq!(av, &[1, 2, 3, 4, 5, 6][..]); + /// assert_eq!(av2, &[][..]); + /// ``` + #[inline] + pub fn append(&mut self, other: &mut Self) { + assert!( + self.try_append(other).is_none(), + "ArrayVec::append> total length {} exceeds capacity {}!", + self.len() + other.len(), + A::CAPACITY + ); + } + + /// Move all values from `other` into this vec. + /// If appending would overflow the capacity, Some(other) is returned. + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 7] => 1, 2, 3); + /// let mut av2 = array_vec!([i32; 7] => 4, 5, 6); + /// av.append(&mut av2); + /// assert_eq!(av, &[1, 2, 3, 4, 5, 6][..]); + /// assert_eq!(av2, &[][..]); + /// + /// let mut av3 = array_vec!([i32; 7] => 7, 8, 9); + /// assert!(av.try_append(&mut av3).is_some()); + /// assert_eq!(av, &[1, 2, 3, 4, 5, 6][..]); + /// assert_eq!(av3, &[7, 8, 9][..]); + /// ``` + #[inline] + pub fn try_append<'other>( + &mut self, other: &'other mut Self, + ) -> Option<&'other mut Self> { + let new_len = self.len() + other.len(); + if new_len > A::CAPACITY { + return Some(other); + } + + let iter = other.iter_mut().map(core::mem::take); + for item in iter { + self.push(item); + } + + other.set_len(0); + + return None; + } + + /// A `*mut` pointer to the backing array. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing array. + #[inline(always)] + #[must_use] + pub fn as_mut_ptr(&mut self) -> *mut A::Item { + self.data.as_slice_mut().as_mut_ptr() + } + + /// Performs a `deref_mut`, into unique slice form. + #[inline(always)] + #[must_use] + pub fn as_mut_slice(&mut self) -> &mut [A::Item] { + self.deref_mut() + } + + /// A `*const` pointer to the backing array. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing array. + #[inline(always)] + #[must_use] + pub fn as_ptr(&self) -> *const A::Item { + self.data.as_slice().as_ptr() + } + + /// Performs a `deref`, into shared slice form. + #[inline(always)] + #[must_use] + pub fn as_slice(&self) -> &[A::Item] { + self.deref() + } + + /// The capacity of the `ArrayVec`. + /// + /// This is fixed based on the array type, but can't yet be made a `const fn` + /// on Stable Rust. + #[inline(always)] + #[must_use] + pub fn capacity(&self) -> usize { + // Note: This shouldn't use A::CAPACITY, because unsafe code can't rely on + // any Array invariants. This ensures that at the very least, the returned + // value is a valid length for a subslice of the backing array. + self.data.as_slice().len().min(u16::MAX as usize) + } + + /// Truncates the `ArrayVec` down to length 0. + #[inline(always)] + pub fn clear(&mut self) { + self.truncate(0) + } + + /// Creates a draining iterator that removes the specified range in the vector + /// and yields the removed items. + /// + /// ## Panics + /// * If the start is greater than the end + /// * If the end is past the edge of the vec. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4] => 1, 2, 3); + /// let av2: ArrayVec<[i32; 4]> = av.drain(1..).collect(); + /// assert_eq!(av.as_slice(), &[1][..]); + /// assert_eq!(av2.as_slice(), &[2, 3][..]); + /// + /// av.drain(..); + /// assert_eq!(av.as_slice(), &[]); + /// ``` + #[inline] + pub fn drain(&mut self, range: R) -> ArrayVecDrain<'_, A::Item> + where + R: RangeBounds, + { + ArrayVecDrain::new(self, range) + } + + /// Returns the inner array of the `ArrayVec`. + /// + /// This returns the full array, even if the `ArrayVec` length is currently + /// less than that. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::{array_vec, ArrayVec}; + /// let mut favorite_numbers = array_vec!([i32; 5] => 87, 48, 33, 9, 26); + /// assert_eq!(favorite_numbers.clone().into_inner(), [87, 48, 33, 9, 26]); + /// + /// favorite_numbers.pop(); + /// assert_eq!(favorite_numbers.into_inner(), [87, 48, 33, 9, 0]); + /// ``` + /// + /// A use for this function is to build an array from an iterator by first + /// collecting it into an `ArrayVec`. + /// + /// ```rust + /// # use tinyvec::ArrayVec; + /// let arr_vec: ArrayVec<[i32; 10]> = (1..=3).cycle().take(10).collect(); + /// let inner = arr_vec.into_inner(); + /// assert_eq!(inner, [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]); + /// ``` + #[inline] + pub fn into_inner(self) -> A { + self.data + } + + /// Clone each element of the slice into this `ArrayVec`. + /// + /// ## Panics + /// * If the `ArrayVec` would overflow, this will panic. + #[inline] + pub fn extend_from_slice(&mut self, sli: &[A::Item]) + where + A::Item: Clone, + { + if sli.is_empty() { + return; + } + + let new_len = self.len as usize + sli.len(); + assert!( + new_len <= A::CAPACITY, + "ArrayVec::extend_from_slice> total length {} exceeds capacity {}!", + new_len, + A::CAPACITY + ); + + let target = &mut self.data.as_slice_mut()[self.len as usize..new_len]; + target.clone_from_slice(sli); + self.set_len(new_len); + } + + /// Fill the vector until its capacity has been reached. + /// + /// Successively fills unused space in the spare slice of the vector with + /// elements from the iterator. It then returns the remaining iterator + /// without exhausting it. This also allows appending the head of an + /// infinite iterator. + /// + /// This is an alternative to `Extend::extend` method for cases where the + /// length of the iterator can not be checked. Since this vector can not + /// reallocate to increase its capacity, it is unclear what to do with + /// remaining elements in the iterator and the iterator itself. The + /// interface also provides no way to communicate this to the caller. + /// + /// ## Panics + /// * If the `next` method of the provided iterator panics. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4]); + /// let mut to_inf = av.fill(0..); + /// assert_eq!(&av[..], [0, 1, 2, 3]); + /// assert_eq!(to_inf.next(), Some(4)); + /// ``` + #[inline] + pub fn fill>( + &mut self, iter: I, + ) -> I::IntoIter { + // If this is written as a call to push for each element in iter, the + // compiler emits code that updates the length for every element. The + // additional complexity from that length update is worth nearly 2x in + // the runtime of this function. + let mut iter = iter.into_iter(); + let mut pushed = 0; + let to_take = self.capacity() - self.len(); + let target = &mut self.data.as_slice_mut()[self.len as usize..]; + for element in iter.by_ref().take(to_take) { + target[pushed] = element; + pushed += 1; + } + self.len += pushed as u16; + iter + } + + /// Wraps up an array and uses the given length as the initial length. + /// + /// If you want to simply use the full array, use `from` instead. + /// + /// ## Panics + /// + /// * The length specified must be less than or equal to the capacity of the + /// array. + #[inline] + #[must_use] + #[allow(clippy::match_wild_err_arm)] + pub fn from_array_len(data: A, len: usize) -> Self { + match Self::try_from_array_len(data, len) { + Ok(out) => out, + Err(_) => panic!( + "ArrayVec::from_array_len> length {} exceeds capacity {}!", + len, + A::CAPACITY + ), + } + } + + /// Inserts an item at the position given, moving all following elements +1 + /// index. + /// + /// ## Panics + /// * If `index` > `len` + /// * If the capacity is exhausted + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut av = array_vec!([i32; 10] => 1, 2, 3); + /// av.insert(1, 4); + /// assert_eq!(av.as_slice(), &[1, 4, 2, 3]); + /// av.insert(4, 5); + /// assert_eq!(av.as_slice(), &[1, 4, 2, 3, 5]); + /// ``` + #[inline] + pub fn insert(&mut self, index: usize, item: A::Item) { + let x = self.try_insert(index, item); + assert!(x.is_none(), "ArrayVec::insert> capacity overflow!"); + } + + /// Tries to insert an item at the position given, moving all following + /// elements +1 index. + /// Returns back the element if the capacity is exhausted, + /// otherwise returns None. + /// + /// ## Panics + /// * If `index` > `len` + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut av = array_vec!([&'static str; 4] => "one", "two", "three"); + /// av.insert(1, "four"); + /// assert_eq!(av.as_slice(), &["one", "four", "two", "three"]); + /// assert_eq!(av.try_insert(4, "five"), Some("five")); + /// ``` + #[inline] + pub fn try_insert( + &mut self, index: usize, mut item: A::Item, + ) -> Option { + assert!( + index <= self.len as usize, + "ArrayVec::try_insert> index {} is out of bounds {}", + index, + self.len + ); + + // A previous implementation used self.try_push and slice::rotate_right + // rotate_right and rotate_left generate a huge amount of code and fail to + // inline; calling them here incurs the cost of all the cases they + // handle even though we're rotating a usually-small array by a constant + // 1 offset. This swap-based implementation benchmarks much better for + // small array lengths in particular. + + if (self.len as usize) < A::CAPACITY { + self.len += 1; + } else { + return Some(item); + } + + let target = &mut self.as_mut_slice()[index..]; + #[allow(clippy::needless_range_loop)] + for i in 0..target.len() { + core::mem::swap(&mut item, &mut target[i]); + } + return None; + } + + /// Checks if the length is 0. + #[inline(always)] + #[must_use] + pub fn is_empty(&self) -> bool { + self.len == 0 + } + + /// The length of the `ArrayVec` (in elements). + #[inline(always)] + #[must_use] + pub fn len(&self) -> usize { + self.len as usize + } + + /// Makes a new, empty `ArrayVec`. + #[inline(always)] + #[must_use] + pub fn new() -> Self { + Self::default() + } + + /// Remove and return the last element of the vec, if there is one. + /// + /// ## Failure + /// * If the vec is empty you get `None`. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 10] => 1, 2); + /// assert_eq!(av.pop(), Some(2)); + /// assert_eq!(av.pop(), Some(1)); + /// assert_eq!(av.pop(), None); + /// ``` + #[inline] + pub fn pop(&mut self) -> Option { + if self.len > 0 { + self.len -= 1; + let out = + core::mem::take(&mut self.data.as_slice_mut()[self.len as usize]); + Some(out) + } else { + None + } + } + + /// Place an element onto the end of the vec. + /// + /// ## Panics + /// * If the length of the vec would overflow the capacity. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 2]); + /// assert_eq!(&av[..], []); + /// av.push(1); + /// assert_eq!(&av[..], [1]); + /// av.push(2); + /// assert_eq!(&av[..], [1, 2]); + /// // av.push(3); this would overflow the ArrayVec and panic! + /// ``` + #[inline(always)] + pub fn push(&mut self, val: A::Item) { + let x = self.try_push(val); + assert!(x.is_none(), "ArrayVec::push> capacity overflow!"); + } + + /// Tries to place an element onto the end of the vec.\ + /// Returns back the element if the capacity is exhausted, + /// otherwise returns None. + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 2]); + /// assert_eq!(av.as_slice(), []); + /// assert_eq!(av.try_push(1), None); + /// assert_eq!(&av[..], [1]); + /// assert_eq!(av.try_push(2), None); + /// assert_eq!(&av[..], [1, 2]); + /// assert_eq!(av.try_push(3), Some(3)); + /// ``` + #[inline(always)] + pub fn try_push(&mut self, val: A::Item) -> Option { + debug_assert!(self.len as usize <= A::CAPACITY); + + let itemref = match self.data.as_slice_mut().get_mut(self.len as usize) { + None => return Some(val), + Some(x) => x, + }; + + *itemref = val; + self.len += 1; + return None; + } + + /// Removes the item at `index`, shifting all others down by one index. + /// + /// Returns the removed element. + /// + /// ## Panics + /// + /// * If the index is out of bounds. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4] => 1, 2, 3); + /// assert_eq!(av.remove(1), 2); + /// assert_eq!(&av[..], [1, 3]); + /// ``` + #[inline] + pub fn remove(&mut self, index: usize) -> A::Item { + let targets: &mut [A::Item] = &mut self.deref_mut()[index..]; + let item = core::mem::take(&mut targets[0]); + + // A previous implementation used rotate_left + // rotate_right and rotate_left generate a huge amount of code and fail to + // inline; calling them here incurs the cost of all the cases they + // handle even though we're rotating a usually-small array by a constant + // 1 offset. This swap-based implementation benchmarks much better for + // small array lengths in particular. + + for i in 0..targets.len() - 1 { + targets.swap(i, i + 1); + } + self.len -= 1; + item + } + + /// As [`resize_with`](ArrayVec::resize_with) + /// and it clones the value as the closure. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// + /// let mut av = array_vec!([&str; 10] => "hello"); + /// av.resize(3, "world"); + /// assert_eq!(&av[..], ["hello", "world", "world"]); + /// + /// let mut av = array_vec!([i32; 10] => 1, 2, 3, 4); + /// av.resize(2, 0); + /// assert_eq!(&av[..], [1, 2]); + /// ``` + #[inline] + pub fn resize(&mut self, new_len: usize, new_val: A::Item) + where + A::Item: Clone, + { + self.resize_with(new_len, || new_val.clone()) + } + + /// Resize the vec to the new length. + /// + /// If it needs to be longer, it's filled with repeated calls to the provided + /// function. If it needs to be shorter, it's truncated. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// + /// let mut av = array_vec!([i32; 10] => 1, 2, 3); + /// av.resize_with(5, Default::default); + /// assert_eq!(&av[..], [1, 2, 3, 0, 0]); + /// + /// let mut av = array_vec!([i32; 10]); + /// let mut p = 1; + /// av.resize_with(4, || { + /// p *= 2; + /// p + /// }); + /// assert_eq!(&av[..], [2, 4, 8, 16]); + /// ``` + #[inline] + pub fn resize_with A::Item>( + &mut self, new_len: usize, mut f: F, + ) { + match new_len.checked_sub(self.len as usize) { + None => self.truncate(new_len), + Some(new_elements) => { + for _ in 0..new_elements { + self.push(f()); + } + } + } + } + + /// Walk the vec and keep only the elements that pass the predicate given. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// + /// let mut av = array_vec!([i32; 10] => 1, 1, 2, 3, 3, 4); + /// av.retain(|&x| x % 2 == 0); + /// assert_eq!(&av[..], [2, 4]); + /// ``` + #[inline] + pub fn retain bool>(&mut self, mut acceptable: F) { + // Drop guard to contain exactly the remaining elements when the test + // panics. + struct JoinOnDrop<'vec, Item> { + items: &'vec mut [Item], + done_end: usize, + // Start of tail relative to `done_end`. + tail_start: usize, + } + + impl Drop for JoinOnDrop<'_, Item> { + fn drop(&mut self) { + self.items[self.done_end..].rotate_left(self.tail_start); + } + } + + let mut rest = JoinOnDrop { + items: &mut self.data.as_slice_mut()[..self.len as usize], + done_end: 0, + tail_start: 0, + }; + + let len = self.len as usize; + for idx in 0..len { + // Loop start invariant: idx = rest.done_end + rest.tail_start + if !acceptable(&rest.items[idx]) { + let _ = core::mem::take(&mut rest.items[idx]); + self.len -= 1; + rest.tail_start += 1; + } else { + rest.items.swap(rest.done_end, idx); + rest.done_end += 1; + } + } + } + + /// Retains only the elements specified by the predicate, passing a mutable + /// reference to it. + /// + /// In other words, remove all elements e such that f(&mut e) returns false. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// + /// let mut av = array_vec!([i32; 10] => 1, 1, 2, 3, 3, 4); + /// av.retain_mut(|x| if *x % 2 == 0 { *x *= 2; true } else { false }); + /// assert_eq!(&av[..], [4, 8]); + /// ``` + #[inline] + pub fn retain_mut(&mut self, mut acceptable: F) + where + F: FnMut(&mut A::Item) -> bool, + { + // Drop guard to contain exactly the remaining elements when the test + // panics. + struct JoinOnDrop<'vec, Item> { + items: &'vec mut [Item], + done_end: usize, + // Start of tail relative to `done_end`. + tail_start: usize, + } + + impl Drop for JoinOnDrop<'_, Item> { + fn drop(&mut self) { + self.items[self.done_end..].rotate_left(self.tail_start); + } + } + + let mut rest = JoinOnDrop { + items: &mut self.data.as_slice_mut()[..self.len as usize], + done_end: 0, + tail_start: 0, + }; + + let len = self.len as usize; + for idx in 0..len { + // Loop start invariant: idx = rest.done_end + rest.tail_start + if !acceptable(&mut rest.items[idx]) { + let _ = core::mem::take(&mut rest.items[idx]); + self.len -= 1; + rest.tail_start += 1; + } else { + rest.items.swap(rest.done_end, idx); + rest.done_end += 1; + } + } + } + + /// Forces the length of the vector to `new_len`. + /// + /// ## Panics + /// * If `new_len` is greater than the vec's capacity. + /// + /// ## Safety + /// * This is a fully safe operation! The inactive memory already counts as + /// "initialized" by Rust's rules. + /// * Other than "the memory is initialized" there are no other guarantees + /// regarding what you find in the inactive portion of the vec. + #[inline(always)] + pub fn set_len(&mut self, new_len: usize) { + if new_len > A::CAPACITY { + // Note(Lokathor): Technically we don't have to panic here, and we could + // just let some other call later on trigger a panic on accident when the + // length is wrong. However, it's a lot easier to catch bugs when things + // are more "fail-fast". + panic!( + "ArrayVec::set_len> new length {} exceeds capacity {}", + new_len, + A::CAPACITY + ) + } + + let new_len: u16 = new_len + .try_into() + .expect("ArrayVec::set_len> new length is not in range 0..=u16::MAX"); + self.len = new_len; + } + + /// Splits the collection at the point given. + /// + /// * `[0, at)` stays in this vec + /// * `[at, len)` ends up in the new vec. + /// + /// ## Panics + /// * if at > len + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4] => 1, 2, 3); + /// let av2 = av.split_off(1); + /// assert_eq!(&av[..], [1]); + /// assert_eq!(&av2[..], [2, 3]); + /// ``` + #[inline] + pub fn split_off(&mut self, at: usize) -> Self { + // FIXME: should this just use drain into the output? + if at > self.len() { + panic!( + "ArrayVec::split_off> at value {} exceeds length of {}", + at, self.len + ); + } + let mut new = Self::default(); + let moves = &mut self.as_mut_slice()[at..]; + let split_len = moves.len(); + let targets = &mut new.data.as_slice_mut()[..split_len]; + moves.swap_with_slice(targets); + + /* moves.len() <= u16::MAX, so these are surely in u16 range */ + new.len = split_len as u16; + self.len = at as u16; + new + } + + /// Creates a splicing iterator that removes the specified range in the + /// vector, yields the removed items, and replaces them with elements from + /// the provided iterator. + /// + /// `splice` fuses the provided iterator, so elements after the first `None` + /// are ignored. + /// + /// ## Panics + /// * If the start is greater than the end. + /// * If the end is past the edge of the vec. + /// * If the provided iterator panics. + /// * If the new length would overflow the capacity of the array. Because + /// `ArrayVecSplice` adds elements to this vec in its destructor when + /// necessary, this panic would occur when it is dropped. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut av = array_vec!([i32; 4] => 1, 2, 3); + /// let av2: ArrayVec<[i32; 4]> = av.splice(1.., 4..=6).collect(); + /// assert_eq!(av.as_slice(), &[1, 4, 5, 6][..]); + /// assert_eq!(av2.as_slice(), &[2, 3][..]); + /// + /// av.splice(.., None); + /// assert_eq!(av.as_slice(), &[]); + /// ``` + #[inline] + pub fn splice( + &mut self, range: R, replacement: I, + ) -> ArrayVecSplice<'_, A, core::iter::Fuse> + where + R: RangeBounds, + I: IntoIterator, + { + use core::ops::Bound; + let start = match range.start_bound() { + Bound::Included(x) => *x, + Bound::Excluded(x) => x.saturating_add(1), + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(x) => x.saturating_add(1), + Bound::Excluded(x) => *x, + Bound::Unbounded => self.len(), + }; + assert!( + start <= end, + "ArrayVec::splice> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= self.len(), + "ArrayVec::splice> Range ends at {} but length is only {}!", + end, + self.len() + ); + + ArrayVecSplice { + removal_start: start, + removal_end: end, + parent: self, + replacement: replacement.into_iter().fuse(), + } + } + + /// Remove an element, swapping the end of the vec into its place. + /// + /// ## Panics + /// * If the index is out of bounds. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([&str; 4] => "foo", "bar", "quack", "zap"); + /// + /// assert_eq!(av.swap_remove(1), "bar"); + /// assert_eq!(&av[..], ["foo", "zap", "quack"]); + /// + /// assert_eq!(av.swap_remove(0), "foo"); + /// assert_eq!(&av[..], ["quack", "zap"]); + /// ``` + #[inline] + pub fn swap_remove(&mut self, index: usize) -> A::Item { + assert!( + index < self.len(), + "ArrayVec::swap_remove> index {} is out of bounds {}", + index, + self.len + ); + if index == self.len() - 1 { + self.pop().unwrap() + } else { + let i = self.pop().unwrap(); + replace(&mut self[index], i) + } + } + + /// Reduces the vec's length to the given value. + /// + /// If the vec is already shorter than the input, nothing happens. + #[inline] + pub fn truncate(&mut self, new_len: usize) { + if new_len >= self.len as usize { + return; + } + + if needs_drop::() { + let len = self.len as usize; + self.data.as_slice_mut()[new_len..len] + .iter_mut() + .map(core::mem::take) + .for_each(drop); + } + + /* new_len is less than self.len */ + self.len = new_len as u16; + } + + /// Wraps an array, using the given length as the starting length. + /// + /// If you want to use the whole length of the array, you can just use the + /// `From` impl. + /// + /// ## Failure + /// + /// If the given length is greater than the capacity of the array this will + /// error, and you'll get the array back in the `Err`. + #[inline] + #[cfg(not(feature = "latest_stable_rust"))] + pub fn try_from_array_len(data: A, len: usize) -> Result { + /* Note(Soveu): Should we allow A::CAPACITY > u16::MAX for now? */ + if len <= A::CAPACITY { + Ok(Self { data, len: len as u16 }) + } else { + Err(data) + } + } + + /// Wraps an array, using the given length as the starting length. + /// + /// If you want to use the whole length of the array, you can just use the + /// `From` impl. + /// + /// ## Failure + /// + /// If the given length is greater than the capacity of the array this will + /// error, and you'll get the array back in the `Err`. + #[inline] + #[cfg(feature = "latest_stable_rust")] + pub const fn try_from_array_len(data: A, len: usize) -> Result { + /* Note(Soveu): Should we allow A::CAPACITY > u16::MAX for now? */ + if len <= A::CAPACITY { + Ok(Self { data, len: len as u16 }) + } else { + Err(data) + } + } +} + +impl ArrayVec { + /// Wraps up an array as a new empty `ArrayVec`. + /// + /// If you want to simply use the full array, use `from` instead. + /// + /// ## Examples + /// + /// This method in particular allows to create values for statics: + /// + /// ```rust + /// # use tinyvec::ArrayVec; + /// static DATA: ArrayVec<[u8; 5]> = ArrayVec::from_array_empty([0; 5]); + /// assert_eq!(DATA.len(), 0); + /// ``` + /// + /// But of course it is just an normal empty `ArrayVec`: + /// + /// ```rust + /// # use tinyvec::ArrayVec; + /// let mut data = ArrayVec::from_array_empty([1, 2, 3, 4]); + /// assert_eq!(&data[..], &[]); + /// data.push(42); + /// assert_eq!(&data[..], &[42]); + /// ``` + #[inline] + #[must_use] + pub const fn from_array_empty(data: A) -> Self { + Self { data, len: 0 } + } +} + +#[cfg(feature = "grab_spare_slice")] +impl ArrayVec { + /// Obtain the shared slice of the array _after_ the active memory. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4]); + /// assert_eq!(av.grab_spare_slice().len(), 4); + /// av.push(10); + /// av.push(11); + /// av.push(12); + /// av.push(13); + /// assert_eq!(av.grab_spare_slice().len(), 0); + /// ``` + #[inline(always)] + pub fn grab_spare_slice(&self) -> &[A::Item] { + &self.data.as_slice()[self.len as usize..] + } + + /// Obtain the mutable slice of the array _after_ the active memory. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 4]); + /// assert_eq!(av.grab_spare_slice_mut().len(), 4); + /// av.push(10); + /// av.push(11); + /// assert_eq!(av.grab_spare_slice_mut().len(), 2); + /// ``` + #[inline(always)] + pub fn grab_spare_slice_mut(&mut self) -> &mut [A::Item] { + &mut self.data.as_slice_mut()[self.len as usize..] + } +} + +#[cfg(feature = "nightly_slice_partition_dedup")] +impl ArrayVec { + /// De-duplicates the vec contents. + #[inline(always)] + pub fn dedup(&mut self) + where + A::Item: PartialEq, + { + self.dedup_by(|a, b| a == b) + } + + /// De-duplicates the vec according to the predicate given. + #[inline(always)] + pub fn dedup_by(&mut self, same_bucket: F) + where + F: FnMut(&mut A::Item, &mut A::Item) -> bool, + { + let len = { + let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); + dedup.len() + }; + self.truncate(len); + } + + /// De-duplicates the vec according to the key selector given. + #[inline(always)] + pub fn dedup_by_key(&mut self, mut key: F) + where + F: FnMut(&mut A::Item) -> K, + K: PartialEq, + { + self.dedup_by(|a, b| key(a) == key(b)) + } +} + +impl ArrayVec { + /// Returns the reference to the inner array of the `ArrayVec`. + /// + /// This returns the full array, even if the `ArrayVec` length is currently + /// less than that. + #[inline(always)] + #[must_use] + pub const fn as_inner(&self) -> &A { + &self.data + } +} + +/// Splicing iterator for `ArrayVec` +/// See [`ArrayVec::splice`](ArrayVec::::splice) +pub struct ArrayVecSplice<'p, A: Array, I: Iterator> { + parent: &'p mut ArrayVec, + removal_start: usize, + removal_end: usize, + replacement: I, +} + +impl<'p, A: Array, I: Iterator> Iterator + for ArrayVecSplice<'p, A, I> +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_start], + replacement, + ); + self.removal_start += 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_start); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl<'p, A, I> ExactSizeIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + #[inline] + fn len(&self) -> usize { + self.removal_end - self.removal_start + } +} + +impl<'p, A, I> FusedIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ +} + +impl<'p, A, I> DoubleEndedIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator + DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next_back() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_end - 1], + replacement, + ); + self.removal_end -= 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_end - 1); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } +} + +impl<'p, A: Array, I: Iterator> Drop + for ArrayVecSplice<'p, A, I> +{ + #[inline] + fn drop(&mut self) { + for _ in self.by_ref() {} + + // FIXME: reserve lower bound of size_hint + + for replacement in self.replacement.by_ref() { + self.parent.insert(self.removal_end, replacement); + self.removal_end += 1; + } + } +} + +impl AsMut<[A::Item]> for ArrayVec { + #[inline(always)] + #[must_use] + fn as_mut(&mut self) -> &mut [A::Item] { + &mut *self + } +} + +impl AsRef<[A::Item]> for ArrayVec { + #[inline(always)] + #[must_use] + fn as_ref(&self) -> &[A::Item] { + &*self + } +} + +impl Borrow<[A::Item]> for ArrayVec { + #[inline(always)] + #[must_use] + fn borrow(&self) -> &[A::Item] { + &*self + } +} + +impl BorrowMut<[A::Item]> for ArrayVec { + #[inline(always)] + #[must_use] + fn borrow_mut(&mut self) -> &mut [A::Item] { + &mut *self + } +} + +impl Extend for ArrayVec { + #[inline] + fn extend>(&mut self, iter: T) { + for t in iter { + self.push(t) + } + } +} + +impl From for ArrayVec { + #[inline(always)] + #[must_use] + /// The output has a length equal to the full array. + /// + /// If you want to select a length, use + /// [`from_array_len`](ArrayVec::from_array_len) + fn from(data: A) -> Self { + let len: u16 = data + .as_slice() + .len() + .try_into() + .expect("ArrayVec::from> length must be in range 0..=u16::MAX"); + Self { len, data } + } +} + +/// The error type returned when a conversion from a slice to an [`ArrayVec`] +/// fails. +#[derive(Debug, Copy, Clone)] +pub struct TryFromSliceError(()); + +impl core::fmt::Display for TryFromSliceError { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.write_str("could not convert slice to ArrayVec") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for TryFromSliceError {} + +impl TryFrom<&'_ [T]> for ArrayVec +where + T: Clone + Default, + A: Array, +{ + type Error = TryFromSliceError; + + #[inline] + /// The output has a length equal to that of the slice, with the same capacity + /// as `A`. + fn try_from(slice: &[T]) -> Result { + if slice.len() > A::CAPACITY { + Err(TryFromSliceError(())) + } else { + let mut arr = ArrayVec::new(); + // We do not use ArrayVec::extend_from_slice, because it looks like LLVM + // fails to deduplicate all the length-checking logic between the + // above if and the contents of that method, thus producing much + // slower code. Unlike many of the other optimizations in this + // crate, this one is worth keeping an eye on. I see no reason, for + // any element type, that these should produce different code. But + // they do. (rustc 1.51.0) + arr.set_len(slice.len()); + arr.as_mut_slice().clone_from_slice(slice); + Ok(arr) + } + } +} + +impl FromIterator for ArrayVec { + #[inline] + #[must_use] + fn from_iter>(iter: T) -> Self { + let mut av = Self::default(); + for i in iter { + av.push(i) + } + av + } +} + +/// Iterator for consuming an `ArrayVec` and returning owned elements. +pub struct ArrayVecIterator { + base: u16, + tail: u16, + data: A, +} + +impl ArrayVecIterator { + /// Returns the remaining items of this iterator as a slice. + #[inline] + #[must_use] + pub fn as_slice(&self) -> &[A::Item] { + &self.data.as_slice()[self.base as usize..self.tail as usize] + } +} +impl FusedIterator for ArrayVecIterator {} +impl Iterator for ArrayVecIterator { + type Item = A::Item; + #[inline] + fn next(&mut self) -> Option { + let slice = + &mut self.data.as_slice_mut()[self.base as usize..self.tail as usize]; + let itemref = slice.first_mut()?; + self.base += 1; + return Some(core::mem::take(itemref)); + } + #[inline(always)] + #[must_use] + fn size_hint(&self) -> (usize, Option) { + let s = self.tail - self.base; + let s = s as usize; + (s, Some(s)) + } + #[inline(always)] + fn count(self) -> usize { + self.size_hint().0 + } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } + #[inline] + fn nth(&mut self, n: usize) -> Option { + let slice = &mut self.data.as_slice_mut(); + let slice = &mut slice[self.base as usize..self.tail as usize]; + + if let Some(x) = slice.get_mut(n) { + /* n is in range [0 .. self.tail - self.base) so in u16 range */ + self.base += n as u16 + 1; + return Some(core::mem::take(x)); + } + + self.base = self.tail; + return None; + } +} + +impl DoubleEndedIterator for ArrayVecIterator { + #[inline] + fn next_back(&mut self) -> Option { + let slice = + &mut self.data.as_slice_mut()[self.base as usize..self.tail as usize]; + let item = slice.last_mut()?; + self.tail -= 1; + return Some(core::mem::take(item)); + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let base = self.base as usize; + let tail = self.tail as usize; + let slice = &mut self.data.as_slice_mut()[base..tail]; + let n = n.saturating_add(1); + + if let Some(n) = slice.len().checked_sub(n) { + let item = &mut slice[n]; + /* n is in [0..self.tail - self.base] range, so in u16 range */ + self.tail = self.base + n as u16; + return Some(core::mem::take(item)); + } + + self.tail = self.base; + return None; + } +} + +impl ExactSizeIterator for ArrayVecIterator { + #[inline] + fn len(&self) -> usize { + self.size_hint().0 + } +} + +impl Debug for ArrayVecIterator +where + A::Item: Debug, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_tuple("ArrayVecIterator").field(&self.as_slice()).finish() + } +} + +impl IntoIterator for ArrayVec { + type Item = A::Item; + type IntoIter = ArrayVecIterator; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + ArrayVecIterator { base: 0, tail: self.len, data: self.data } + } +} + +impl<'a, A: Array> IntoIterator for &'a mut ArrayVec { + type Item = &'a mut A::Item; + type IntoIter = core::slice::IterMut<'a, A::Item>; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +impl<'a, A: Array> IntoIterator for &'a ArrayVec { + type Item = &'a A::Item; + type IntoIter = core::slice::Iter<'a, A::Item>; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl PartialEq for ArrayVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &Self) -> bool { + self.as_slice().eq(other.as_slice()) + } +} +impl Eq for ArrayVec where A::Item: Eq {} + +impl PartialOrd for ArrayVec +where + A::Item: PartialOrd, +{ + #[inline] + #[must_use] + fn partial_cmp(&self, other: &Self) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } +} +impl Ord for ArrayVec +where + A::Item: Ord, +{ + #[inline] + #[must_use] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.as_slice().cmp(other.as_slice()) + } +} + +impl PartialEq<&A> for ArrayVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &&A) -> bool { + self.as_slice().eq(other.as_slice()) + } +} + +impl PartialEq<&[A::Item]> for ArrayVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &&[A::Item]) -> bool { + self.as_slice().eq(*other) + } +} + +impl Hash for ArrayVec +where + A::Item: Hash, +{ + #[inline] + fn hash(&self, state: &mut H) { + self.as_slice().hash(state) + } +} + +#[cfg(feature = "experimental_write_impl")] +impl> core::fmt::Write for ArrayVec { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + let my_len = self.len(); + let str_len = s.as_bytes().len(); + if my_len + str_len <= A::CAPACITY { + let remainder = &mut self.data.as_slice_mut()[my_len..]; + let target = &mut remainder[..str_len]; + target.copy_from_slice(s.as_bytes()); + Ok(()) + } else { + Err(core::fmt::Error) + } + } +} + +// // // // // // // // +// Formatting impls +// // // // // // // // + +impl Binary for ArrayVec +where + A::Item: Binary, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Binary::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Debug for ArrayVec +where + A::Item: Debug, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() && !self.is_empty() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Debug::fmt(elem, f)?; + } + if f.alternate() && !self.is_empty() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Display for ArrayVec +where + A::Item: Display, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Display::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl LowerExp for ArrayVec +where + A::Item: LowerExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl LowerHex for ArrayVec +where + A::Item: LowerHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Octal for ArrayVec +where + A::Item: Octal, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Octal::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Pointer for ArrayVec +where + A::Item: Pointer, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Pointer::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl UpperExp for ArrayVec +where + A::Item: UpperExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl UpperHex for ArrayVec +where + A::Item: UpperHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +#[cfg(all(feature = "alloc", feature = "rustc_1_57"))] +use alloc::collections::TryReserveError; + +#[cfg(feature = "alloc")] +impl ArrayVec { + /// Drains all elements to a Vec, but reserves additional space + /// ``` + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 7] => 1, 2, 3); + /// let v = av.drain_to_vec_and_reserve(10); + /// assert_eq!(v, &[1, 2, 3]); + /// assert_eq!(v.capacity(), 13); + /// ``` + #[inline] + pub fn drain_to_vec_and_reserve(&mut self, n: usize) -> Vec { + let cap = n + self.len(); + let mut v = Vec::with_capacity(cap); + let iter = self.iter_mut().map(core::mem::take); + v.extend(iter); + self.set_len(0); + return v; + } + + /// Tries to drain all elements to a Vec, but reserves additional space. + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned. + /// + /// ``` + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 7] => 1, 2, 3); + /// let v = av.try_drain_to_vec_and_reserve(10); + /// assert!(matches!(v, Ok(_))); + /// let v = v.unwrap(); + /// assert_eq!(v, &[1, 2, 3]); + /// assert_eq!(v.capacity(), 13); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_drain_to_vec_and_reserve( + &mut self, n: usize, + ) -> Result, TryReserveError> { + let cap = n + self.len(); + let mut v = Vec::new(); + v.try_reserve(cap)?; + let iter = self.iter_mut().map(core::mem::take); + v.extend(iter); + self.set_len(0); + return Ok(v); + } + + /// Drains all elements to a Vec + /// ``` + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 7] => 1, 2, 3); + /// let v = av.drain_to_vec(); + /// assert_eq!(v, &[1, 2, 3]); + /// assert_eq!(v.capacity(), 3); + /// ``` + #[inline] + pub fn drain_to_vec(&mut self) -> Vec { + self.drain_to_vec_and_reserve(0) + } + + /// Tries to drain all elements to a Vec. + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned. + /// + /// ``` + /// # use tinyvec::*; + /// let mut av = array_vec!([i32; 7] => 1, 2, 3); + /// let v = av.try_drain_to_vec(); + /// assert!(matches!(v, Ok(_))); + /// let v = v.unwrap(); + /// assert_eq!(v, &[1, 2, 3]); + /// // Vec may reserve more than necessary in order to prevent more future allocations. + /// assert!(v.capacity() >= 3); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_drain_to_vec(&mut self) -> Result, TryReserveError> { + self.try_drain_to_vec_and_reserve(0) + } +} + +#[cfg(feature = "serde")] +struct ArrayVecVisitor(PhantomData); + +#[cfg(feature = "serde")] +impl<'de, A: Array> Visitor<'de> for ArrayVecVisitor +where + A::Item: Deserialize<'de>, +{ + type Value = ArrayVec; + + fn expecting( + &self, formatter: &mut core::fmt::Formatter, + ) -> core::fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: S) -> Result + where + S: SeqAccess<'de>, + { + let mut new_arrayvec: ArrayVec = Default::default(); + + let mut idx = 0usize; + while let Some(value) = seq.next_element()? { + if new_arrayvec.len() >= new_arrayvec.capacity() { + return Err(DeserializeError::invalid_length(idx, &self)); + } + new_arrayvec.push(value); + idx = idx + 1; + } + + Ok(new_arrayvec) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn retain_mut_empty_vec() { + let mut av: ArrayVec<[i32; 4]> = ArrayVec::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_all_elements() { + let mut av: ArrayVec<[i32; 4]> = array_vec!([i32; 4] => 2, 4, 6, 8); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 4); + assert_eq!(av.as_slice(), &[2, 4, 6, 8]); + } + + #[test] + fn retain_mut_some_elements() { + let mut av: ArrayVec<[i32; 4]> = array_vec!([i32; 4] => 1, 2, 3, 4); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 2); + assert_eq!(av.as_slice(), &[2, 4]); + } + + #[test] + fn retain_mut_no_elements() { + let mut av: ArrayVec<[i32; 4]> = array_vec!([i32; 4] => 1, 3, 5, 7); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_zero_capacity() { + let mut av: ArrayVec<[i32; 0]> = ArrayVec::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } +} diff --git a/third_party/rust/tinyvec/src/arrayvec_drain.rs b/third_party/rust/tinyvec/src/arrayvec_drain.rs new file mode 100644 index 000000000000..3b1fcfd405fe --- /dev/null +++ b/third_party/rust/tinyvec/src/arrayvec_drain.rs @@ -0,0 +1,99 @@ +use super::*; + +use core::{ + ops::{Bound, RangeBounds}, + slice, +}; + +/// Draining iterator for [`ArrayVec`] +/// +/// See [`ArrayVec::drain`](ArrayVec::drain) +pub struct ArrayVecDrain<'a, T: 'a + Default> { + iter: slice::IterMut<'a, T>, +} + +impl<'a, T: 'a + Default> ArrayVecDrain<'a, T> { + pub(crate) fn new(arr: &'a mut ArrayVec, range: R) -> Self + where + A: Array, + R: RangeBounds, + { + let start = match range.start_bound() { + Bound::Unbounded => 0, + Bound::Included(&n) => n, + Bound::Excluded(&n) => n.saturating_add(1), + }; + let end = match range.end_bound() { + Bound::Unbounded => arr.len(), + Bound::Included(&n) => n.saturating_add(1), + Bound::Excluded(&n) => n, + }; + + assert!( + start <= end, + "ArrayVec::drain> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= arr.len(), + "ArrayVec::drain> Range ends at {}, but length is only {}", + end, + arr.len() + ); + + let len = end - start; + let to_rotate = &mut arr[start..]; + to_rotate.rotate_left(len); + + let oldlen = arr.len(); + let newlen = oldlen - len; + arr.set_len(newlen); + let slice = &mut arr.data.as_slice_mut()[newlen..oldlen]; + let iter = slice.iter_mut(); + Self { iter } + } +} + +impl<'a, T: 'a + Default> DoubleEndedIterator for ArrayVecDrain<'a, T> { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().map(core::mem::take) + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.iter.nth_back(n).map(core::mem::take) + } +} + +impl<'a, T: 'a + Default> Iterator for ArrayVecDrain<'a, T> { + type Item = T; + #[inline] + fn next(&mut self) -> Option { + self.iter.next().map(core::mem::take) + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.iter.nth(n).map(core::mem::take) + } + #[inline] + fn last(self) -> Option { + self.iter.last().map(core::mem::take) + } + #[inline] + fn for_each(self, f: F) + where + F: FnMut(Self::Item), + { + self.iter.map(core::mem::take).for_each(f) + } +} + +impl<'a, T: 'a + Default> FusedIterator for ArrayVecDrain<'a, T> {} +impl<'a, T: 'a + Default> ExactSizeIterator for ArrayVecDrain<'a, T> {} +/* No need to impl Drop! */ diff --git a/third_party/rust/tinyvec/src/lib.rs b/third_party/rust/tinyvec/src/lib.rs new file mode 100644 index 000000000000..fb558e715388 --- /dev/null +++ b/third_party/rust/tinyvec/src/lib.rs @@ -0,0 +1,112 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![forbid(unsafe_code)] +#![cfg_attr( + feature = "nightly_slice_partition_dedup", + feature(slice_partition_dedup) +)] +#![cfg_attr( + feature = "debugger_visualizer", + feature(debugger_visualizer), + debugger_visualizer(natvis_file = "../debug_metadata/tinyvec.natvis") +)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn(clippy::missing_inline_in_public_items)] +#![warn(clippy::must_use_candidate)] +#![warn(missing_docs)] +#![allow(clippy::borrow_deref_ref)] +#![allow(unused_imports)] +#![allow(unused_mut)] +#![allow(clippy::write_with_newline)] +#![allow(clippy::needless_return)] + +//! `tinyvec` provides 100% safe vec-like data structures. +//! +//! ## Provided Types +//! With no features enabled, this crate provides the [`ArrayVec`] type, which +//! is an array-backed storage. You can push values into the array and pop them +//! out of the array and so on. If the array is made to overflow it will panic. +//! +//! Similarly, there is also a [`SliceVec`] type available, which is a vec-like +//! that's backed by a slice you provide. You can add and remove elements, but +//! if you overflow the slice it will panic. +//! +//! With the `alloc` feature enabled, the crate also has a [`TinyVec`] type. +//! This is an enum type which is either an `Inline(ArrayVec)` or a `Heap(Vec)`. +//! If a `TinyVec` is `Inline` and would overflow it automatically transitions +//! itself into being `Heap` mode instead of a panic. +//! +//! All of this is done with no `unsafe` code within the crate. Technically the +//! `Vec` type from the standard library uses `unsafe` internally, but *this +//! crate* introduces no new `unsafe` code into your project. +//! +//! The limitation is that the element type of a vec from this crate must +//! support the [`Default`] trait. This means that this crate isn't suitable for +//! all situations, but a very surprising number of types do support `Default`. +//! +//! ## Other Features +//! * `grab_spare_slice` lets you get access to the "inactive" portions of an +//! ArrayVec. +//! * `serde` provides a `Serialize` and `Deserialize` implementation for +//! [`TinyVec`] and [`ArrayVec`] types, provided the inner item also has an +//! implementation. +//! * `borsh` provides a `BorshSerialize` and `BorshDeserialize` implementation +//! for [`TinyVec`] and [`ArrayVec`] types, provided the inner item also has +//! an implementation. +//! +//! ## API +//! The general goal of the crate is that, as much as possible, the vecs here +//! should be a "drop in" replacement for the standard library `Vec` type. We +//! strive to provide all of the `Vec` methods with the same names and +//! signatures. The exception is that the element type of some methods will have +//! a `Default` bound that's not part of the normal `Vec` type. +//! +//! The vecs here also have a few additional methods that aren't on the `Vec` +//! type. In this case, the names tend to be fairly long so that they are +//! unlikely to clash with any future methods added to `Vec`. +//! +//! ## Stability +//! * The `1.0` series of the crate works with Rustc `1.34.0` or later, though +//! you still need to have Rustc `1.36.0` to use the `alloc` feature. +//! * The `2.0` version of the crate is planned for some time after the +//! `min_const_generics` stuff becomes stable. This would greatly raise the +//! minimum rust version and also allow us to totally eliminate the need for +//! the `Array` trait. The actual usage of the crate is not expected to break +//! significantly in this transition. + +#[allow(unused_imports)] +use core::{ + borrow::{Borrow, BorrowMut}, + cmp::PartialEq, + convert::AsMut, + default::Default, + fmt::{ + Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Pointer, + UpperExp, UpperHex, + }, + hash::{Hash, Hasher}, + iter::{Extend, FromIterator, FusedIterator, IntoIterator, Iterator}, + mem::{needs_drop, replace}, + ops::{Deref, DerefMut, Index, IndexMut, RangeBounds}, + slice::SliceIndex, +}; + +#[cfg(feature = "alloc")] +#[doc(hidden)] // re-export for macros +pub extern crate alloc; + +mod array; +pub use array::*; + +mod arrayvec; +pub use arrayvec::*; + +mod arrayvec_drain; +pub use arrayvec_drain::*; + +mod slicevec; +pub use slicevec::*; + +#[cfg(feature = "alloc")] +mod tinyvec; +#[cfg(feature = "alloc")] +pub use crate::tinyvec::*; diff --git a/third_party/rust/tinyvec/src/slicevec.rs b/third_party/rust/tinyvec/src/slicevec.rs new file mode 100644 index 000000000000..c56071f07142 --- /dev/null +++ b/third_party/rust/tinyvec/src/slicevec.rs @@ -0,0 +1,1083 @@ +#![allow(unused_variables)] +#![allow(missing_docs)] + +use super::*; + +/// A slice-backed vector-like data structure. +/// +/// This is a very similar concept to `ArrayVec`, but instead +/// of the backing memory being an owned array, the backing +/// memory is a unique-borrowed slice. You can thus create +/// one of these structures "around" some slice that you're +/// working with to make it easier to manipulate. +/// +/// * Has a fixed capacity (the initial slice size). +/// * Has a variable length. +pub struct SliceVec<'s, T> { + data: &'s mut [T], + len: usize, +} + +impl<'s, T> Default for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn default() -> Self { + Self { data: &mut [], len: 0 } + } +} + +impl<'s, T> Deref for SliceVec<'s, T> { + type Target = [T]; + #[inline(always)] + #[must_use] + fn deref(&self) -> &Self::Target { + &self.data[..self.len] + } +} + +impl<'s, T> DerefMut for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data[..self.len] + } +} + +impl<'s, T, I> Index for SliceVec<'s, T> +where + I: SliceIndex<[T]>, +{ + type Output = >::Output; + #[inline(always)] + #[must_use] + fn index(&self, index: I) -> &Self::Output { + &self.deref()[index] + } +} + +impl<'s, T, I> IndexMut for SliceVec<'s, T> +where + I: SliceIndex<[T]>, +{ + #[inline(always)] + #[must_use] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + &mut self.deref_mut()[index] + } +} + +impl<'s, T> SliceVec<'s, T> { + #[inline] + pub fn append(&mut self, other: &mut Self) + where + T: Default, + { + for item in other.drain(..) { + self.push(item) + } + } + + /// A `*mut` pointer to the backing slice. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing slice. + #[inline(always)] + #[must_use] + pub fn as_mut_ptr(&mut self) -> *mut T { + self.data.as_mut_ptr() + } + + /// Performs a `deref_mut`, into unique slice form. + #[inline(always)] + #[must_use] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.deref_mut() + } + + /// A `*const` pointer to the backing slice. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing slice. + #[inline(always)] + #[must_use] + pub fn as_ptr(&self) -> *const T { + self.data.as_ptr() + } + + /// Performs a `deref`, into shared slice form. + #[inline(always)] + #[must_use] + pub fn as_slice(&self) -> &[T] { + self.deref() + } + + /// The capacity of the `SliceVec`. + /// + /// This the length of the initial backing slice. + #[inline(always)] + #[must_use] + pub fn capacity(&self) -> usize { + self.data.len() + } + + /// Truncates the `SliceVec` down to length 0. + #[inline(always)] + pub fn clear(&mut self) + where + T: Default, + { + self.truncate(0) + } + + /// Creates a draining iterator that removes the specified range in the vector + /// and yields the removed items. + /// + /// ## Panics + /// * If the start is greater than the end + /// * If the end is past the edge of the vec. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [6, 7, 8]; + /// let mut sv = SliceVec::from(&mut arr); + /// let drained_values: ArrayVec<[i32; 4]> = sv.drain(1..).collect(); + /// assert_eq!(sv.as_slice(), &[6][..]); + /// assert_eq!(drained_values.as_slice(), &[7, 8][..]); + /// + /// sv.drain(..); + /// assert_eq!(sv.as_slice(), &[]); + /// ``` + #[inline] + pub fn drain<'p, R: RangeBounds>( + &'p mut self, range: R, + ) -> SliceVecDrain<'p, 's, T> + where + T: Default, + { + use core::ops::Bound; + let start = match range.start_bound() { + Bound::Included(x) => *x, + Bound::Excluded(x) => x.saturating_add(1), + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(x) => x.saturating_add(1), + Bound::Excluded(x) => *x, + Bound::Unbounded => self.len, + }; + assert!( + start <= end, + "SliceVec::drain> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= self.len, + "SliceVec::drain> Range ends at {} but length is only {}!", + end, + self.len + ); + SliceVecDrain { + parent: self, + target_start: start, + target_index: start, + target_end: end, + } + } + + #[inline] + pub fn extend_from_slice(&mut self, sli: &[T]) + where + T: Clone, + { + if sli.is_empty() { + return; + } + + let new_len = self.len + sli.len(); + if new_len > self.capacity() { + panic!( + "SliceVec::extend_from_slice> total length {} exceeds capacity {}", + new_len, + self.capacity() + ) + } + + let target = &mut self.data[self.len..new_len]; + target.clone_from_slice(sli); + self.set_len(new_len); + } + + /// Fill the vector until its capacity has been reached. + /// + /// Successively fills unused space in the spare slice of the vector with + /// elements from the iterator. It then returns the remaining iterator + /// without exhausting it. This also allows appending the head of an + /// infinite iterator. + /// + /// This is an alternative to `Extend::extend` method for cases where the + /// length of the iterator can not be checked. Since this vector can not + /// reallocate to increase its capacity, it is unclear what to do with + /// remaining elements in the iterator and the iterator itself. The + /// interface also provides no way to communicate this to the caller. + /// + /// ## Panics + /// * If the `next` method of the provided iterator panics. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [7, 7, 7, 7]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 0); + /// let mut to_inf = sv.fill(0..); + /// assert_eq!(&sv[..], [0, 1, 2, 3]); + /// assert_eq!(to_inf.next(), Some(4)); + /// ``` + #[inline] + pub fn fill>(&mut self, iter: I) -> I::IntoIter { + let mut iter = iter.into_iter(); + for element in iter.by_ref().take(self.capacity() - self.len()) { + self.push(element); + } + iter + } + + /// Wraps up a slice and uses the given length as the initial length. + /// + /// If you want to simply use the full slice, use `from` instead. + /// + /// ## Panics + /// + /// * The length specified must be less than or equal to the capacity of the + /// slice. + #[inline] + #[must_use] + #[allow(clippy::match_wild_err_arm)] + pub fn from_slice_len(data: &'s mut [T], len: usize) -> Self { + assert!(len <= data.len()); + Self { data, len } + } + + /// Inserts an item at the position given, moving all following elements +1 + /// index. + /// + /// ## Panics + /// * If `index` > `len` + /// * If the capacity is exhausted + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [1, 2, 3, 0, 0]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 3); + /// sv.insert(1, 4); + /// assert_eq!(sv.as_slice(), &[1, 4, 2, 3]); + /// sv.insert(4, 5); + /// assert_eq!(sv.as_slice(), &[1, 4, 2, 3, 5]); + /// ``` + #[inline] + pub fn insert(&mut self, index: usize, item: T) { + if index > self.len { + panic!("SliceVec::insert> index {} is out of bounds {}", index, self.len); + } + + // Try to push the element. + self.push(item); + // And move it into its place. + self.as_mut_slice()[index..].rotate_right(1); + } + + /// Checks if the length is 0. + #[inline(always)] + #[must_use] + pub fn is_empty(&self) -> bool { + self.len == 0 + } + + /// The length of the `SliceVec` (in elements). + #[inline(always)] + #[must_use] + pub fn len(&self) -> usize { + self.len + } + + /// Remove and return the last element of the vec, if there is one. + /// + /// ## Failure + /// * If the vec is empty you get `None`. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [1, 2]; + /// let mut sv = SliceVec::from(&mut arr); + /// assert_eq!(sv.pop(), Some(2)); + /// assert_eq!(sv.pop(), Some(1)); + /// assert_eq!(sv.pop(), None); + /// ``` + #[inline] + pub fn pop(&mut self) -> Option + where + T: Default, + { + if self.len > 0 { + self.len -= 1; + let out = core::mem::take(&mut self.data[self.len]); + Some(out) + } else { + None + } + } + + /// Place an element onto the end of the vec. + /// + /// ## Panics + /// * If the length of the vec would overflow the capacity. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [0, 0]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 0); + /// assert_eq!(&sv[..], []); + /// sv.push(1); + /// assert_eq!(&sv[..], [1]); + /// sv.push(2); + /// assert_eq!(&sv[..], [1, 2]); + /// // sv.push(3); this would overflow the ArrayVec and panic! + /// ``` + #[inline(always)] + pub fn push(&mut self, val: T) { + if self.len < self.capacity() { + self.data[self.len] = val; + self.len += 1; + } else { + panic!("SliceVec::push> capacity overflow") + } + } + + /// Removes the item at `index`, shifting all others down by one index. + /// + /// Returns the removed element. + /// + /// ## Panics + /// + /// * If the index is out of bounds. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [1, 2, 3]; + /// let mut sv = SliceVec::from(&mut arr); + /// assert_eq!(sv.remove(1), 2); + /// assert_eq!(&sv[..], [1, 3]); + /// ``` + #[inline] + pub fn remove(&mut self, index: usize) -> T + where + T: Default, + { + let targets: &mut [T] = &mut self.deref_mut()[index..]; + let item = core::mem::take(&mut targets[0]); + targets.rotate_left(1); + self.len -= 1; + item + } + + /// As [`resize_with`](SliceVec::resize_with) + /// and it clones the value as the closure. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// // bigger + /// let mut arr = ["hello", "", "", "", ""]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 1); + /// sv.resize(3, "world"); + /// assert_eq!(&sv[..], ["hello", "world", "world"]); + /// + /// // smaller + /// let mut arr = ['a', 'b', 'c', 'd']; + /// let mut sv = SliceVec::from(&mut arr); + /// sv.resize(2, 'z'); + /// assert_eq!(&sv[..], ['a', 'b']); + /// ``` + #[inline] + pub fn resize(&mut self, new_len: usize, new_val: T) + where + T: Clone, + { + self.resize_with(new_len, || new_val.clone()) + } + + /// Resize the vec to the new length. + /// + /// * If it needs to be longer, it's filled with repeated calls to the + /// provided function. + /// * If it needs to be shorter, it's truncated. + /// * If the type needs to drop the truncated slots are filled with calls to + /// the provided function. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [1, 2, 3, 7, 7, 7, 7]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 3); + /// sv.resize_with(5, Default::default); + /// assert_eq!(&sv[..], [1, 2, 3, 0, 0]); + /// + /// let mut arr = [0, 0, 0, 0]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 0); + /// let mut p = 1; + /// sv.resize_with(4, || { + /// p *= 2; + /// p + /// }); + /// assert_eq!(&sv[..], [2, 4, 8, 16]); + /// ``` + #[inline] + pub fn resize_with T>(&mut self, new_len: usize, mut f: F) { + match new_len.checked_sub(self.len) { + None => { + if needs_drop::() { + while self.len() > new_len { + self.len -= 1; + self.data[self.len] = f(); + } + } else { + self.len = new_len; + } + } + Some(new_elements) => { + for _ in 0..new_elements { + self.push(f()); + } + } + } + } + + /// Walk the vec and keep only the elements that pass the predicate given. + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// + /// let mut arr = [1, 1, 2, 3, 3, 4]; + /// let mut sv = SliceVec::from(&mut arr); + /// sv.retain(|&x| x % 2 == 0); + /// assert_eq!(&sv[..], [2, 4]); + /// ``` + #[inline] + pub fn retain bool>(&mut self, mut acceptable: F) + where + T: Default, + { + // Drop guard to contain exactly the remaining elements when the test + // panics. + struct JoinOnDrop<'vec, Item> { + items: &'vec mut [Item], + done_end: usize, + // Start of tail relative to `done_end`. + tail_start: usize, + } + + impl Drop for JoinOnDrop<'_, Item> { + fn drop(&mut self) { + self.items[self.done_end..].rotate_left(self.tail_start); + } + } + + let mut rest = JoinOnDrop { items: self.data, done_end: 0, tail_start: 0 }; + + for idx in 0..self.len { + // Loop start invariant: idx = rest.done_end + rest.tail_start + if !acceptable(&rest.items[idx]) { + let _ = core::mem::take(&mut rest.items[idx]); + self.len -= 1; + rest.tail_start += 1; + } else { + rest.items.swap(rest.done_end, idx); + rest.done_end += 1; + } + } + } + + /// Forces the length of the vector to `new_len`. + /// + /// ## Panics + /// * If `new_len` is greater than the vec's capacity. + /// + /// ## Safety + /// * This is a fully safe operation! The inactive memory already counts as + /// "initialized" by Rust's rules. + /// * Other than "the memory is initialized" there are no other guarantees + /// regarding what you find in the inactive portion of the vec. + #[inline(always)] + pub fn set_len(&mut self, new_len: usize) { + if new_len > self.capacity() { + // Note(Lokathor): Technically we don't have to panic here, and we could + // just let some other call later on trigger a panic on accident when the + // length is wrong. However, it's a lot easier to catch bugs when things + // are more "fail-fast". + panic!( + "SliceVec::set_len> new length {} exceeds capacity {}", + new_len, + self.capacity() + ) + } else { + self.len = new_len; + } + } + + /// Splits the collection at the point given. + /// + /// * `[0, at)` stays in this vec (and this vec is now full). + /// * `[at, len)` ends up in the new vec (with any spare capacity). + /// + /// ## Panics + /// * if `at` > `self.len()` + /// + /// ## Example + /// + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [1, 2, 3]; + /// let mut sv = SliceVec::from(&mut arr); + /// let sv2 = sv.split_off(1); + /// assert_eq!(&sv[..], [1]); + /// assert_eq!(&sv2[..], [2, 3]); + /// ``` + #[inline] + pub fn split_off<'a>(&'a mut self, at: usize) -> SliceVec<'s, T> { + let mut new = Self::default(); + let backing: &'s mut [T] = core::mem::take(&mut self.data); + let (me, other) = backing.split_at_mut(at); + new.len = self.len - at; + new.data = other; + self.len = me.len(); + self.data = me; + new + } + + /// Remove an element, swapping the end of the vec into its place. + /// + /// ## Panics + /// * If the index is out of bounds. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = ["foo", "bar", "quack", "zap"]; + /// let mut sv = SliceVec::from(&mut arr); + /// + /// assert_eq!(sv.swap_remove(1), "bar"); + /// assert_eq!(&sv[..], ["foo", "zap", "quack"]); + /// + /// assert_eq!(sv.swap_remove(0), "foo"); + /// assert_eq!(&sv[..], ["quack", "zap"]); + /// ``` + #[inline] + pub fn swap_remove(&mut self, index: usize) -> T + where + T: Default, + { + assert!( + index < self.len, + "SliceVec::swap_remove> index {} is out of bounds {}", + index, + self.len + ); + if index == self.len - 1 { + self.pop().unwrap() + } else { + let i = self.pop().unwrap(); + replace(&mut self[index], i) + } + } + + /// Reduces the vec's length to the given value. + /// + /// If the vec is already shorter than the input, nothing happens. + #[inline] + pub fn truncate(&mut self, new_len: usize) + where + T: Default, + { + if needs_drop::() { + while self.len > new_len { + self.pop(); + } + } else { + self.len = self.len.min(new_len); + } + } + + /// Wraps a slice, using the given length as the starting length. + /// + /// If you want to use the whole length of the slice, you can just use the + /// `From` impl. + /// + /// ## Failure + /// + /// If the given length is greater than the length of the slice you get + /// `None`. + #[inline] + pub fn try_from_slice_len(data: &'s mut [T], len: usize) -> Option { + if len <= data.len() { + Some(Self { data, len }) + } else { + None + } + } +} + +#[cfg(feature = "grab_spare_slice")] +impl<'s, T> SliceVec<'s, T> { + /// Obtain the shared slice of the array _after_ the active memory. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [0; 4]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 0); + /// assert_eq!(sv.grab_spare_slice().len(), 4); + /// sv.push(10); + /// sv.push(11); + /// sv.push(12); + /// sv.push(13); + /// assert_eq!(sv.grab_spare_slice().len(), 0); + /// ``` + #[must_use] + #[inline(always)] + pub fn grab_spare_slice(&self) -> &[T] { + &self.data[self.len..] + } + + /// Obtain the mutable slice of the array _after_ the active memory. + /// + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [0; 4]; + /// let mut sv = SliceVec::from_slice_len(&mut arr, 0); + /// assert_eq!(sv.grab_spare_slice_mut().len(), 4); + /// sv.push(10); + /// sv.push(11); + /// assert_eq!(sv.grab_spare_slice_mut().len(), 2); + /// ``` + #[inline(always)] + pub fn grab_spare_slice_mut(&mut self) -> &mut [T] { + &mut self.data[self.len..] + } +} + +impl<'s, T> From<&'s mut [T]> for SliceVec<'s, T> { + /// Uses the full slice as the initial length. + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [0_i32; 2]; + /// let mut sv = SliceVec::from(&mut arr[..]); + /// ``` + #[inline] + fn from(data: &'s mut [T]) -> Self { + let len = data.len(); + Self { data, len } + } +} + +impl<'s, T, A> From<&'s mut A> for SliceVec<'s, T> +where + A: AsMut<[T]>, +{ + /// Calls `AsRef::as_mut` then uses the full slice as the initial length. + /// ## Example + /// ```rust + /// # use tinyvec::*; + /// let mut arr = [0, 0]; + /// let mut sv = SliceVec::from(&mut arr); + /// ``` + #[inline] + fn from(a: &'s mut A) -> Self { + let data = a.as_mut(); + let len = data.len(); + Self { data, len } + } +} + +/// Draining iterator for [`SliceVec`] +/// +/// See [`SliceVec::drain`](SliceVec::drain) +pub struct SliceVecDrain<'p, 's, T: Default> { + parent: &'p mut SliceVec<'s, T>, + target_start: usize, + target_index: usize, + target_end: usize, +} +impl<'p, 's, T: Default> Iterator for SliceVecDrain<'p, 's, T> { + type Item = T; + #[inline] + fn next(&mut self) -> Option { + if self.target_index != self.target_end { + let out = core::mem::take(&mut self.parent[self.target_index]); + self.target_index += 1; + Some(out) + } else { + None + } + } +} +impl<'p, 's, T: Default> FusedIterator for SliceVecDrain<'p, 's, T> {} +impl<'p, 's, T: Default> Drop for SliceVecDrain<'p, 's, T> { + #[inline] + fn drop(&mut self) { + // Changed because it was moving `self`, it's also more clear and the std + // does the same + self.for_each(drop); + // Implementation very similar to [`SliceVec::remove`](SliceVec::remove) + let count = self.target_end - self.target_start; + let targets: &mut [T] = &mut self.parent.deref_mut()[self.target_start..]; + targets.rotate_left(count); + self.parent.len -= count; + } +} + +impl<'s, T> AsMut<[T]> for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn as_mut(&mut self) -> &mut [T] { + &mut *self + } +} + +impl<'s, T> AsRef<[T]> for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn as_ref(&self) -> &[T] { + &*self + } +} + +impl<'s, T> Borrow<[T]> for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn borrow(&self) -> &[T] { + &*self + } +} + +impl<'s, T> BorrowMut<[T]> for SliceVec<'s, T> { + #[inline(always)] + #[must_use] + fn borrow_mut(&mut self) -> &mut [T] { + &mut *self + } +} + +impl<'s, T> Extend for SliceVec<'s, T> { + #[inline] + fn extend>(&mut self, iter: I) { + for t in iter { + self.push(t) + } + } +} + +impl<'s, T> IntoIterator for SliceVec<'s, T> { + type Item = &'s mut T; + type IntoIter = core::slice::IterMut<'s, T>; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + self.data.iter_mut() + } +} + +impl<'s, T> PartialEq for SliceVec<'s, T> +where + T: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &Self) -> bool { + self.as_slice().eq(other.as_slice()) + } +} +impl<'s, T> Eq for SliceVec<'s, T> where T: Eq {} + +impl<'s, T> PartialOrd for SliceVec<'s, T> +where + T: PartialOrd, +{ + #[inline] + #[must_use] + fn partial_cmp(&self, other: &Self) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } +} +impl<'s, T> Ord for SliceVec<'s, T> +where + T: Ord, +{ + #[inline] + #[must_use] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.as_slice().cmp(other.as_slice()) + } +} + +impl<'s, T> PartialEq<&[T]> for SliceVec<'s, T> +where + T: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &&[T]) -> bool { + self.as_slice().eq(*other) + } +} + +impl<'s, T> Hash for SliceVec<'s, T> +where + T: Hash, +{ + #[inline] + fn hash(&self, state: &mut H) { + self.as_slice().hash(state) + } +} + +#[cfg(feature = "experimental_write_impl")] +impl<'s> core::fmt::Write for SliceVec<'s, u8> { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + let my_len = self.len(); + let str_len = s.as_bytes().len(); + if my_len + str_len <= self.capacity() { + let remainder = &mut self.data[my_len..]; + let target = &mut remainder[..str_len]; + target.copy_from_slice(s.as_bytes()); + Ok(()) + } else { + Err(core::fmt::Error) + } + } +} + +// // // // // // // // +// Formatting impls +// // // // // // // // + +impl<'s, T> Binary for SliceVec<'s, T> +where + T: Binary, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Binary::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> Debug for SliceVec<'s, T> +where + T: Debug, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() && !self.is_empty() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Debug::fmt(elem, f)?; + } + if f.alternate() && !self.is_empty() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> Display for SliceVec<'s, T> +where + T: Display, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Display::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> LowerExp for SliceVec<'s, T> +where + T: LowerExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> LowerHex for SliceVec<'s, T> +where + T: LowerHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> Octal for SliceVec<'s, T> +where + T: Octal, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Octal::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> Pointer for SliceVec<'s, T> +where + T: Pointer, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Pointer::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> UpperExp for SliceVec<'s, T> +where + T: UpperExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl<'s, T> UpperHex for SliceVec<'s, T> +where + T: UpperHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} diff --git a/third_party/rust/tinyvec/src/tinyvec.rs b/third_party/rust/tinyvec/src/tinyvec.rs new file mode 100644 index 000000000000..7e23c371817e --- /dev/null +++ b/third_party/rust/tinyvec/src/tinyvec.rs @@ -0,0 +1,1910 @@ +use super::*; + +use alloc::vec::{self, Vec}; +use core::convert::TryFrom; +use tinyvec_macros::impl_mirrored; + +#[cfg(feature = "rustc_1_57")] +use alloc::collections::TryReserveError; + +#[cfg(feature = "serde")] +use core::marker::PhantomData; +#[cfg(feature = "serde")] +use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; +#[cfg(feature = "serde")] +use serde::ser::{Serialize, SerializeSeq, Serializer}; + +/// Helper to make a `TinyVec`. +/// +/// You specify the backing array type, and optionally give all the elements you +/// want to initially place into the array. +/// +/// ```rust +/// use tinyvec::*; +/// +/// // The backing array type can be specified in the macro call +/// let empty_tv = tiny_vec!([u8; 16]); +/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3); +/// let many_ints = tiny_vec!([i32; 4] => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +/// +/// // Or left to inference +/// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!(); +/// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3); +/// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +/// ``` +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +macro_rules! tiny_vec { + ($array_type:ty => $($elem:expr),* $(,)?) => { + { + // https://github.com/rust-lang/lang-team/issues/28 + const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*; + // If we have more `$elem` than the `CAPACITY` we will simply go directly + // to constructing on the heap. + match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) { + $crate::TinyVecConstructor::Inline(f) => { + f($crate::array_vec!($array_type => $($elem),*)) + } + $crate::TinyVecConstructor::Heap(f) => { + f(vec!($($elem),*)) + } + } + } + }; + ($array_type:ty) => { + $crate::TinyVec::<$array_type>::default() + }; + ($($elem:expr),*) => { + $crate::tiny_vec!(_ => $($elem),*) + }; + ($elem:expr; $n:expr) => { + $crate::TinyVec::from([$elem; $n]) + }; + () => { + $crate::tiny_vec!(_) + }; +} + +#[doc(hidden)] // Internal implementation details of `tiny_vec!` +pub enum TinyVecConstructor { + Inline(fn(ArrayVec) -> TinyVec), + Heap(fn(Vec) -> TinyVec), +} + +/// A vector that starts inline, but can automatically move to the heap. +/// +/// * Requires the `alloc` feature +/// +/// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::)) or +/// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The +/// interface for the type as a whole is a bunch of methods that just match on +/// the enum variant and then call the same method on the inner vec. +/// +/// ## Construction +/// +/// Because it's an enum, you can construct a `TinyVec` simply by making an +/// `ArrayVec` or `Vec` and then putting it into the enum. +/// +/// There is also a macro +/// +/// ```rust +/// # use tinyvec::*; +/// let empty_tv = tiny_vec!([u8; 16]); +/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3); +/// ``` +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub enum TinyVec { + #[allow(missing_docs)] + Inline(ArrayVec), + #[allow(missing_docs)] + Heap(Vec), +} + +impl Clone for TinyVec +where + A: Array + Clone, + A::Item: Clone, +{ + #[inline] + fn clone(&self) -> Self { + match self { + TinyVec::Heap(v) => TinyVec::Heap(v.clone()), + TinyVec::Inline(v) => TinyVec::Inline(v.clone()), + } + } + + #[inline] + fn clone_from(&mut self, o: &Self) { + if o.len() > self.len() { + self.reserve(o.len() - self.len()); + } else { + self.truncate(o.len()); + } + let (start, end) = o.split_at(self.len()); + for (dst, src) in self.iter_mut().zip(start) { + dst.clone_from(src); + } + self.extend_from_slice(end); + } +} + +impl Default for TinyVec { + #[inline] + #[must_use] + fn default() -> Self { + TinyVec::Inline(ArrayVec::default()) + } +} + +impl Deref for TinyVec { + type Target = [A::Item]; + + impl_mirrored! { + type Mirror = TinyVec; + #[inline(always)] + #[must_use] + fn deref(self: &Self) -> &Self::Target; + } +} + +impl DerefMut for TinyVec { + impl_mirrored! { + type Mirror = TinyVec; + #[inline(always)] + #[must_use] + fn deref_mut(self: &mut Self) -> &mut Self::Target; + } +} + +impl> Index for TinyVec { + type Output = >::Output; + #[inline(always)] + #[must_use] + fn index(&self, index: I) -> &Self::Output { + &self.deref()[index] + } +} + +impl> IndexMut for TinyVec { + #[inline(always)] + #[must_use] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + &mut self.deref_mut()[index] + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docs_rs, doc(cfg(feature = "std")))] +impl> std::io::Write for TinyVec { + #[inline(always)] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.extend_from_slice(buf); + Ok(buf.len()) + } + + #[inline(always)] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] +impl Serialize for TinyVec +where + A::Item: Serialize, +{ + #[must_use] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for element in self.iter() { + seq.serialize_element(element)?; + } + seq.end() + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] +impl<'de, A: Array> Deserialize<'de> for TinyVec +where + A::Item: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(TinyVecVisitor(PhantomData)) + } +} + +#[cfg(feature = "borsh")] +#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))] +impl borsh::BorshSerialize for TinyVec +where + ::Item: borsh::BorshSerialize, +{ + fn serialize( + &self, writer: &mut W, + ) -> borsh::io::Result<()> { + ::serialize(&self.len(), writer)?; + for elem in self.iter() { + <::Item as borsh::BorshSerialize>::serialize(elem, writer)?; + } + Ok(()) + } +} + +#[cfg(feature = "borsh")] +#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))] +impl borsh::BorshDeserialize for TinyVec +where + ::Item: borsh::BorshDeserialize, +{ + fn deserialize_reader( + reader: &mut R, + ) -> borsh::io::Result { + let len = ::deserialize_reader(reader)?; + let mut new_tinyvec = Self::with_capacity(len); + + for _ in 0..len { + new_tinyvec.push( + <::Item as borsh::BorshDeserialize>::deserialize_reader( + reader, + )?, + ) + } + + Ok(new_tinyvec) + } +} + +#[cfg(feature = "arbitrary")] +#[cfg_attr(docs_rs, doc(cfg(feature = "arbitrary")))] +impl<'a, A> arbitrary::Arbitrary<'a> for TinyVec +where + A: Array, + A::Item: arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let v = Vec::arbitrary(u)?; + let mut tv = TinyVec::Heap(v); + tv.shrink_to_fit(); + Ok(tv) + } +} + +impl TinyVec { + /// Returns whether elements are on heap + #[inline(always)] + #[must_use] + pub fn is_heap(&self) -> bool { + match self { + TinyVec::Heap(_) => true, + TinyVec::Inline(_) => false, + } + } + /// Returns whether elements are on stack + #[inline(always)] + #[must_use] + pub fn is_inline(&self) -> bool { + !self.is_heap() + } + + /// Shrinks the capacity of the vector as much as possible.\ + /// It is inlined if length is less than `A::CAPACITY`. + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 2] => 1, 2, 3); + /// assert!(tv.is_heap()); + /// let _ = tv.pop(); + /// assert!(tv.is_heap()); + /// tv.shrink_to_fit(); + /// assert!(tv.is_inline()); + /// ``` + #[inline] + pub fn shrink_to_fit(&mut self) { + let vec = match self { + TinyVec::Inline(_) => return, + TinyVec::Heap(h) => h, + }; + + if vec.len() > A::CAPACITY { + return vec.shrink_to_fit(); + } + + let moved_vec = core::mem::take(vec); + + let mut av = ArrayVec::default(); + let mut rest = av.fill(moved_vec); + debug_assert!(rest.next().is_none()); + *self = TinyVec::Inline(av); + } + + /// Moves the content of the TinyVec to the heap, if it's inline. + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// assert!(tv.is_inline()); + /// tv.move_to_the_heap(); + /// assert!(tv.is_heap()); + /// ``` + #[allow(clippy::missing_inline_in_public_items)] + pub fn move_to_the_heap(&mut self) { + let arr = match self { + TinyVec::Heap(_) => return, + TinyVec::Inline(a) => a, + }; + + let v = arr.drain_to_vec(); + *self = TinyVec::Heap(v); + } + + /// Tries to move the content of the TinyVec to the heap, if it's inline. + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned and the + /// content is kept on the stack. + /// + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// assert!(tv.is_inline()); + /// assert_eq!(Ok(()), tv.try_move_to_the_heap()); + /// assert!(tv.is_heap()); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_move_to_the_heap(&mut self) -> Result<(), TryReserveError> { + let arr = match self { + TinyVec::Heap(_) => return Ok(()), + TinyVec::Inline(a) => a, + }; + + let v = arr.try_drain_to_vec()?; + *self = TinyVec::Heap(v); + return Ok(()); + } + + /// If TinyVec is inline, moves the content of it to the heap. + /// Also reserves additional space. + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// assert!(tv.is_inline()); + /// tv.move_to_the_heap_and_reserve(32); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 35); + /// ``` + #[inline] + pub fn move_to_the_heap_and_reserve(&mut self, n: usize) { + let arr = match self { + TinyVec::Heap(h) => return h.reserve(n), + TinyVec::Inline(a) => a, + }; + + let v = arr.drain_to_vec_and_reserve(n); + *self = TinyVec::Heap(v); + } + + /// If TinyVec is inline, try to move the content of it to the heap. + /// Also reserves additional space. + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned. + /// + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// assert!(tv.is_inline()); + /// assert_eq!(Ok(()), tv.try_move_to_the_heap_and_reserve(32)); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 35); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_move_to_the_heap_and_reserve( + &mut self, n: usize, + ) -> Result<(), TryReserveError> { + let arr = match self { + TinyVec::Heap(h) => return h.try_reserve(n), + TinyVec::Inline(a) => a, + }; + + let v = arr.try_drain_to_vec_and_reserve(n)?; + *self = TinyVec::Heap(v); + return Ok(()); + } + + /// Reserves additional space. + /// Moves to the heap if array can't hold `n` more items + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); + /// assert!(tv.is_inline()); + /// tv.reserve(1); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 5); + /// ``` + #[inline] + pub fn reserve(&mut self, n: usize) { + let arr = match self { + TinyVec::Heap(h) => return h.reserve(n), + TinyVec::Inline(a) => a, + }; + + if n > arr.capacity() - arr.len() { + let v = arr.drain_to_vec_and_reserve(n); + *self = TinyVec::Heap(v); + } + + /* In this place array has enough place, so no work is needed more */ + return; + } + + /// Tries to reserve additional space. + /// Moves to the heap if array can't hold `n` more items. + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned. + /// + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); + /// assert!(tv.is_inline()); + /// assert_eq!(Ok(()), tv.try_reserve(1)); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 5); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_reserve(&mut self, n: usize) -> Result<(), TryReserveError> { + let arr = match self { + TinyVec::Heap(h) => return h.try_reserve(n), + TinyVec::Inline(a) => a, + }; + + if n > arr.capacity() - arr.len() { + let v = arr.try_drain_to_vec_and_reserve(n)?; + *self = TinyVec::Heap(v); + } + + /* In this place array has enough place, so no work is needed more */ + return Ok(()); + } + + /// Reserves additional space. + /// Moves to the heap if array can't hold `n` more items + /// + /// From [Vec::reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve_exact) + /// ```text + /// Note that the allocator may give the collection more space than it requests. + /// Therefore, capacity can not be relied upon to be precisely minimal. + /// Prefer `reserve` if future insertions are expected. + /// ``` + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); + /// assert!(tv.is_inline()); + /// tv.reserve_exact(1); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 5); + /// ``` + #[inline] + pub fn reserve_exact(&mut self, n: usize) { + let arr = match self { + TinyVec::Heap(h) => return h.reserve_exact(n), + TinyVec::Inline(a) => a, + }; + + if n > arr.capacity() - arr.len() { + let v = arr.drain_to_vec_and_reserve(n); + *self = TinyVec::Heap(v); + } + + /* In this place array has enough place, so no work is needed more */ + return; + } + + /// Tries to reserve additional space. + /// Moves to the heap if array can't hold `n` more items + /// + /// # Errors + /// + /// If the allocator reports a failure, then an error is returned. + /// + /// From [Vec::try_reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve_exact) + /// ```text + /// Note that the allocator may give the collection more space than it requests. + /// Therefore, capacity can not be relied upon to be precisely minimal. + /// Prefer `reserve` if future insertions are expected. + /// ``` + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); + /// assert!(tv.is_inline()); + /// assert_eq!(Ok(()), tv.try_reserve_exact(1)); + /// assert!(tv.is_heap()); + /// assert!(tv.capacity() >= 5); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_57")] + pub fn try_reserve_exact(&mut self, n: usize) -> Result<(), TryReserveError> { + let arr = match self { + TinyVec::Heap(h) => return h.try_reserve_exact(n), + TinyVec::Inline(a) => a, + }; + + if n > arr.capacity() - arr.len() { + let v = arr.try_drain_to_vec_and_reserve(n)?; + *self = TinyVec::Heap(v); + } + + /* In this place array has enough place, so no work is needed more */ + return Ok(()); + } + + /// Makes a new TinyVec with _at least_ the given capacity. + /// + /// If the requested capacity is less than or equal to the array capacity you + /// get an inline vec. If it's greater than you get a heap vec. + /// ``` + /// # use tinyvec::*; + /// let t = TinyVec::<[u8; 10]>::with_capacity(5); + /// assert!(t.is_inline()); + /// assert!(t.capacity() >= 5); + /// + /// let t = TinyVec::<[u8; 10]>::with_capacity(20); + /// assert!(t.is_heap()); + /// assert!(t.capacity() >= 20); + /// ``` + #[inline] + #[must_use] + pub fn with_capacity(cap: usize) -> Self { + if cap <= A::CAPACITY { + TinyVec::Inline(ArrayVec::default()) + } else { + TinyVec::Heap(Vec::with_capacity(cap)) + } + } + + /// Converts a `TinyVec<[T; N]>` into a `Box<[T]>`. + /// + /// - For `TinyVec::Heap(Vec)`, it takes the `Vec` and converts it into + /// a `Box<[T]>` without heap reallocation. + /// - For `TinyVec::Inline(inner_data)`, it first converts the `inner_data` to + /// `Vec`, then into a `Box<[T]>`. Requiring only a single heap + /// allocation. + /// + /// ## Example + /// + /// ``` + /// use core::mem::size_of_val as mem_size_of; + /// use tinyvec::TinyVec; + /// + /// // Initialize TinyVec with 256 elements (exceeding inline capacity) + /// let v: TinyVec<[_; 128]> = (0u8..=255).collect(); + /// + /// assert!(v.is_heap()); + /// assert_eq!(mem_size_of(&v), 136); // mem size of TinyVec<[u8; N]>: N+8 + /// assert_eq!(v.len(), 256); + /// + /// let boxed = v.into_boxed_slice(); + /// assert_eq!(mem_size_of(&boxed), 16); // mem size of Box<[u8]>: 16 bytes (fat pointer) + /// assert_eq!(boxed.len(), 256); + /// ``` + #[inline] + #[must_use] + pub fn into_boxed_slice(self) -> alloc::boxed::Box<[A::Item]> { + self.into_vec().into_boxed_slice() + } + + /// Converts a `TinyVec<[T; N]>` into a `Vec`. + /// + /// `v.into_vec()` is equivalent to `Into::>::into(v)`. + /// + /// - For `TinyVec::Inline(_)`, `.into_vec()` **does not** offer a performance + /// advantage over `.to_vec()`. + /// - For `TinyVec::Heap(vec_data)`, `.into_vec()` will take `vec_data` + /// without heap reallocation. + /// + /// ## Example + /// + /// ``` + /// use tinyvec::TinyVec; + /// + /// let v = TinyVec::from([0u8; 8]); + /// let v2 = v.clone(); + /// + /// let vec = v.into_vec(); + /// let vec2: Vec<_> = v2.into(); + /// + /// assert_eq!(vec, vec2); + /// ``` + #[inline] + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl TinyVec { + /// Move all values from `other` into this vec. + #[inline] + pub fn append(&mut self, other: &mut Self) { + self.reserve(other.len()); + + /* Doing append should be faster, because it is effectively a memcpy */ + match (self, other) { + (TinyVec::Heap(sh), TinyVec::Heap(oh)) => sh.append(oh), + (TinyVec::Inline(a), TinyVec::Heap(h)) => a.extend(h.drain(..)), + (ref mut this, TinyVec::Inline(arr)) => this.extend(arr.drain(..)), + } + } + + impl_mirrored! { + type Mirror = TinyVec; + + /// Remove an element, swapping the end of the vec into its place. + /// + /// ## Panics + /// * If the index is out of bounds. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([&str; 4] => "foo", "bar", "quack", "zap"); + /// + /// assert_eq!(tv.swap_remove(1), "bar"); + /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]); + /// + /// assert_eq!(tv.swap_remove(0), "foo"); + /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]); + /// ``` + #[inline] + pub fn swap_remove(self: &mut Self, index: usize) -> A::Item; + + /// Remove and return the last element of the vec, if there is one. + /// + /// ## Failure + /// * If the vec is empty you get `None`. + #[inline] + pub fn pop(self: &mut Self) -> Option; + + /// Removes the item at `index`, shifting all others down by one index. + /// + /// Returns the removed element. + /// + /// ## Panics + /// + /// If the index is out of bounds. + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// assert_eq!(tv.remove(1), 2); + /// assert_eq!(tv.as_slice(), &[1, 3][..]); + /// ``` + #[inline] + pub fn remove(self: &mut Self, index: usize) -> A::Item; + + /// The length of the vec (in elements). + #[inline(always)] + #[must_use] + pub fn len(self: &Self) -> usize; + + /// The capacity of the `TinyVec`. + /// + /// When not heap allocated this is fixed based on the array type. + /// Otherwise its the result of the underlying Vec::capacity. + #[inline(always)] + #[must_use] + pub fn capacity(self: &Self) -> usize; + + /// Reduces the vec's length to the given value. + /// + /// If the vec is already shorter than the input, nothing happens. + #[inline] + pub fn truncate(self: &mut Self, new_len: usize); + + /// A mutable pointer to the backing array. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing array/buffer. + #[inline(always)] + #[must_use] + pub fn as_mut_ptr(self: &mut Self) -> *mut A::Item; + + /// A const pointer to the backing array. + /// + /// ## Safety + /// + /// This pointer has provenance over the _entire_ backing array/buffer. + #[inline(always)] + #[must_use] + pub fn as_ptr(self: &Self) -> *const A::Item; + } + + /// Walk the vec and keep only the elements that pass the predicate given. + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// + /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4); + /// tv.retain(|&x| x % 2 == 0); + /// assert_eq!(tv.as_slice(), &[2, 4][..]); + /// ``` + #[inline] + pub fn retain bool>(&mut self, acceptable: F) { + match self { + TinyVec::Inline(i) => i.retain(acceptable), + TinyVec::Heap(h) => h.retain(acceptable), + } + } + + /// Walk the vec and keep only the elements that pass the predicate given, + /// having the opportunity to modify the elements at the same time. + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// + /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4); + /// tv.retain_mut(|x| if *x % 2 == 0 { *x *= 2; true } else { false }); + /// assert_eq!(tv.as_slice(), &[4, 8][..]); + /// ``` + #[inline] + #[cfg(feature = "rustc_1_61")] + pub fn retain_mut bool>(&mut self, acceptable: F) { + match self { + TinyVec::Inline(i) => i.retain_mut(acceptable), + TinyVec::Heap(h) => h.retain_mut(acceptable), + } + } + + /// Helper for getting the mut slice. + #[inline(always)] + #[must_use] + pub fn as_mut_slice(&mut self) -> &mut [A::Item] { + self.deref_mut() + } + + /// Helper for getting the shared slice. + #[inline(always)] + #[must_use] + pub fn as_slice(&self) -> &[A::Item] { + self.deref() + } + + /// Removes all elements from the vec. + #[inline(always)] + pub fn clear(&mut self) { + self.truncate(0) + } + + /// De-duplicates the vec. + #[cfg(feature = "nightly_slice_partition_dedup")] + #[inline(always)] + pub fn dedup(&mut self) + where + A::Item: PartialEq, + { + self.dedup_by(|a, b| a == b) + } + + /// De-duplicates the vec according to the predicate given. + #[cfg(feature = "nightly_slice_partition_dedup")] + #[inline(always)] + pub fn dedup_by(&mut self, same_bucket: F) + where + F: FnMut(&mut A::Item, &mut A::Item) -> bool, + { + let len = { + let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); + dedup.len() + }; + self.truncate(len); + } + + /// De-duplicates the vec according to the key selector given. + #[cfg(feature = "nightly_slice_partition_dedup")] + #[inline(always)] + pub fn dedup_by_key(&mut self, mut key: F) + where + F: FnMut(&mut A::Item) -> K, + K: PartialEq, + { + self.dedup_by(|a, b| key(a) == key(b)) + } + + /// Creates a draining iterator that removes the specified range in the vector + /// and yields the removed items. + /// + /// **Note: This method has significant performance issues compared to + /// matching on the TinyVec and then calling drain on the Inline or Heap value + /// inside. The draining iterator has to branch on every single access. It is + /// provided for simplicity and compatibility only.** + /// + /// ## Panics + /// * If the start is greater than the end + /// * If the end is past the edge of the vec. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect(); + /// assert_eq!(tv.as_slice(), &[1][..]); + /// assert_eq!(tv2.as_slice(), &[2, 3][..]); + /// + /// tv.drain(..); + /// assert_eq!(tv.as_slice(), &[]); + /// ``` + #[inline] + pub fn drain>( + &mut self, range: R, + ) -> TinyVecDrain<'_, A> { + match self { + TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)), + TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)), + } + } + + /// Clone each element of the slice into this vec. + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2); + /// tv.extend_from_slice(&[3, 4]); + /// assert_eq!(tv.as_slice(), [1, 2, 3, 4]); + /// ``` + #[inline] + pub fn extend_from_slice(&mut self, sli: &[A::Item]) + where + A::Item: Clone, + { + self.reserve(sli.len()); + match self { + TinyVec::Inline(a) => a.extend_from_slice(sli), + TinyVec::Heap(h) => h.extend_from_slice(sli), + } + } + + /// Wraps up an array and uses the given length as the initial length. + /// + /// Note that the `From` impl for arrays assumes the full length is used. + /// + /// ## Panics + /// + /// The length must be less than or equal to the capacity of the array. + #[inline] + #[must_use] + #[allow(clippy::match_wild_err_arm)] + pub fn from_array_len(data: A, len: usize) -> Self { + match Self::try_from_array_len(data, len) { + Ok(out) => out, + Err(_) => { + panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY) + } + } + } + + /// This is an internal implementation detail of the `tiny_vec!` macro, and + /// using it other than from that macro is not supported by this crate's + /// SemVer guarantee. + #[inline(always)] + #[doc(hidden)] + pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor { + if cap <= A::CAPACITY { + TinyVecConstructor::Inline(TinyVec::Inline) + } else { + TinyVecConstructor::Heap(TinyVec::Heap) + } + } + + /// Inserts an item at the position given, moving all following elements +1 + /// index. + /// + /// ## Panics + /// * If `index` > `len` + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3); + /// tv.insert(1, 4); + /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]); + /// tv.insert(4, 5); + /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]); + /// ``` + #[inline] + pub fn insert(&mut self, index: usize, item: A::Item) { + assert!( + index <= self.len(), + "insertion index (is {}) should be <= len (is {})", + index, + self.len() + ); + + let arr = match self { + TinyVec::Heap(v) => return v.insert(index, item), + TinyVec::Inline(a) => a, + }; + + if let Some(x) = arr.try_insert(index, item) { + let mut v = Vec::with_capacity(arr.len() * 2); + let mut it = arr.iter_mut().map(core::mem::take); + v.extend(it.by_ref().take(index)); + v.push(x); + v.extend(it); + *self = TinyVec::Heap(v); + } + } + + /// If the vec is empty. + #[inline(always)] + #[must_use] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Makes a new, empty vec. + #[inline(always)] + #[must_use] + pub fn new() -> Self { + Self::default() + } + + /// Place an element onto the end of the vec. + #[inline] + pub fn push(&mut self, val: A::Item) { + // The code path for moving the inline contents to the heap produces a lot + // of instructions, but we have a strong guarantee that this is a cold + // path. LLVM doesn't know this, inlines it, and this tends to cause a + // cascade of other bad inlining decisions because the body of push looks + // huge even though nearly every call executes the same few instructions. + // + // Moving the logic out of line with #[cold] causes the hot code to be + // inlined together, and we take the extra cost of a function call only + // in rare cases. + #[cold] + fn drain_to_heap_and_push( + arr: &mut ArrayVec, val: A::Item, + ) -> TinyVec { + /* Make the Vec twice the size to amortize the cost of draining */ + let mut v = arr.drain_to_vec_and_reserve(arr.len()); + v.push(val); + TinyVec::Heap(v) + } + + match self { + TinyVec::Heap(v) => v.push(val), + TinyVec::Inline(arr) => { + if let Some(x) = arr.try_push(val) { + *self = drain_to_heap_and_push(arr, x); + } + } + } + } + + /// Resize the vec to the new length. + /// + /// If it needs to be longer, it's filled with clones of the provided value. + /// If it needs to be shorter, it's truncated. + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// + /// let mut tv = tiny_vec!([&str; 10] => "hello"); + /// tv.resize(3, "world"); + /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]); + /// + /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4); + /// tv.resize(2, 0); + /// assert_eq!(tv.as_slice(), &[1, 2][..]); + /// ``` + #[inline] + pub fn resize(&mut self, new_len: usize, new_val: A::Item) + where + A::Item: Clone, + { + self.resize_with(new_len, || new_val.clone()); + } + + /// Resize the vec to the new length. + /// + /// If it needs to be longer, it's filled with repeated calls to the provided + /// function. If it needs to be shorter, it's truncated. + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// + /// let mut tv = tiny_vec!([i32; 3] => 1, 2, 3); + /// tv.resize_with(5, Default::default); + /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]); + /// + /// let mut tv = tiny_vec!([i32; 2]); + /// let mut p = 1; + /// tv.resize_with(4, || { + /// p *= 2; + /// p + /// }); + /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]); + /// ``` + #[inline] + pub fn resize_with A::Item>(&mut self, new_len: usize, f: F) { + match new_len.checked_sub(self.len()) { + None => return self.truncate(new_len), + Some(n) => self.reserve(n), + } + + match self { + TinyVec::Inline(a) => a.resize_with(new_len, f), + TinyVec::Heap(v) => v.resize_with(new_len, f), + } + } + + /// Splits the collection at the point given. + /// + /// * `[0, at)` stays in this vec + /// * `[at, len)` ends up in the new vec. + /// + /// ## Panics + /// * if at > len + /// + /// ## Example + /// + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// let tv2 = tv.split_off(1); + /// assert_eq!(tv.as_slice(), &[1][..]); + /// assert_eq!(tv2.as_slice(), &[2, 3][..]); + /// ``` + #[inline] + pub fn split_off(&mut self, at: usize) -> Self { + match self { + TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)), + TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)), + } + } + + /// Creates a splicing iterator that removes the specified range in the + /// vector, yields the removed items, and replaces them with elements from + /// the provided iterator. + /// + /// `splice` fuses the provided iterator, so elements after the first `None` + /// are ignored. + /// + /// ## Panics + /// * If the start is greater than the end. + /// * If the end is past the edge of the vec. + /// * If the provided iterator panics. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// let tv2: TinyVec<[i32; 4]> = tv.splice(1.., 4..=6).collect(); + /// assert_eq!(tv.as_slice(), &[1, 4, 5, 6][..]); + /// assert_eq!(tv2.as_slice(), &[2, 3][..]); + /// + /// tv.splice(.., None); + /// assert_eq!(tv.as_slice(), &[]); + /// ``` + #[inline] + pub fn splice( + &mut self, range: R, replacement: I, + ) -> TinyVecSplice<'_, A, core::iter::Fuse> + where + R: RangeBounds, + I: IntoIterator, + { + use core::ops::Bound; + let start = match range.start_bound() { + Bound::Included(x) => *x, + Bound::Excluded(x) => x.saturating_add(1), + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(x) => x.saturating_add(1), + Bound::Excluded(x) => *x, + Bound::Unbounded => self.len(), + }; + assert!( + start <= end, + "TinyVec::splice> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= self.len(), + "TinyVec::splice> Range ends at {} but length is only {}!", + end, + self.len() + ); + + TinyVecSplice { + removal_start: start, + removal_end: end, + parent: self, + replacement: replacement.into_iter().fuse(), + } + } + + /// Wraps an array, using the given length as the starting length. + /// + /// If you want to use the whole length of the array, you can just use the + /// `From` impl. + /// + /// ## Failure + /// + /// If the given length is greater than the capacity of the array this will + /// error, and you'll get the array back in the `Err`. + #[inline] + pub fn try_from_array_len(data: A, len: usize) -> Result { + let arr = ArrayVec::try_from_array_len(data, len)?; + Ok(TinyVec::Inline(arr)) + } +} + +/// Draining iterator for `TinyVecDrain` +/// +/// See [`TinyVecDrain::drain`](TinyVecDrain::::drain) +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub enum TinyVecDrain<'p, A: Array> { + #[allow(missing_docs)] + Inline(ArrayVecDrain<'p, A::Item>), + #[allow(missing_docs)] + Heap(vec::Drain<'p, A::Item>), +} + +impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> { + type Item = A::Item; + + impl_mirrored! { + type Mirror = TinyVecDrain; + + #[inline] + fn next(self: &mut Self) -> Option; + #[inline] + fn nth(self: &mut Self, n: usize) -> Option; + #[inline] + fn size_hint(self: &Self) -> (usize, Option); + #[inline] + fn last(self: Self) -> Option; + #[inline] + fn count(self: Self) -> usize; + } + + #[inline] + fn for_each(self, f: F) { + match self { + TinyVecDrain::Inline(i) => i.for_each(f), + TinyVecDrain::Heap(h) => h.for_each(f), + } + } +} + +impl<'p, A: Array> DoubleEndedIterator for TinyVecDrain<'p, A> { + impl_mirrored! { + type Mirror = TinyVecDrain; + + #[inline] + fn next_back(self: &mut Self) -> Option; + + #[inline] + fn nth_back(self: &mut Self, n: usize) -> Option; + } +} + +/// Splicing iterator for `TinyVec` +/// See [`TinyVec::splice`](TinyVec::::splice) +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub struct TinyVecSplice<'p, A: Array, I: Iterator> { + parent: &'p mut TinyVec, + removal_start: usize, + removal_end: usize, + replacement: I, +} + +impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_start], + replacement, + ); + self.removal_start += 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_start); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + #[inline] + fn len(&self) -> usize { + self.removal_end - self.removal_start + } +} + +impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ +} + +impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator + DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next_back() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_end - 1], + replacement, + ); + self.removal_end -= 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_end - 1); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } +} + +impl<'p, A: Array, I: Iterator> Drop + for TinyVecSplice<'p, A, I> +{ + #[inline] + fn drop(&mut self) { + for _ in self.by_ref() {} + + let (lower_bound, _) = self.replacement.size_hint(); + self.parent.reserve(lower_bound); + + for replacement in self.replacement.by_ref() { + self.parent.insert(self.removal_end, replacement); + self.removal_end += 1; + } + } +} + +impl AsMut<[A::Item]> for TinyVec { + #[inline(always)] + #[must_use] + fn as_mut(&mut self) -> &mut [A::Item] { + &mut *self + } +} + +impl AsRef<[A::Item]> for TinyVec { + #[inline(always)] + #[must_use] + fn as_ref(&self) -> &[A::Item] { + &*self + } +} + +impl Borrow<[A::Item]> for TinyVec { + #[inline(always)] + #[must_use] + fn borrow(&self) -> &[A::Item] { + &*self + } +} + +impl BorrowMut<[A::Item]> for TinyVec { + #[inline(always)] + #[must_use] + fn borrow_mut(&mut self) -> &mut [A::Item] { + &mut *self + } +} + +impl Extend for TinyVec { + #[inline] + fn extend>(&mut self, iter: T) { + let iter = iter.into_iter(); + let (lower_bound, _) = iter.size_hint(); + self.reserve(lower_bound); + + let a = match self { + TinyVec::Heap(h) => return h.extend(iter), + TinyVec::Inline(a) => a, + }; + + let mut iter = a.fill(iter); + let maybe = iter.next(); + + let surely = match maybe { + Some(x) => x, + None => return, + }; + + let mut v = a.drain_to_vec_and_reserve(a.len()); + v.push(surely); + v.extend(iter); + *self = TinyVec::Heap(v); + } +} + +impl From> for TinyVec { + #[inline(always)] + #[must_use] + fn from(arr: ArrayVec) -> Self { + TinyVec::Inline(arr) + } +} + +impl From for TinyVec { + #[inline] + fn from(array: A) -> Self { + TinyVec::Inline(ArrayVec::from(array)) + } +} + +impl From<&'_ [T]> for TinyVec +where + T: Clone + Default, + A: Array, +{ + #[inline] + #[must_use] + fn from(slice: &[T]) -> Self { + if let Ok(arr) = ArrayVec::try_from(slice) { + TinyVec::Inline(arr) + } else { + TinyVec::Heap(slice.into()) + } + } +} + +impl From<&'_ mut [T]> for TinyVec +where + T: Clone + Default, + A: Array, +{ + #[inline] + #[must_use] + fn from(slice: &mut [T]) -> Self { + Self::from(&*slice) + } +} + +impl FromIterator for TinyVec { + #[inline] + #[must_use] + fn from_iter>(iter: T) -> Self { + let mut av = Self::default(); + av.extend(iter); + av + } +} + +impl Into> for TinyVec { + /// Converts a `TinyVec` into a `Vec`. + /// + /// ## Examples + /// + /// ### Inline to Vec + /// + /// For `TinyVec::Inline(_)`, + /// `.into()` **does not** offer a performance advantage over `.to_vec()`. + /// + /// ``` + /// use core::mem::size_of_val as mem_size_of; + /// use tinyvec::TinyVec; + /// + /// let v = TinyVec::from([0u8; 128]); + /// assert_eq!(mem_size_of(&v), 136); + /// + /// let vec: Vec<_> = v.into(); + /// assert_eq!(mem_size_of(&vec), 24); + /// ``` + /// + /// ### Heap into Vec + /// + /// For `TinyVec::Heap(vec_data)`, + /// `.into()` will take `vec_data` without heap reallocation. + /// + /// ``` + /// use core::{ + /// any::type_name_of_val as type_of, mem::size_of_val as mem_size_of, + /// }; + /// use tinyvec::TinyVec; + /// + /// const fn from_heap(owned: Vec) -> TinyVec<[T; 1]> { + /// TinyVec::Heap(owned) + /// } + /// + /// let v = from_heap(vec![0u8; 128]); + /// assert_eq!(v.len(), 128); + /// assert_eq!(mem_size_of(&v), 24); + /// assert!(type_of(&v).ends_with("TinyVec<[u8; 1]>")); + /// + /// let vec: Vec<_> = v.into(); + /// assert_eq!(mem_size_of(&vec), 24); + /// assert!(type_of(&vec).ends_with("Vec")); + /// ``` + #[inline] + #[must_use] + fn into(self) -> Vec { + match self { + Self::Heap(inner) => inner, + Self::Inline(mut inner) => inner.drain_to_vec(), + } + } +} + +/// Iterator for consuming an `TinyVec` and returning owned elements. +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub enum TinyVecIterator { + #[allow(missing_docs)] + Inline(ArrayVecIterator), + #[allow(missing_docs)] + Heap(alloc::vec::IntoIter), +} + +impl TinyVecIterator { + impl_mirrored! { + type Mirror = TinyVecIterator; + /// Returns the remaining items of this iterator as a slice. + #[inline] + #[must_use] + pub fn as_slice(self: &Self) -> &[A::Item]; + } +} + +impl FusedIterator for TinyVecIterator {} + +impl Iterator for TinyVecIterator { + type Item = A::Item; + + impl_mirrored! { + type Mirror = TinyVecIterator; + + #[inline] + fn next(self: &mut Self) -> Option; + + #[inline(always)] + #[must_use] + fn size_hint(self: &Self) -> (usize, Option); + + #[inline(always)] + fn count(self: Self) -> usize; + + #[inline] + fn last(self: Self) -> Option; + + #[inline] + fn nth(self: &mut Self, n: usize) -> Option; + } +} + +impl DoubleEndedIterator for TinyVecIterator { + impl_mirrored! { + type Mirror = TinyVecIterator; + + #[inline] + fn next_back(self: &mut Self) -> Option; + + #[inline] + fn nth_back(self: &mut Self, n: usize) -> Option; + } +} + +impl ExactSizeIterator for TinyVecIterator { + impl_mirrored! { + type Mirror = TinyVecIterator; + #[inline] + fn len(self: &Self) -> usize; + } +} + +impl Debug for TinyVecIterator +where + A::Item: Debug, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish() + } +} + +impl IntoIterator for TinyVec { + type Item = A::Item; + type IntoIter = TinyVecIterator; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + match self { + TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()), + TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()), + } + } +} + +impl<'a, A: Array> IntoIterator for &'a mut TinyVec { + type Item = &'a mut A::Item; + type IntoIter = core::slice::IterMut<'a, A::Item>; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +impl<'a, A: Array> IntoIterator for &'a TinyVec { + type Item = &'a A::Item; + type IntoIter = core::slice::Iter<'a, A::Item>; + #[inline(always)] + #[must_use] + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl PartialEq for TinyVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &Self) -> bool { + self.as_slice().eq(other.as_slice()) + } +} +impl Eq for TinyVec where A::Item: Eq {} + +impl PartialOrd for TinyVec +where + A::Item: PartialOrd, +{ + #[inline] + #[must_use] + fn partial_cmp(&self, other: &Self) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } +} +impl Ord for TinyVec +where + A::Item: Ord, +{ + #[inline] + #[must_use] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.as_slice().cmp(other.as_slice()) + } +} + +impl PartialEq<&A> for TinyVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &&A) -> bool { + self.as_slice().eq(other.as_slice()) + } +} + +impl PartialEq<&[A::Item]> for TinyVec +where + A::Item: PartialEq, +{ + #[inline] + #[must_use] + fn eq(&self, other: &&[A::Item]) -> bool { + self.as_slice().eq(*other) + } +} + +impl Hash for TinyVec +where + A::Item: Hash, +{ + #[inline] + fn hash(&self, state: &mut H) { + self.as_slice().hash(state) + } +} + +// // // // // // // // +// Formatting impls +// // // // // // // // + +impl Binary for TinyVec +where + A::Item: Binary, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Binary::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Debug for TinyVec +where + A::Item: Debug, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() && !self.is_empty() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Debug::fmt(elem, f)?; + } + if f.alternate() && !self.is_empty() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Display for TinyVec +where + A::Item: Display, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Display::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl LowerExp for TinyVec +where + A::Item: LowerExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl LowerHex for TinyVec +where + A::Item: LowerHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + LowerHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Octal for TinyVec +where + A::Item: Octal, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Octal::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl Pointer for TinyVec +where + A::Item: Pointer, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + Pointer::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl UpperExp for TinyVec +where + A::Item: UpperExp, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperExp::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +impl UpperHex for TinyVec +where + A::Item: UpperHex, +{ + #[allow(clippy::missing_inline_in_public_items)] + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "[")?; + if f.alternate() { + write!(f, "\n ")?; + } + for (i, elem) in self.iter().enumerate() { + if i > 0 { + write!(f, ",{}", if f.alternate() { "\n " } else { " " })?; + } + UpperHex::fmt(elem, f)?; + } + if f.alternate() { + write!(f, ",\n")?; + } + write!(f, "]") + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] +struct TinyVecVisitor(PhantomData); + +#[cfg(feature = "serde")] +impl<'de, A: Array> Visitor<'de> for TinyVecVisitor +where + A::Item: Deserialize<'de>, +{ + type Value = TinyVec; + + fn expecting( + &self, formatter: &mut core::fmt::Formatter, + ) -> core::fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: S) -> Result + where + S: SeqAccess<'de>, + { + let mut new_tinyvec = match seq.size_hint() { + Some(expected_size) => TinyVec::with_capacity(expected_size), + None => Default::default(), + }; + + while let Some(value) = seq.next_element()? { + new_tinyvec.push(value); + } + + Ok(new_tinyvec) + } +} diff --git a/third_party/rust/tinyvec/tests/arrayvec.rs b/third_party/rust/tinyvec/tests/arrayvec.rs new file mode 100644 index 000000000000..bcde9b58aaa8 --- /dev/null +++ b/third_party/rust/tinyvec/tests/arrayvec.rs @@ -0,0 +1,500 @@ +#![allow(bad_style)] +#![allow(clippy::clone_on_copy)] + +#[cfg(feature = "serde")] +use serde_test::{assert_tokens, Token}; +use std::iter::FromIterator; +use tinyvec::*; + +#[test] +fn test_a_vec() { + let mut expected: ArrayVec<[i32; 4]> = Default::default(); + expected.push(1); + expected.push(2); + expected.push(3); + + let actual = array_vec!(1, 2, 3); + + assert_eq!(expected, actual); + + assert_eq!(array_vec![0u8; 4], array_vec!(0u8, 0u8, 0u8, 0u8)); + assert_eq!(array_vec![0u8; 4], array_vec!([u8; 4] => 0, 0, 0, 0)); + assert_eq!(array_vec![0; 4], array_vec!(0, 0, 0, 0)); + assert_eq!(array_vec![0; 4], array_vec!([u8; 4] => 0, 0, 0, 0)); + + let expected2 = array_vec![1.1; 3]; + let actual2 = array_vec!([f32; 3] => 1.1, 1.1, 1.1); + assert_eq!(expected2, actual2); +} + +#[test] +fn ArrayVec_push_pop() { + let mut av: ArrayVec<[i32; 4]> = Default::default(); + assert_eq!(av.len(), 0); + assert_eq!(av.pop(), None); + + av.push(10_i32); + assert_eq!(av.len(), 1); + assert_eq!(av[0], 10); + assert_eq!(av.pop(), Some(10)); + assert_eq!(av.len(), 0); + assert_eq!(av.pop(), None); + + av.push(10); + av.push(11); + av.push(12); + av.push(13); + assert_eq!(av[0], 10); + assert_eq!(av[1], 11); + assert_eq!(av[2], 12); + assert_eq!(av[3], 13); + assert_eq!(av.len(), 4); + assert_eq!(av.pop(), Some(13)); + assert_eq!(av.len(), 3); + assert_eq!(av.pop(), Some(12)); + assert_eq!(av.len(), 2); + assert_eq!(av.pop(), Some(11)); + assert_eq!(av.len(), 1); + assert_eq!(av.pop(), Some(10)); + assert_eq!(av.len(), 0); + assert_eq!(av.pop(), None); +} + +#[test] +#[should_panic] +fn ArrayVec_push_overflow() { + let mut av: ArrayVec<[i32; 0]> = Default::default(); + av.push(7); +} + +#[test] +fn ArrayVec_formatting() { + // check that we get the comma placement correct + + let mut av: ArrayVec<[i32; 4]> = Default::default(); + assert_eq!(format!("{:?}", av), "[]"); + av.push(10); + assert_eq!(format!("{:?}", av), "[10]"); + av.push(11); + assert_eq!(format!("{:?}", av), "[10, 11]"); + av.push(12); + assert_eq!(format!("{:?}", av), "[10, 11, 12]"); + + // below here just asserts that the impls exist. + + // + let av: ArrayVec<[i32; 4]> = Default::default(); + assert_eq!(format!("{:b}", av), "[]"); + assert_eq!(format!("{:o}", av), "[]"); + assert_eq!(format!("{:x}", av), "[]"); + assert_eq!(format!("{:X}", av), "[]"); + assert_eq!(format!("{}", av), "[]"); + // + let av: ArrayVec<[f32; 4]> = Default::default(); + assert_eq!(format!("{:e}", av), "[]"); + assert_eq!(format!("{:E}", av), "[]"); + // + let av: ArrayVec<[&'static str; 4]> = Default::default(); + assert_eq!(format!("{:p}", av), "[]"); +} + +#[test] +fn ArrayVec_iteration() { + let av = array_vec!([i32; 4] => 10, 11, 12, 13); + + let mut i = av.into_iter(); + assert_eq!(i.next(), Some(10)); + assert_eq!(i.next(), Some(11)); + assert_eq!(i.next(), Some(12)); + assert_eq!(i.next(), Some(13)); + assert_eq!(i.next(), None); + + let av = array_vec!([i32; 4] => 10, 11, 12, 13); + + let mut av2: ArrayVec<[i32; 4]> = av.clone().into_iter().collect(); + assert_eq!(av, av2); + + // IntoIterator for &mut ArrayVec + for x in &mut av2 { + *x = -*x; + } + + // IntoIterator for &ArrayVec + assert!(av.iter().zip(&av2).all(|(&a, &b)| a == -b)); +} + +#[test] +fn ArrayVec_append() { + let mut av = array_vec!([i32; 8] => 1, 2, 3); + let mut av2 = array_vec!([i32; 8] => 4, 5, 6); + // + av.append(&mut av2); + assert_eq!(av.as_slice(), &[1_i32, 2, 3, 4, 5, 6]); + assert_eq!(av2.as_slice(), &[]); +} + +#[test] +fn ArrayVec_remove() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + assert_eq!(av.remove(1), 2); + assert_eq!(&av[..], &[1, 3][..]); +} + +#[test] +#[should_panic] +fn ArrayVec_remove_invalid() { + let mut av: ArrayVec<[i32; 1]> = Default::default(); + av.push(1); + av.remove(1); +} + +#[test] +fn ArrayVec_swap_remove() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + av.push(4); + assert_eq!(av.swap_remove(3), 4); + assert_eq!(&av[..], &[1, 2, 3][..]); + assert_eq!(av.swap_remove(0), 1); + assert_eq!(&av[..], &[3, 2][..]); + assert_eq!(av.swap_remove(0), 3); + assert_eq!(&av[..], &[2][..]); + assert_eq!(av.swap_remove(0), 2); + assert_eq!(&av[..], &[][..]); +} + +#[test] +fn ArrayVec_drain() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + + assert_eq!(Vec::from_iter(av.clone().drain(..)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().drain(..2)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().drain(..3)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().drain(..=1)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().drain(..=2)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().drain(0..)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().drain(1..)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().drain(0..2)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().drain(0..3)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().drain(1..2)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().drain(1..3)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().drain(0..=1)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().drain(0..=2)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().drain(1..=1)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().drain(1..=2)), vec![2, 3]); +} + +#[test] +fn ArrayVec_splice() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + + // splice returns the same things as drain + assert_eq!(Vec::from_iter(av.clone().splice(.., None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(..3, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(..=2, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0.., None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1.., None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(0..3, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1..2, None)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().splice(1..3, None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(0..=2, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1..=1, None)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().splice(1..=2, None)), vec![2, 3]); + + // splice removes the same things as drain + let mut av2 = av.clone(); + av2.splice(.., None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(..2, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(..3, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(..=1, None); + assert_eq!(av2, array_vec![3]); + let mut av2 = av.clone(); + av2.splice(..=2, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(0.., None); + assert_eq!(av2, array_vec![]); + let mut av2 = av.clone(); + av2.splice(1.., None); + assert_eq!(av2, array_vec![1]); + + let mut av2 = av.clone(); + av2.splice(0..2, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(0..3, None); + assert_eq!(av2, array_vec![]); + let mut av2 = av.clone(); + av2.splice(1..2, None); + assert_eq!(av2, array_vec![1, 3]); + + let mut av2 = av.clone(); + av2.splice(1..3, None); + assert_eq!(av2, array_vec![1]); + + let mut av2 = av.clone(); + av2.splice(0..=1, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(0..=2, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(1..=1, None); + assert_eq!(av2, array_vec![1, 3]); + + let mut av2 = av.clone(); + av2.splice(1..=2, None); + assert_eq!(av2, array_vec![1]); + + // splice adds the elements correctly + let mut av2 = av.clone(); + av2.splice(.., 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(..2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(..3, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(..=1, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(..=2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0.., 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1.., 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0..2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(0..3, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1..2, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(1..3, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0..=1, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(0..=2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1..=1, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(1..=2, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + // splice adds the elements correctly when the replacement is smaller + let mut av2 = av.clone(); + av2.splice(.., Some(4)); + assert_eq!(av2, array_vec![4]); + + let mut av2 = av.clone(); + av2.splice(..2, Some(4)); + assert_eq!(av2, array_vec![4, 3]); + + let mut av2 = av.clone(); + av2.splice(1.., Some(4)); + assert_eq!(av2, array_vec![1, 4]); + + let mut av2 = av.clone(); + av2.splice(1..=1, Some(4)); + assert_eq!(av2, array_vec![1, 4, 3]); +} + +#[test] +fn iter_last_nth() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + av.push(4); + assert_eq!(av.len(), 4); + let mut iter = av.into_iter(); + assert_eq!(iter.next(), Some(1)); + assert_eq!(iter.next(), Some(2)); + assert_eq!(iter.next(), Some(3)); + assert_eq!(iter.next(), Some(4)); + assert_eq!(iter.next(), None); + assert_eq!(iter.last(), None); + + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + + assert_eq!(av.into_iter().next(), Some(1)); +} + +#[test] +#[cfg(feature = "rustc_1_40")] +fn reviter() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + av.push(4); + + let mut iter = av.into_iter(); + + assert_eq!(iter.next(), Some(1)); + assert_eq!(iter.next_back(), Some(4)); + assert_eq!(iter.next(), Some(2)); + assert_eq!(iter.next_back(), Some(3)); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + + let mut av: ArrayVec<[i32; 32]> = Default::default(); + av.extend(0..32); + + let mut iter = av.into_iter(); + + assert_eq!(iter.nth_back(0), Some(31)); + assert_eq!(iter.nth_back(2), Some(28)); + assert_eq!(iter.nth_back(0), Some(27)); + assert_eq!(iter.nth_back(99), None); + assert_eq!(iter.nth_back(99), None); +} + +#[cfg(feature = "serde")] +#[test] +fn ArrayVec_ser_de_empty() { + let tv: ArrayVec<[i32; 0]> = Default::default(); + + assert_tokens(&tv, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); +} + +#[cfg(feature = "serde")] +#[test] +fn ArrayVec_ser_de() { + let mut tv: ArrayVec<[i32; 4]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + tv.push(4); + + assert_tokens( + &tv, + &[ + Token::Seq { len: Some(4) }, + Token::I32(1), + Token::I32(2), + Token::I32(3), + Token::I32(4), + Token::SeqEnd, + ], + ); +} + +#[cfg(feature = "borsh")] +#[test] +fn ArrayVec_borsh_de_empty() { + let tv: ArrayVec<[i32; 0]> = Default::default(); + let buffer = borsh::to_vec(&tv).unwrap(); + let des: ArrayVec<[i32; 0]> = borsh::from_slice(&buffer).unwrap(); + assert_eq!(tv, des); +} + +#[cfg(feature = "borsh")] +#[test] +fn ArrayVec_borsh_de() { + let mut tv: ArrayVec<[i32; 4]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + tv.push(4); + let buffer = borsh::to_vec(&tv).unwrap(); + let des: ArrayVec<[i32; 4]> = borsh::from_slice(&buffer).unwrap(); + assert_eq!(tv, des); +} + +#[test] +fn ArrayVec_try_from_slice() { + use std::convert::TryFrom; + + let nums = [1, 2, 3, 4]; + + let empty: Result, _> = ArrayVec::try_from(&nums[..0]); + assert!(empty.is_ok()); + assert_eq!(empty.unwrap().as_slice(), &[]); + + let fits: Result, _> = ArrayVec::try_from(&nums[..2]); + assert!(fits.is_ok()); + assert_eq!(fits.unwrap().as_slice(), &[1, 2]); + + let does_not_fit: Result, _> = + ArrayVec::try_from(&nums[..4]); + assert!(does_not_fit.is_err()); +} + +#[test] +fn ArrayVec_pretty_debug() { + let arr: [i32; 3] = [1, 2, 3]; + let expect = format!("{:#?}", arr); + + let arr: ArrayVec<[i32; 3]> = array_vec![1, 2, 3]; + let got = format!("{:#?}", arr); + + assert_eq!(got, expect); +} diff --git a/third_party/rust/tinyvec/tests/debugger_visualizer.rs b/third_party/rust/tinyvec/tests/debugger_visualizer.rs new file mode 100644 index 000000000000..de7cf71e1be4 --- /dev/null +++ b/third_party/rust/tinyvec/tests/debugger_visualizer.rs @@ -0,0 +1,91 @@ +use debugger_test::debugger_test; +use tinyvec::*; + +#[inline(never)] +fn __break() { + println!("breakpoint hit"); +} + +#[debugger_test( + debugger = "cdb", + commands = r#" +dx strings +dx inline_tv +dx inline_tv.__0 +g +dx slice_vec +g +dx strings +"#, + expected_statements = r#" +pattern:strings : \{ len=0x3 \} \[Type: tinyvec::arrayvec::ArrayVec >\] +pattern:\[\] \[Type: tinyvec::arrayvec::ArrayVec >\] +pattern:\[len\] : 0x3 \[Type: unsigned short\] +pattern:\[capacity\] : 7 +pattern:\[0\] : "a" \[Type: .*str.*\] +pattern:\[1\] : "b" \[Type: .*str.*\] +pattern:\[2\] : "c" \[Type: .*str.*\] + +inline_tv : Inline [Type: enum2$ > >] + [] [Type: enum2$ > >] + [+0x004] __0 : { len=0x4 } [Type: tinyvec::arrayvec::ArrayVec >] + +inline_tv.__0 : { len=0x4 } [Type: tinyvec::arrayvec::ArrayVec >] + [] [Type: tinyvec::arrayvec::ArrayVec >] + [len] : 0x4 [Type: unsigned short] + [capacity] : 4 + [0] : 1 [Type: i32] + [1] : 2 [Type: i32] + [2] : 3 [Type: i32] + [3] : 4 [Type: i32] + +pattern:slice_vec : \{ len=0x3 \} \[Type: tinyvec::slicevec::SliceVec<.*str.*>\] +pattern:\[\] \[Type: tinyvec::slicevec::SliceVec<.*str.*>\] +pattern:\[len\] : 0x3 \[Type: unsigned __int64\] +pattern:\[0\] : "a" \[Type: .*str.*\] +pattern:\[1\] : "b" \[Type: .*str.*\] +pattern:\[2\] : "d" \[Type: .*str.*\] + +pattern:strings : \{ len=0x6 \} \[Type: tinyvec::arrayvec::ArrayVec >\] +pattern:\[\] \[Type: tinyvec::arrayvec::ArrayVec >\] +pattern:\[len\] : 0x6 \[Type: unsigned short\] +pattern:\[capacity\] : 7 +pattern:\[0\] : "a" \[Type: .*str.*\] +pattern:\[1\] : "b" \[Type: .*str.*\] +pattern:\[2\] : "d" \[Type: .*str.*\] +pattern:\[3\] : "e" \[Type: .*str.*\] +pattern:\[4\] : "f" \[Type: .*str.*\] +pattern:\[5\] : "g" \[Type: .*str.*\] +"# +)] +#[inline(never)] +fn test_debugger_visualizer() { + let mut strings = ArrayVec::<[&str; 7]>::default(); + strings.push("a"); + strings.push("b"); + strings.push("c"); + assert_eq!(["a", "b", "c"], &strings[..]); + + let mut inline_tv = tiny_vec!([i32; 4] => 1, 2, 3); + assert!(inline_tv.is_inline()); + + inline_tv.push(4); + __break(); + + { + let mut slice_vec = SliceVec::from(strings.as_mut_slice()); + assert_eq!(3, slice_vec.capacity()); + assert_eq!("c", slice_vec.remove(2)); + slice_vec.push("d"); + println!("{:?}", slice_vec); + __break(); + + assert_eq!(["a", "b", "d"], &slice_vec[..]); + } + + strings.push("e"); + strings.push("f"); + strings.push("g"); + assert_eq!(["a", "b", "d", "e", "f", "g"], &strings[..]); + __break(); +} diff --git a/third_party/rust/tinyvec/tests/tinyvec.rs b/third_party/rust/tinyvec/tests/tinyvec.rs new file mode 100644 index 000000000000..c934646bb4b1 --- /dev/null +++ b/third_party/rust/tinyvec/tests/tinyvec.rs @@ -0,0 +1,501 @@ +#![cfg(feature = "alloc")] +#![allow(bad_style)] +#![allow(clippy::redundant_clone)] + +#[cfg(feature = "serde")] +use serde_test::{assert_tokens, Token}; +use std::iter::FromIterator; +use tinyvec::*; + +#[test] +fn TinyVec_swap_remove() { + let mut tv: TinyVec<[i32; 10]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + tv.push(4); + assert_eq!(tv.swap_remove(3), 4); + assert_eq!(&tv[..], &[1, 2, 3][..]); + assert_eq!(tv.swap_remove(0), 1); + assert_eq!(&tv[..], &[3, 2][..]); + assert_eq!(tv.swap_remove(0), 3); + assert_eq!(&tv[..], &[2][..]); + assert_eq!(tv.swap_remove(0), 2); + assert_eq!(&tv[..], &[][..]); +} + +#[test] +fn TinyVec_capacity() { + let mut tv: TinyVec<[i32; 1]> = Default::default(); + assert_eq!(tv.capacity(), 1); + tv.move_to_the_heap(); + tv.extend_from_slice(&[1, 2, 3, 4]); + assert_eq!(tv.capacity(), 4); +} + +#[test] +fn TinyVec_drain() { + let mut tv: TinyVec<[i32; 10]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + + assert_eq!(Vec::from_iter(tv.clone().drain(..)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().drain(..2)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().drain(..3)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().drain(..=1)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().drain(..=2)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().drain(0..)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().drain(1..)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().drain(0..2)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().drain(0..3)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().drain(1..2)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().drain(1..3)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().drain(0..=1)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().drain(0..=2)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().drain(1..=1)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().drain(1..=2)), vec![2, 3]); +} + +#[test] +fn TinyVec_splice() { + let mut tv: TinyVec<[i32; 10]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + + // splice returns the same things as drain + assert_eq!(Vec::from_iter(tv.clone().splice(.., None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(..3, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(..=2, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0.., None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1.., None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(0..3, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..2, None)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..3, None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(0..=2, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..=1, None)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..=2, None)), vec![2, 3]); + + // splice removes the same things as drain + let mut tv2 = tv.clone(); + tv2.splice(.., None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(..3, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(..=1, None); + assert_eq!(tv2, tiny_vec![3]); + let mut tv2 = tv.clone(); + tv2.splice(..=2, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(0.., None); + assert_eq!(tv2, tiny_vec![]); + let mut tv2 = tv.clone(); + tv2.splice(1.., None); + assert_eq!(tv2, tiny_vec![1]); + + let mut tv2 = tv.clone(); + tv2.splice(0..2, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..3, None); + assert_eq!(tv2, tiny_vec![]); + let mut tv2 = tv.clone(); + tv2.splice(1..2, None); + assert_eq!(tv2, tiny_vec![1, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..3, None); + assert_eq!(tv2, tiny_vec![1]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=1, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=2, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, None); + assert_eq!(tv2, tiny_vec![1, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=2, None); + assert_eq!(tv2, tiny_vec![1]); + + // splice adds the elements correctly + let mut tv2 = tv.clone(); + tv2.splice(.., 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(..3, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(..=1, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(..=2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0.., 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1.., 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0..2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..3, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1..2, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..3, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=1, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=2, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + // splice adds the elements correctly when the replacement is smaller + let mut tv2 = tv.clone(); + tv2.splice(.., Some(4)); + assert_eq!(tv2, tiny_vec![4]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, Some(4)); + assert_eq!(tv2, tiny_vec![4, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1.., Some(4)); + assert_eq!(tv2, tiny_vec![1, 4]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, Some(4)); + assert_eq!(tv2, tiny_vec![1, 4, 3]); +} + +#[test] +fn TinyVec_resize() { + let mut tv: TinyVec<[i32; 10]> = Default::default(); + tv.resize(20, 5); + assert_eq!(&tv[..], &[5; 20]); +} + +#[test] +fn TinyVec_from_slice_impl() { + let bigger_slice: [u8; 11] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let tinyvec: TinyVec<[u8; 10]> = TinyVec::Heap((&bigger_slice[..]).into()); + assert_eq!(TinyVec::from(&bigger_slice[..]), tinyvec); + + let smaller_slice: [u8; 5] = [0, 1, 2, 3, 4]; + let tinyvec: TinyVec<[u8; 10]> = TinyVec::Inline(ArrayVec::from_array_len( + [0, 1, 2, 3, 4, 0, 0, 0, 0, 0], + 5, + )); + assert_eq!(TinyVec::from(&smaller_slice[..]), tinyvec); + + let same_size: [u8; 4] = [0, 1, 2, 3]; + let tinyvec: TinyVec<[u8; 4]> = + TinyVec::Inline(ArrayVec::from_array_len(same_size, 4)); + assert_eq!(TinyVec::from(&same_size[..]), tinyvec); +} + +#[test] +fn TinyVec_from_array() { + let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]; + let tv = TinyVec::from(array); + assert_eq!(&array, &tv[..]); +} + +#[test] +fn TinyVec_macro() { + let mut expected: TinyVec<[i32; 4]> = Default::default(); + expected.push(1); + expected.push(2); + expected.push(3); + + let actual = tiny_vec!(1, 2, 3); + + assert_eq!(expected, actual); + + assert_eq!(tiny_vec![0u8; 4], tiny_vec!(0u8, 0u8, 0u8, 0u8)); + assert_eq!(tiny_vec![0u8; 4], tiny_vec!([u8; 4] => 0, 0, 0, 0)); + assert_eq!(tiny_vec![0; 4], tiny_vec!(0, 0, 0, 0)); + assert_eq!(tiny_vec![0; 4], tiny_vec!([u8; 4] => 0, 0, 0, 0)); + + let expected2 = tiny_vec![1.1; 3]; + let actual2 = tiny_vec!([f32; 3] => 1.1, 1.1, 1.1); + assert_eq!(expected2, actual2); +} + +#[test] +fn TinyVec_macro_non_copy() { + // must use a variable here to avoid macro shenanigans + let s = String::new(); + let _: TinyVec<[String; 10]> = tiny_vec!([String; 10] => s); +} + +#[test] +fn TinyVec_reserve() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert_eq!(tv.capacity(), 4); + tv.extend_from_slice(&[1, 2]); + assert_eq!(tv.capacity(), 4); + tv.reserve(2); + assert_eq!(tv.capacity(), 4); + tv.reserve(4); + assert!(tv.capacity() >= 6); + tv.extend_from_slice(&[3, 4, 5, 6]); + tv.reserve(4); + assert!(tv.capacity() >= 10); +} + +#[cfg(feature = "rustc_1_57")] +#[test] +fn TinyVec_try_reserve() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert_eq!(tv.capacity(), 4); + tv.extend_from_slice(&[1, 2]); + assert_eq!(tv.capacity(), 4); + assert!(tv.try_reserve(2).is_ok()); + assert_eq!(tv.capacity(), 4); + assert!(tv.try_reserve(4).is_ok()); + assert!(tv.capacity() >= 6); + tv.extend_from_slice(&[3, 4, 5, 6]); + assert!(tv.try_reserve(4).is_ok()); + assert!(tv.capacity() >= 10); +} + +#[test] +fn TinyVec_reserve_exact() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert_eq!(tv.capacity(), 4); + + tv.extend_from_slice(&[1, 2]); + assert_eq!(tv.capacity(), 4); + tv.reserve_exact(2); + assert_eq!(tv.capacity(), 4); + tv.reserve_exact(4); + assert!(tv.capacity() >= 6); + tv.extend_from_slice(&[3, 4, 5, 6]); + tv.reserve_exact(4); + assert!(tv.capacity() >= 10); +} + +#[cfg(feature = "rustc_1_57")] +#[test] +fn TinyVec_try_reserve_exact() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert_eq!(tv.capacity(), 4); + + tv.extend_from_slice(&[1, 2]); + assert_eq!(tv.capacity(), 4); + assert!(tv.try_reserve_exact(2).is_ok()); + assert_eq!(tv.capacity(), 4); + assert!(tv.try_reserve_exact(4).is_ok()); + assert!(tv.capacity() >= 6); + tv.extend_from_slice(&[3, 4, 5, 6]); + assert!(tv.try_reserve_exact(4).is_ok()); + assert!(tv.capacity() >= 10); +} + +#[test] +fn TinyVec_move_to_heap_and_shrink() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert!(tv.is_inline()); + tv.move_to_the_heap(); + assert!(tv.is_heap()); + assert_eq!(tv.capacity(), 0); + + tv.push(1); + tv.shrink_to_fit(); + assert!(tv.is_inline()); + assert_eq!(tv.capacity(), 4); + + tv.move_to_the_heap_and_reserve(3); + assert!(tv.is_heap()); + assert_eq!(tv.capacity(), 4); + tv.extend(2..=4); + assert_eq!(tv.capacity(), 4); + assert_eq!(tv.as_slice(), [1, 2, 3, 4]); +} + +#[cfg(feature = "rustc_1_57")] +#[test] +fn TinyVec_try_move_to_heap_and_shrink() { + let mut tv: TinyVec<[i32; 4]> = Default::default(); + assert!(tv.is_inline()); + assert!(tv.try_move_to_the_heap().is_ok()); + assert!(tv.is_heap()); + assert_eq!(tv.capacity(), 0); + + assert!(tv.try_reserve_exact(1).is_ok()); + assert_eq!(tv.capacity(), 1); + tv.push(1); + tv.shrink_to_fit(); + assert!(tv.is_inline()); + assert_eq!(tv.capacity(), 4); + + assert!(tv.try_move_to_the_heap_and_reserve(3).is_ok()); + assert!(tv.is_heap()); + assert_eq!(tv.capacity(), 4); + tv.extend(2..=4); + assert_eq!(tv.capacity(), 4); + assert_eq!(tv.as_slice(), [1, 2, 3, 4]); +} + +#[cfg(feature = "serde")] +#[test] +fn TinyVec_ser_de_empty() { + let tv: TinyVec<[i32; 0]> = tiny_vec![]; + + assert_tokens(&tv, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); +} + +#[cfg(feature = "serde")] +#[test] +fn TinyVec_ser_de() { + let tv: TinyVec<[i32; 4]> = tiny_vec![1, 2, 3, 4]; + + assert_tokens( + &tv, + &[ + Token::Seq { len: Some(4) }, + Token::I32(1), + Token::I32(2), + Token::I32(3), + Token::I32(4), + Token::SeqEnd, + ], + ); +} + +#[cfg(feature = "serde")] +#[test] +fn TinyVec_ser_de_heap() { + let mut tv: TinyVec<[i32; 4]> = tiny_vec![1, 2, 3, 4]; + tv.move_to_the_heap(); + + assert_tokens( + &tv, + &[ + Token::Seq { len: Some(4) }, + Token::I32(1), + Token::I32(2), + Token::I32(3), + Token::I32(4), + Token::SeqEnd, + ], + ); +} + +#[cfg(feature = "borsh")] +#[test] +fn TinyVec_borsh_de_empty() { + let tv: ArrayVec<[i32; 0]> = Default::default(); + let buffer = borsh::to_vec(&tv).unwrap(); + let des: ArrayVec<[i32; 0]> = borsh::from_slice(&buffer).unwrap(); + assert_eq!(tv, des); +} + +#[cfg(feature = "borsh")] +#[test] +fn TinyVec_borsh_de() { + let mut tv: ArrayVec<[i32; 4]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + tv.push(4); + let buffer = borsh::to_vec(&tv).unwrap(); + let des: ArrayVec<[i32; 4]> = borsh::from_slice(&buffer).unwrap(); + assert_eq!(tv, des); +} + +#[cfg(feature = "borsh")] +#[test] +fn TinyVec_borsh_de_heap() { + let mut tv: TinyVec<[i32; 4]> = tiny_vec![1, 2, 3, 4]; + tv.move_to_the_heap(); + + let buffer = borsh::to_vec(&tv).unwrap(); + let des: TinyVec<[i32; 4]> = borsh::from_slice(&buffer).unwrap(); + assert_eq!(tv, des); +} + +#[test] +fn TinyVec_pretty_debug() { + let tv: TinyVec<[i32; 6]> = tiny_vec![1, 2, 3]; + let s = format!("{:#?}", tv); + let expected = format!("{:#?}", tv.as_slice()); + + assert_eq!(s, expected); +} + +#[cfg(feature = "std")] +#[test] +fn TinyVec_std_io_write() { + use std::io::Write; + let mut tv: TinyVec<[u8; 3]> = TinyVec::new(); + + tv.write_all(b"foo").ok(); + assert!(tv.is_inline()); + assert_eq!(tv, tiny_vec![b'f', b'o', b'o']); + + tv.write_all(b"bar").ok(); + assert!(tv.is_heap()); + assert_eq!(tv, tiny_vec![b'f', b'o', b'o', b'b', b'a', b'r']); +} diff --git a/third_party/rust/tinyvec_macros/.cargo-checksum.json b/third_party/rust/tinyvec_macros/.cargo-checksum.json new file mode 100644 index 000000000000..1a77eeb118b6 --- /dev/null +++ b/third_party/rust/tinyvec_macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"104cb36d7a1c9f2b345883f74e8d49f6cdfab9b44d00516934cdc1476ed1cc44","LICENSE-APACHE.md":"4f44572785f35152c1fd2eadf565b7e079c0f300b4324f0af653419f9d76b735","LICENSE-MIT.md":"1dd8eca0f83669e75fa119e34fb9e1be9d16e3e9b6368962b8019db6e8ae5f7b","LICENSE-ZLIB.md":"41ace205715d9f19a3214218cc1c01d57c533e02cd0fef7c8e51a49a7fce5ac5","src/lib.rs":"8e79346da033b3441987b45e8d8530dd48441aa5d5addaeec5650ce7a0f64dc0"},"package":"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"} \ No newline at end of file diff --git a/third_party/rust/tinyvec_macros/Cargo.toml b/third_party/rust/tinyvec_macros/Cargo.toml new file mode 100644 index 000000000000..613628666cc0 --- /dev/null +++ b/third_party/rust/tinyvec_macros/Cargo.toml @@ -0,0 +1,19 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "tinyvec_macros" +version = "0.1.1" +authors = ["Soveu "] +description = "Some macros for tiny containers" +license = "MIT OR Apache-2.0 OR Zlib" +repository = "https://github.com/Soveu/tinyvec_macros" diff --git a/third_party/rust/tinyvec_macros/LICENSE-APACHE.md b/third_party/rust/tinyvec_macros/LICENSE-APACHE.md new file mode 100644 index 000000000000..69a59b412c4e --- /dev/null +++ b/third_party/rust/tinyvec_macros/LICENSE-APACHE.md @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor 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, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Tomasz "Soveu" Marx + + 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. + diff --git a/third_party/rust/tinyvec_macros/LICENSE-MIT.md b/third_party/rust/tinyvec_macros/LICENSE-MIT.md new file mode 100644 index 000000000000..4a8554df7c6b --- /dev/null +++ b/third_party/rust/tinyvec_macros/LICENSE-MIT.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Soveu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/rust/tinyvec_macros/LICENSE-ZLIB.md b/third_party/rust/tinyvec_macros/LICENSE-ZLIB.md new file mode 100644 index 000000000000..f43568b03f0c --- /dev/null +++ b/third_party/rust/tinyvec_macros/LICENSE-ZLIB.md @@ -0,0 +1,20 @@ +zlib License + +(C) 2020 Tomasz "Soveu" Marx + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + diff --git a/third_party/rust/tinyvec_macros/src/lib.rs b/third_party/rust/tinyvec_macros/src/lib.rs new file mode 100644 index 000000000000..3c15b19d6366 --- /dev/null +++ b/third_party/rust/tinyvec_macros/src/lib.rs @@ -0,0 +1,25 @@ +#![no_std] +#![forbid(unsafe_code)] + +#[macro_export] +macro_rules! impl_mirrored { + { + type Mirror = $tinyname:ident; + $( + $(#[$attr:meta])* + $v:vis fn $fname:ident ($seif:ident : $seifty:ty $(,$argname:ident : $argtype:ty)*) $(-> $ret:ty)? ; + )* + } => { + $( + $(#[$attr])* + #[inline(always)] + $v fn $fname($seif : $seifty, $($argname: $argtype),*) $(-> $ret)? { + match $seif { + $tinyname::Inline(i) => i.$fname($($argname),*), + $tinyname::Heap(h) => h.$fname($($argname),*), + } + } + )* + }; +} + diff --git a/third_party/rust/unicode-normalization/.cargo-checksum.json b/third_party/rust/unicode-normalization/.cargo-checksum.json new file mode 100644 index 000000000000..868d6f070aa0 --- /dev/null +++ b/third_party/rust/unicode-normalization/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"c9b3a7c693bc221578c150ca0f889cb42a301b09258a33d42d5a2541104534e3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"5e6af58a3100ef18063422cb2fdf70afac62b5d60d828c6cde6344236d795be9","benches/bench.rs":"2c756c3a084c2ffc740988373fbc01a0333f7e85692ef547cac5ac592bed3024","scripts/unicode.py":"199ae07668c2f9c14b978cda56ab2d5deb0e4b819a3b7abba19bbfe10b1e49df","src/__test_api.rs":"4ca9e8f342dee364d0ca82f80504051b9d7c88fb6726bbe2683898ed0b919dfa","src/decompose.rs":"87bbc8e5814d79613804f1684f0f1fc572878ee31620f1857184509a6619f802","src/lib.rs":"ac4346617ee1f046a7d107ad50ecd928f96f5b1a25c45a1bc912a2d7b760c19f","src/lookups.rs":"962f9909b32e02b8a2a05836135d9cd39bb1ce01f7c659de99cbd8a3a3c78574","src/normalize.rs":"e6bb470ed410399f967b8eed63b161a93930520cf75f04a1d34b3d0aa458fbb6","src/perfect_hash.rs":"400c84e2f467f61bd55d55d08672da6a9ad7a57c938ce5d0c701a6994b1b273b","src/quick_check.rs":"eea209153e6d6b6ff242bc0df10678be2513a6440214bfdf1889321f9657d6d7","src/recompose.rs":"30746c36c1f2929a7b89f2771d63fc857b5d57a87934c661d82c5649ff0cf391","src/replace.rs":"33edf2301d3ec56fc12f48c9e60d6b23ada82c6ffa7e4230ceb744db3fa62ba1","src/stream_safe.rs":"5be52c38cf18f8dae33b84602c6e8c5785f531d598185bbdfac9b05696e60a2d","src/tables.rs":"69a0faad67afe03146d80ff5b2d889d1898cbfe8f7677a24f012148f6fd27348","src/test.rs":"8af1c74989355970cc150075f0c8517bb061caeb46a456458483fe5ef661dc89"},"package":"5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"} \ No newline at end of file diff --git a/third_party/rust/unicode-normalization/COPYRIGHT b/third_party/rust/unicode-normalization/COPYRIGHT new file mode 100644 index 000000000000..b286ec16abbb --- /dev/null +++ b/third_party/rust/unicode-normalization/COPYRIGHT @@ -0,0 +1,7 @@ +Licensed under the Apache License, Version 2.0 + or the MIT +license , +at your option. All files in the project carrying such +notice may not be copied, modified, or distributed except +according to those terms. diff --git a/third_party/rust/unicode-normalization/Cargo.toml b/third_party/rust/unicode-normalization/Cargo.toml new file mode 100644 index 000000000000..049b8145def9 --- /dev/null +++ b/third_party/rust/unicode-normalization/Cargo.toml @@ -0,0 +1,66 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.36" +name = "unicode-normalization" +version = "0.1.24" +authors = [ + "kwantam ", + "Manish Goregaokar ", +] +build = false +exclude = [ + "target/*", + "Cargo.lock", + "scripts/tmp", + "*.txt", + "tests/*", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = """ +This crate provides functions for normalization of +Unicode strings, including Canonical and Compatible +Decomposition and Recomposition, as described in +Unicode Standard Annex #15. +""" +homepage = "https://github.com/unicode-rs/unicode-normalization" +documentation = "https://docs.rs/unicode-normalization/" +readme = "README.md" +keywords = [ + "text", + "unicode", + "normalization", + "decomposition", + "recomposition", +] +license = "MIT/Apache-2.0" +repository = "https://github.com/unicode-rs/unicode-normalization" + +[lib] +name = "unicode_normalization" +path = "src/lib.rs" + +[[bench]] +name = "bench" +path = "benches/bench.rs" + +[dependencies.tinyvec] +version = "1" +features = ["alloc"] + +[features] +default = ["std"] +std = [] diff --git a/third_party/rust/unicode-normalization/LICENSE-APACHE b/third_party/rust/unicode-normalization/LICENSE-APACHE new file mode 100644 index 000000000000..16fe87b06e80 --- /dev/null +++ b/third_party/rust/unicode-normalization/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor 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, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +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. diff --git a/third_party/rust/unicode-normalization/LICENSE-MIT b/third_party/rust/unicode-normalization/LICENSE-MIT new file mode 100644 index 000000000000..e69282e381bc --- /dev/null +++ b/third_party/rust/unicode-normalization/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2015 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/unicode-normalization/README.md b/third_party/rust/unicode-normalization/README.md new file mode 100644 index 000000000000..7d10e4dacb7a --- /dev/null +++ b/third_party/rust/unicode-normalization/README.md @@ -0,0 +1,39 @@ +# unicode-normalization + +[![Build Status](https://travis-ci.org/unicode-rs/unicode-normalization.svg)](https://travis-ci.org/unicode-rs/unicode-normalization) +[![Docs](https://docs.rs/unicode-normalization/badge.svg)](https://docs.rs/unicode-normalization/) + +Unicode character composition and decomposition utilities +as described in +[Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/). + +This crate requires Rust 1.36+. + +```rust +extern crate unicode_normalization; + +use unicode_normalization::char::compose; +use unicode_normalization::UnicodeNormalization; + +fn main() { + assert_eq!(compose('A','\u{30a}'), Some('Å')); + + let s = "ÅΩ"; + let c = s.nfc().collect::(); + assert_eq!(c, "ÅΩ"); +} +``` + +## crates.io + +You can use this package in your project by adding the following +to your `Cargo.toml`: + +```toml +[dependencies] +unicode-normalization = "0.1.23" +``` + +## `no_std` + `alloc` support + +This crate is completely `no_std` + `alloc` compatible. This can be enabled by disabling the `std` feature, i.e. specifying `default-features = false` for this crate on your `Cargo.toml`. diff --git a/third_party/rust/unicode-normalization/benches/bench.rs b/third_party/rust/unicode-normalization/benches/bench.rs new file mode 100644 index 000000000000..94c989e472bb --- /dev/null +++ b/third_party/rust/unicode-normalization/benches/bench.rs @@ -0,0 +1,127 @@ +#![feature(test)] + +extern crate test; +extern crate unicode_normalization; + +use std::fs; +use test::Bencher; +use unicode_normalization::UnicodeNormalization; + +const ASCII: &str = "all types of normalized"; +const NFC: &str = "Introducci\u{00f3}n a Unicode.pdf"; +const NFD: &str = "Introduccio\u{0301}n a Unicode.pdf"; + +#[bench] +fn bench_is_nfc_ascii(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc(ASCII)); +} + +#[bench] +fn bench_is_nfc_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc(NFC)); +} + +#[bench] +fn bench_is_nfc_not_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc(NFD)); +} + +#[bench] +fn bench_is_nfd_ascii(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd(ASCII)); +} + +#[bench] +fn bench_is_nfd_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd(NFD)); +} + +#[bench] +fn bench_is_nfd_not_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd(NFC)); +} + +#[bench] +fn bench_is_nfc_stream_safe_ascii(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc_stream_safe(ASCII)); +} + +#[bench] +fn bench_is_nfc_stream_safe_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc_stream_safe(NFC)); +} + +#[bench] +fn bench_is_nfc_stream_safe_not_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfc_stream_safe(NFD)); +} + +#[bench] +fn bench_is_nfd_stream_safe_ascii(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd_stream_safe(ASCII)); +} + +#[bench] +fn bench_is_nfd_stream_safe_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd_stream_safe(NFD)); +} + +#[bench] +fn bench_is_nfd_stream_safe_not_normalized(b: &mut Bencher) { + b.iter(|| unicode_normalization::is_nfd_stream_safe(NFC)); +} + +#[bench] +fn bench_nfc_ascii(b: &mut Bencher) { + b.iter(|| ASCII.nfc().count()); +} + +#[bench] +fn bench_nfd_ascii(b: &mut Bencher) { + b.iter(|| ASCII.nfd().count()); +} + +#[bench] +fn bench_nfc_long(b: &mut Bencher) { + let long = fs::read_to_string("benches/long.txt").unwrap(); + b.iter(|| long.nfc().count()); +} + +#[bench] +fn bench_nfd_long(b: &mut Bencher) { + let long = fs::read_to_string("benches/long.txt").unwrap(); + b.iter(|| long.nfd().count()); +} + +#[bench] +fn bench_nfkc_ascii(b: &mut Bencher) { + b.iter(|| ASCII.nfkc().count()); +} + +#[bench] +fn bench_nfkd_ascii(b: &mut Bencher) { + b.iter(|| ASCII.nfkd().count()); +} + +#[bench] +fn bench_nfkc_long(b: &mut Bencher) { + let long = fs::read_to_string("benches/long.txt").unwrap(); + b.iter(|| long.nfkc().count()); +} + +#[bench] +fn bench_nfkd_long(b: &mut Bencher) { + let long = fs::read_to_string("benches/long.txt").unwrap(); + b.iter(|| long.nfkd().count()); +} + +#[bench] +fn bench_streamsafe_ascii(b: &mut Bencher) { + b.iter(|| ASCII.stream_safe().count()); +} + +#[bench] +fn bench_streamsafe_adversarial(b: &mut Bencher) { + let s = "bo\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{032e}oom"; + b.iter(|| s.stream_safe().count()); +} diff --git a/third_party/rust/unicode-normalization/scripts/unicode.py b/third_party/rust/unicode-normalization/scripts/unicode.py new file mode 100755 index 000000000000..d9bb69cf60f8 --- /dev/null +++ b/third_party/rust/unicode-normalization/scripts/unicode.py @@ -0,0 +1,617 @@ +#!/usr/bin/env python +# +# Copyright 2011-2018 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# This script uses the following Unicode tables: +# - DerivedNormalizationProps.txt +# - NormalizationTest.txt +# - UnicodeData.txt +# - StandardizedVariants.txt +# +# Since this should not require frequent updates, we just store this +# out-of-line and check the tables.rs and normalization_tests.rs files into git. +import collections +import urllib.request +from itertools import batched + +UNICODE_VERSION = "16.0.0" +UCD_URL = "https://www.unicode.org/Public/%s/ucd/" % UNICODE_VERSION + +PREAMBLE = """// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// NOTE: The following code was generated by "scripts/unicode.py", do not edit directly + +#![allow(missing_docs)] +""" + +NormalizationTest = collections.namedtuple( + "NormalizationTest", + ["source", "nfc", "nfd", "nfkc", "nfkd"], +) + +# Mapping taken from Table 12 from: +# http://www.unicode.org/reports/tr44/#General_Category_Values +expanded_categories = { + 'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'], + 'Lm': ['L'], 'Lo': ['L'], + 'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'], + 'Nd': ['N'], 'Nl': ['N'], 'No': ['No'], + 'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'], + 'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'], + 'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'], + 'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'], + 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'], +} + +# Constants from Unicode 9.0.0 Section 3.12 Conjoining Jamo Behavior +# http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#M9.32468.Heading.310.Combining.Jamo.Behavior +S_BASE, L_COUNT, V_COUNT, T_COUNT = 0xAC00, 19, 21, 28 +S_COUNT = L_COUNT * V_COUNT * T_COUNT + +class UnicodeData(object): + def __init__(self): + self._load_unicode_data() + self.norm_props = self._load_norm_props() + self.norm_tests = self._load_norm_tests() + + self.canon_comp = self._compute_canonical_comp() + self.canon_fully_decomp, self.compat_fully_decomp = self._compute_fully_decomposed() + + self.cjk_compat_variants_fully_decomp = {} + self._load_cjk_compat_ideograph_variants() + + def stats(name, table): + count = sum(len(v) for v in table.values()) + print("%s: %d chars => %d decomposed chars" % (name, len(table), count)) + + print("Decomposition table stats:") + stats("Canonical decomp", self.canon_decomp) + stats("Compatible decomp", self.compat_decomp) + stats("Canonical fully decomp", self.canon_fully_decomp) + stats("Compatible fully decomp", self.compat_fully_decomp) + stats("CJK Compat Variants fully decomp", self.cjk_compat_variants_fully_decomp) + + self.ss_leading, self.ss_trailing = self._compute_stream_safe_tables() + + def _fetch(self, filename): + resp = urllib.request.urlopen(UCD_URL + filename) + return resp.read().decode('utf-8') + + def _load_unicode_data(self): + self.name_to_char_int = {} + self.combining_classes = {} + self.compat_decomp = {} + self.canon_decomp = {} + self.general_category_mark = [] + self.general_category_public_assigned = [] + + assigned_start = 0; + prev_char_int = -1; + prev_name = ""; + + for line in self._fetch("UnicodeData.txt").splitlines(): + # See ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html + pieces = line.split(';') + assert len(pieces) == 15 + char, name, category, cc, decomp = pieces[0], pieces[1], pieces[2], pieces[3], pieces[5] + char_int = int(char, 16) + + name = pieces[1].strip() + self.name_to_char_int[name] = char_int + + if cc != '0': + self.combining_classes[char_int] = cc + + if decomp.startswith('<'): + self.compat_decomp[char_int] = [int(c, 16) for c in decomp.split()[1:]] + elif decomp != '': + self.canon_decomp[char_int] = [int(c, 16) for c in decomp.split()] + + if category == 'M' or 'M' in expanded_categories.get(category, []): + self.general_category_mark.append(char_int) + + assert category != 'Cn', "Unexpected: Unassigned codepoint in UnicodeData.txt" + if category not in ['Co', 'Cs']: + if char_int != prev_char_int + 1 and not is_first_and_last(prev_name, name): + self.general_category_public_assigned.append((assigned_start, prev_char_int)) + assigned_start = char_int + prev_char_int = char_int + prev_name = name; + + self.general_category_public_assigned.append((assigned_start, prev_char_int)) + + def _load_cjk_compat_ideograph_variants(self): + for line in self._fetch("StandardizedVariants.txt").splitlines(): + strip_comments = line.split('#', 1)[0].strip() + if not strip_comments: + continue + + variation_sequence, description, differences = strip_comments.split(';') + description = description.strip() + + # Don't use variations that only apply in particular shaping environments. + if differences: + continue + + # Look for entries where the description field is a codepoint name. + if description not in self.name_to_char_int: + continue + + # Only consider the CJK Compatibility Ideographs. + if not description.startswith('CJK COMPATIBILITY IDEOGRAPH-'): + continue + + char_int = self.name_to_char_int[description] + + assert not char_int in self.combining_classes, "Unexpected: CJK compat variant with a combining class" + assert not char_int in self.compat_decomp, "Unexpected: CJK compat variant and compatibility decomposition" + assert len(self.canon_decomp[char_int]) == 1, "Unexpected: CJK compat variant and non-singleton canonical decomposition" + # If we ever need to handle Hangul here, we'll need to handle it separately. + assert not (S_BASE <= char_int < S_BASE + S_COUNT) + + cjk_compat_variant_parts = [int(c, 16) for c in variation_sequence.split()] + for c in cjk_compat_variant_parts: + assert not c in self.canon_decomp, "Unexpected: CJK compat variant is unnormalized (canon)" + assert not c in self.compat_decomp, "Unexpected: CJK compat variant is unnormalized (compat)" + self.cjk_compat_variants_fully_decomp[char_int] = cjk_compat_variant_parts + + def _load_norm_props(self): + props = collections.defaultdict(list) + + for line in self._fetch("DerivedNormalizationProps.txt").splitlines(): + (prop_data, _, _) = line.partition("#") + prop_pieces = prop_data.split(";") + + if len(prop_pieces) < 2: + continue + + assert len(prop_pieces) <= 3 + (low, _, high) = prop_pieces[0].strip().partition("..") + + prop = prop_pieces[1].strip() + + data = None + if len(prop_pieces) == 3: + data = prop_pieces[2].strip() + + props[prop].append((low, high, data)) + + return props + + def _load_norm_tests(self): + tests = [] + for line in self._fetch("NormalizationTest.txt").splitlines(): + (test_data, _, _) = line.partition("#") + test_pieces = test_data.split(";") + + if len(test_pieces) < 5: + continue + + source, nfc, nfd, nfkc, nfkd = [[c.strip() for c in p.split()] for p in test_pieces[:5]] + tests.append(NormalizationTest(source, nfc, nfd, nfkc, nfkd)) + + return tests + + def _compute_canonical_comp(self): + canon_comp = {} + comp_exclusions = [ + (int(low, 16), int(high or low, 16)) + for low, high, _ in self.norm_props["Full_Composition_Exclusion"] + ] + for char_int, decomp in self.canon_decomp.items(): + if any(lo <= char_int <= hi for lo, hi in comp_exclusions): + continue + + assert len(decomp) == 2 + assert (decomp[0], decomp[1]) not in canon_comp + canon_comp[(decomp[0], decomp[1])] = char_int + + return canon_comp + + def _compute_fully_decomposed(self): + """ + Even though the decomposition algorithm is recursive, it is possible + to precompute the recursion at table generation time with modest + increase to the table size. Then, for these precomputed tables, we + note that 1) compatible decomposition is a subset of canonical + decomposition and 2) they mostly agree on their intersection. + Therefore, we don't store entries in the compatible table for + characters that decompose the same way under canonical decomposition. + + Decomposition table stats: + Canonical decomp: 2060 chars => 3085 decomposed chars + Compatible decomp: 3662 chars => 5440 decomposed chars + Canonical fully decomp: 2060 chars => 3404 decomposed chars + Compatible fully decomp: 3678 chars => 5599 decomposed chars + + The upshot is that decomposition code is very simple and easy to inline + at mild code size cost. + """ + def _decompose(char_int, compatible): + # 7-bit ASCII never decomposes + if char_int <= 0x7f: + yield char_int + return + + # Assert that we're handling Hangul separately. + assert not (S_BASE <= char_int < S_BASE + S_COUNT) + + decomp = self.canon_decomp.get(char_int) + if decomp is not None: + for decomposed_ch in decomp: + for fully_decomposed_ch in _decompose(decomposed_ch, compatible): + yield fully_decomposed_ch + return + + if compatible and char_int in self.compat_decomp: + for decomposed_ch in self.compat_decomp[char_int]: + for fully_decomposed_ch in _decompose(decomposed_ch, compatible): + yield fully_decomposed_ch + return + + yield char_int + return + + end_codepoint = max( + max(self.canon_decomp.keys()), + max(self.compat_decomp.keys()), + ) + + canon_fully_decomp = {} + compat_fully_decomp = {} + + for char_int in range(0, end_codepoint + 1): + # Always skip Hangul, since it's more efficient to represent its + # decomposition programmatically. + if S_BASE <= char_int < S_BASE + S_COUNT: + continue + + canon = list(_decompose(char_int, False)) + if not (len(canon) == 1 and canon[0] == char_int): + canon_fully_decomp[char_int] = canon + + compat = list(_decompose(char_int, True)) + if not (len(compat) == 1 and compat[0] == char_int): + compat_fully_decomp[char_int] = compat + + # Since canon_fully_decomp is a subset of compat_fully_decomp, we don't + # need to store their overlap when they agree. When they don't agree, + # store the decomposition in the compatibility table since we'll check + # that first when normalizing to NFKD. + assert set(canon_fully_decomp) <= set(compat_fully_decomp) + + for ch in set(canon_fully_decomp) & set(compat_fully_decomp): + if canon_fully_decomp[ch] == compat_fully_decomp[ch]: + del compat_fully_decomp[ch] + + return canon_fully_decomp, compat_fully_decomp + + def _compute_stream_safe_tables(self): + """ + To make a text stream-safe with the Stream-Safe Text Process (UAX15-D4), + we need to be able to know the number of contiguous non-starters *after* + applying compatibility decomposition to each character. + + We can do this incrementally by computing the number of leading and + trailing non-starters for each character's compatibility decomposition + with the following rules: + + 1) If a character is not affected by compatibility decomposition, look + up its canonical combining class to find out if it's a non-starter. + 2) All Hangul characters are starters, even under decomposition. + 3) Otherwise, very few decomposing characters have a nonzero count + of leading or trailing non-starters, so store these characters + with their associated counts in a separate table. + """ + leading_nonstarters = {} + trailing_nonstarters = {} + + for c in set(self.canon_fully_decomp) | set(self.compat_fully_decomp): + decomposed = self.compat_fully_decomp.get(c) or self.canon_fully_decomp[c] + + num_leading = 0 + for d in decomposed: + if d not in self.combining_classes: + break + num_leading += 1 + + num_trailing = 0 + for d in reversed(decomposed): + if d not in self.combining_classes: + break + num_trailing += 1 + + if num_leading > 0: + leading_nonstarters[c] = num_leading + if num_trailing > 0: + trailing_nonstarters[c] = num_trailing + + return leading_nonstarters, trailing_nonstarters + +hexify = lambda c: '{:04X}'.format(c) + +# Test whether `first` and `last` are corresponding "<..., First>" and +# "<..., Last>" markers. +def is_first_and_last(first, last): + if not first.startswith('<') or not first.endswith(', First>'): + return False + if not last.startswith('<') or not last.endswith(', Last>'): + return False + return first[1:-8] == last[1:-7] + +def gen_mph_data(name, d, kv_type, kv_callback, kv_row_width): + (salt, keys) = minimal_perfect_hash(d) + out.write(f"\npub(crate) const {name.upper()}_SALT: &[u16] = &[\n") + for s_row in batched(salt, 13): + out.write(" ") + for s in s_row: + out.write(f" 0x{s:03X},") + out.write("\n") + out.write("];\n") + out.write(f"pub(crate) const {name.upper()}_KV: &[{kv_type}] = &[\n") + for k_row in batched(keys, kv_row_width): + out.write(" ") + for k in k_row: + out.write(f" {kv_callback(k)},") + out.write("\n") + out.write("];\n") + +def gen_combining_class(combining_classes, out): + gen_mph_data('canonical_combining_class', combining_classes, 'u32', + lambda k: f"0x{int(combining_classes[k]) | (k << 8):07X}", 8) + +def gen_composition_table(canon_comp, out): + table = {} + for (c1, c2), c3 in canon_comp.items(): + if c1 < 0x10000 and c2 < 0x10000: + table[(c1 << 16) | c2] = c3 + (salt, keys) = minimal_perfect_hash(table) + gen_mph_data('COMPOSITION_TABLE', table, '(u32, char)', + lambda k: f"(0x{k:08X}, '\\u{{{table[k]:06X}}}')", 1) + + out.write("pub(crate) fn composition_table_astral(c1: char, c2: char) -> Option {\n") + out.write(" match (c1, c2) {\n") + for (c1, c2), c3 in sorted(canon_comp.items()): + if c1 >= 0x10000 or c2 >= 0x10000: + out.write(" ('\\u{%s}', '\\u{%s}') => Some('\\u{%s}'),\n" % (hexify(c1), hexify(c2), hexify(c3))) + + out.write(" _ => None,\n") + out.write(" }\n") + out.write("}\n") + +def gen_decomposition_tables(canon_decomp, compat_decomp, cjk_compat_variants_decomp, out): + tables = [(canon_decomp, 'canonical'), (compat_decomp, 'compatibility'), (cjk_compat_variants_decomp, 'cjk_compat_variants')] + for table, name in tables: + offsets = {} + offset = 0 + out.write("pub(crate) const %s_DECOMPOSED_CHARS: &[char] = &[\n" % name.upper()) + for k, v in table.items(): + offsets[k] = offset + offset += len(v) + for c in v: + out.write(" '\\u{%s}',\n" % hexify(c)) + # The largest offset must fit in a u16. + assert offset < 65536 + out.write("];\n") + gen_mph_data(name + '_decomposed', table, "(u32, (u16, u16))", + lambda k: f"(0x{k:05X}, (0x{offsets[k]:03X}, 0x{len(table[k]):X}))", 1) + +def gen_qc_match(prop_table, out): + out.write(" match c {\n") + + for low, high, data in prop_table: + assert data in ('N', 'M') + result = "No" if data == 'N' else "Maybe" + if high: + out.write(r" '\u{%s}'..='\u{%s}' => %s," % (low, high, result)) + else: + out.write(r" '\u{%s}' => %s," % (low, result)) + out.write("\n") + + out.write(" _ => Yes,\n") + out.write(" }\n") + +def gen_nfc_qc(prop_tables, out): + out.write("\n#[inline]\n") + out.write("#[allow(ellipsis_inclusive_range_patterns)]\n") + out.write("pub fn qc_nfc(c: char) -> IsNormalized {\n") + gen_qc_match(prop_tables['NFC_QC'], out) + out.write("}\n") + +def gen_nfkc_qc(prop_tables, out): + out.write("#[inline]\n") + out.write("#[allow(ellipsis_inclusive_range_patterns)]\n") + out.write("pub fn qc_nfkc(c: char) -> IsNormalized {\n") + gen_qc_match(prop_tables['NFKC_QC'], out) + out.write("}\n") + +def gen_nfd_qc(prop_tables, out): + out.write("#[inline]\n") + out.write("#[allow(ellipsis_inclusive_range_patterns)]\n") + out.write("pub fn qc_nfd(c: char) -> IsNormalized {\n") + gen_qc_match(prop_tables['NFD_QC'], out) + out.write("}\n") + +def gen_nfkd_qc(prop_tables, out): + out.write("#[inline]\n") + out.write("#[allow(ellipsis_inclusive_range_patterns)]\n") + out.write("pub fn qc_nfkd(c: char) -> IsNormalized {\n") + gen_qc_match(prop_tables['NFKD_QC'], out) + out.write("}\n") + +def gen_combining_mark(general_category_mark, out): + gen_mph_data('combining_mark', general_category_mark, 'u32', + lambda k: '0x{:05X}'.format(k), 10) + +def gen_public_assigned(general_category_public_assigned, out): + # This could be done as a hash but the table is somewhat small. + out.write("#[inline]\n") + out.write("pub fn is_public_assigned(c: char) -> bool {\n") + out.write(" match c {\n") + + start = True + for first, last in general_category_public_assigned: + if start: + out.write(" ") + start = False + else: + out.write("\n | ") + if first == last: + out.write("'\\u{%s}'" % hexify(first)) + else: + out.write("'\\u{%s}'..='\\u{%s}'" % (hexify(first), hexify(last))) + out.write(" => true,\n") + + out.write(" _ => false,\n") + out.write(" }\n") + out.write("}\n") + +def gen_stream_safe(leading, trailing, out): + # This could be done as a hash but the table is very small. + out.write("#[inline]\n") + out.write("pub fn stream_safe_leading_nonstarters(c: char) -> usize {\n") + out.write(" match c {\n") + + for char, num_leading in sorted(leading.items()): + out.write(" '\\u{%s}' => %d,\n" % (hexify(char), num_leading)) + + out.write(" _ => 0,\n") + out.write(" }\n") + out.write("}\n") + + gen_mph_data('trailing_nonstarters', trailing, 'u32', + lambda k: f"0x{int(trailing[k]) | (k << 8):07X}", 8) + +def gen_tests(tests, out): + out.write("""#[derive(Debug)] +pub struct NormalizationTest { + pub source: &'static str, + pub nfc: &'static str, + pub nfd: &'static str, + pub nfkc: &'static str, + pub nfkd: &'static str, +} + +""") + + out.write("pub const NORMALIZATION_TESTS: &[NormalizationTest] = &[\n") + str_literal = lambda s: '"%s"' % "".join("\\u{%s}" % c for c in s) + + for test in tests: + out.write(" NormalizationTest {\n") + out.write(" source: %s,\n" % str_literal(test.source)) + out.write(" nfc: %s,\n" % str_literal(test.nfc)) + out.write(" nfd: %s,\n" % str_literal(test.nfd)) + out.write(" nfkc: %s,\n" % str_literal(test.nfkc)) + out.write(" nfkd: %s,\n" % str_literal(test.nfkd)) + out.write(" },\n") + + out.write("];\n") + +# Guaranteed to be less than n. +def my_hash(x, salt, n): + # This is hash based on the theory that multiplication is efficient + mask_32 = 0xffffffff + y = ((x + salt) * 2654435769) & mask_32 + y ^= (x * 0x31415926) & mask_32 + return (y * n) >> 32 + +# Compute minimal perfect hash function, d can be either a dict or list of keys. +def minimal_perfect_hash(d): + n = len(d) + buckets = dict((h, []) for h in range(n)) + for key in d: + h = my_hash(key, 0, n) + buckets[h].append(key) + bsorted = [(len(buckets[h]), h) for h in range(n)] + bsorted.sort(reverse = True) + claimed = [False] * n + salts = [0] * n + keys = [0] * n + for (bucket_size, h) in bsorted: + # Note: the traditional perfect hashing approach would also special-case + # bucket_size == 1 here and assign any empty slot, rather than iterating + # until rehash finds an empty slot. But we're not doing that so we can + # avoid the branch. + if bucket_size == 0: + break + else: + for salt in range(1, 32768): + rehashes = [my_hash(key, salt, n) for key in buckets[h]] + # Make sure there are no rehash collisions within this bucket. + if all(not claimed[hash] for hash in rehashes): + if len(set(rehashes)) < bucket_size: + continue + salts[h] = salt + for key in buckets[h]: + rehash = my_hash(key, salt, n) + claimed[rehash] = True + keys[rehash] = key + break + if salts[h] == 0: + print("minimal perfect hashing failed") + # Note: if this happens (because of unfortunate data), then there are + # a few things that could be done. First, the hash function could be + # tweaked. Second, the bucket order could be scrambled (especially the + # singletons). Right now, the buckets are sorted, which has the advantage + # of being deterministic. + # + # As a more extreme approach, the singleton bucket optimization could be + # applied (give the direct address for singleton buckets, rather than + # relying on a rehash). That is definitely the more standard approach in + # the minimal perfect hashing literature, but in testing the branch was a + # significant slowdown. + exit(1) + return (salts, keys) + +if __name__ == '__main__': + data = UnicodeData() + with open("tables.rs", "w", newline = "\n") as out: + out.write(PREAMBLE) + out.write("use crate::quick_check::IsNormalized;\n") + out.write("use crate::quick_check::IsNormalized::*;\n") + out.write("\n") + + version = "(%s, %s, %s)" % tuple(UNICODE_VERSION.split(".")) + out.write("#[allow(unused)]\n") + out.write("pub const UNICODE_VERSION: (u8, u8, u8) = %s;\n" % version) + + gen_combining_class(data.combining_classes, out) + + gen_composition_table(data.canon_comp, out) + + gen_decomposition_tables(data.canon_fully_decomp, data.compat_fully_decomp, data.cjk_compat_variants_fully_decomp, out) + + gen_combining_mark(data.general_category_mark, out) + + gen_public_assigned(data.general_category_public_assigned, out) + + gen_nfc_qc(data.norm_props, out) + + gen_nfkc_qc(data.norm_props, out) + + gen_nfd_qc(data.norm_props, out) + + gen_nfkd_qc(data.norm_props, out) + + gen_stream_safe(data.ss_leading, data.ss_trailing, out) + + with open("normalization_tests.rs", "w", newline = "\n") as out: + out.write(PREAMBLE) + gen_tests(data.norm_tests, out) diff --git a/third_party/rust/unicode-normalization/src/__test_api.rs b/third_party/rust/unicode-normalization/src/__test_api.rs new file mode 100644 index 000000000000..6f6f35e16486 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/__test_api.rs @@ -0,0 +1,18 @@ +// This crate comprises hacks and glue required to test private functions from tests/ +// +// Keep this as slim as possible. +// +// If you're caught using this outside this crates tests/, you get to clean up the mess. + +#[cfg(not(feature = "std"))] +use alloc::string::String; + +use crate::stream_safe::StreamSafe; + +pub fn stream_safe(s: &str) -> String { + StreamSafe::new(s.chars()).collect() +} + +pub mod quick_check { + pub use crate::quick_check::*; +} diff --git a/third_party/rust/unicode-normalization/src/decompose.rs b/third_party/rust/unicode-normalization/src/decompose.rs new file mode 100644 index 000000000000..2c73383a0432 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/decompose.rs @@ -0,0 +1,173 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +use core::fmt::{self, Write}; +use core::iter::{Fuse, FusedIterator}; +use core::ops::Range; +use tinyvec::TinyVec; + +#[derive(Clone)] +enum DecompositionType { + Canonical, + Compatible, +} + +/// External iterator for a string decomposition's characters. +#[derive(Clone)] +pub struct Decompositions { + kind: DecompositionType, + iter: Fuse, + + // This buffer stores pairs of (canonical combining class, character), + // pushed onto the end in text order. + // + // It's divided into up to three sections: + // 1) A prefix that is free space; + // 2) "Ready" characters which are sorted and ready to emit on demand; + // 3) A "pending" block which stills needs more characters for us to be able + // to sort in canonical order and is not safe to emit. + buffer: TinyVec<[(u8, char); 4]>, + ready: Range, +} + +impl> Decompositions { + /// Create a new decomposition iterator for canonical decompositions (NFD) + /// + /// Note that this iterator can also be obtained by directly calling [`.nfd()`](crate::UnicodeNormalization::nfd) + /// on the iterator. + #[inline] + pub fn new_canonical(iter: I) -> Decompositions { + Decompositions { + kind: self::DecompositionType::Canonical, + iter: iter.fuse(), + buffer: TinyVec::new(), + ready: 0..0, + } + } + + /// Create a new decomposition iterator for compatability decompositions (NFkD) + /// + /// Note that this iterator can also be obtained by directly calling [`.nfd()`](crate::UnicodeNormalization::nfd) + /// on the iterator. + #[inline] + pub fn new_compatible(iter: I) -> Decompositions { + Decompositions { + kind: self::DecompositionType::Compatible, + iter: iter.fuse(), + buffer: TinyVec::new(), + ready: 0..0, + } + } +} + +impl Decompositions { + #[inline] + fn push_back(&mut self, ch: char) { + let class = super::char::canonical_combining_class(ch); + + if class == 0 { + self.sort_pending(); + self.buffer.push((class, ch)); + self.ready.end = self.buffer.len(); + } else { + self.buffer.push((class, ch)); + } + } + + #[inline] + fn sort_pending(&mut self) { + // NB: `sort_by_key` is stable, so it will preserve the original text's + // order within a combining class. + self.buffer[self.ready.end..].sort_by_key(|k| k.0); + } + + #[inline] + fn reset_buffer(&mut self) { + // Equivalent to `self.buffer.drain(0..self.ready.end)` + // but faster than drain() if the buffer is a SmallVec or TinyVec + let pending = self.buffer.len() - self.ready.end; + for i in 0..pending { + self.buffer[i] = self.buffer[i + self.ready.end]; + } + self.buffer.truncate(pending); + self.ready = 0..0; + } + + #[inline] + fn increment_next_ready(&mut self) { + let next = self.ready.start + 1; + if next == self.ready.end { + self.reset_buffer(); + } else { + self.ready.start = next; + } + } +} + +impl> Iterator for Decompositions { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + while self.ready.end == 0 { + match (self.iter.next(), &self.kind) { + (Some(ch), &DecompositionType::Canonical) => { + super::char::decompose_canonical(ch, |d| self.push_back(d)); + } + (Some(ch), &DecompositionType::Compatible) => { + super::char::decompose_compatible(ch, |d| self.push_back(d)); + } + (None, _) => { + if self.buffer.is_empty() { + return None; + } else { + self.sort_pending(); + self.ready.end = self.buffer.len(); + + // This implementation means that we can call `next` + // on an exhausted iterator; the last outer `next` call + // will result in an inner `next` call. To make this + // safe, we use `fuse`. + break; + } + } + } + } + + // We can assume here that, if `self.ready.end` is greater than zero, + // it's also greater than `self.ready.start`. That's because we only + // increment `self.ready.start` inside `increment_next_ready`, and + // whenever it reaches equality with `self.ready.end`, we reset both + // to zero, maintaining the invariant that: + // self.ready.start < self.ready.end || self.ready.end == self.ready.start == 0 + // + // This less-than-obviously-safe implementation is chosen for performance, + // minimizing the number & complexity of branches in `next` in the common + // case of buffering then unbuffering a single character with each call. + let (_, ch) = self.buffer[self.ready.start]; + self.increment_next_ready(); + Some(ch) + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, _) = self.iter.size_hint(); + (lower, None) + } +} + +impl + FusedIterator> FusedIterator for Decompositions {} + +impl + Clone> fmt::Display for Decompositions { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for c in self.clone() { + f.write_char(c)?; + } + Ok(()) + } +} diff --git a/third_party/rust/unicode-normalization/src/lib.rs b/third_party/rust/unicode-normalization/src/lib.rs new file mode 100644 index 000000000000..6c5e0294b0a3 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/lib.rs @@ -0,0 +1,227 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Unicode character composition and decomposition utilities +//! as described in +//! [Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/). +//! +//! ```rust +//! extern crate unicode_normalization; +//! +//! use unicode_normalization::char::compose; +//! use unicode_normalization::UnicodeNormalization; +//! +//! fn main() { +//! assert_eq!(compose('A','\u{30a}'), Some('Å')); +//! +//! let s = "ÅΩ"; +//! let c = s.nfc().collect::(); +//! assert_eq!(c, "ÅΩ"); +//! } +//! ``` +//! +//! # crates.io +//! +//! You can use this package in your project by adding the following +//! to your `Cargo.toml`: +//! +//! ```toml +//! [dependencies] +//! unicode-normalization = "0.1.20" +//! ``` + +#![deny(missing_docs, unsafe_code)] +#![doc( + html_logo_url = "https://unicode-rs.github.io/unicode-rs_sm.png", + html_favicon_url = "https://unicode-rs.github.io/unicode-rs_sm.png" +)] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(feature = "std")] +extern crate core; + +extern crate tinyvec; + +pub use crate::decompose::Decompositions; +pub use crate::quick_check::{ + is_nfc, is_nfc_quick, is_nfc_stream_safe, is_nfc_stream_safe_quick, is_nfd, is_nfd_quick, + is_nfd_stream_safe, is_nfd_stream_safe_quick, is_nfkc, is_nfkc_quick, is_nfkd, is_nfkd_quick, + IsNormalized, +}; +pub use crate::recompose::Recompositions; +pub use crate::replace::Replacements; +pub use crate::stream_safe::StreamSafe; +pub use crate::tables::UNICODE_VERSION; +use core::{option, str::Chars}; + +mod decompose; +mod lookups; +mod normalize; +mod perfect_hash; +mod quick_check; +mod recompose; +mod replace; +mod stream_safe; +mod tables; + +#[doc(hidden)] +pub mod __test_api; +#[cfg(test)] +mod test; + +/// Methods for composing and decomposing characters. +pub mod char { + pub use crate::normalize::{ + compose, decompose_canonical, decompose_cjk_compat_variants, decompose_compatible, + }; + + pub use crate::lookups::{canonical_combining_class, is_combining_mark}; + + /// Return whether the given character is assigned (`General_Category` != `Unassigned`) + /// and not Private-Use (`General_Category` != `Private_Use`), in the supported version + /// of Unicode. + pub use crate::tables::is_public_assigned; +} + +/// Methods for iterating over strings while applying Unicode normalizations +/// as described in +/// [Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/). +pub trait UnicodeNormalization> { + /// Returns an iterator over the string in Unicode Normalization Form D + /// (canonical decomposition). + fn nfd(self) -> Decompositions; + + /// Returns an iterator over the string in Unicode Normalization Form KD + /// (compatibility decomposition). + fn nfkd(self) -> Decompositions; + + /// An Iterator over the string in Unicode Normalization Form C + /// (canonical decomposition followed by canonical composition). + fn nfc(self) -> Recompositions; + + /// An Iterator over the string in Unicode Normalization Form KC + /// (compatibility decomposition followed by canonical composition). + fn nfkc(self) -> Recompositions; + + /// A transformation which replaces CJK Compatibility Ideograph codepoints + /// with normal forms using Standardized Variation Sequences. This is not + /// part of the canonical or compatibility decomposition algorithms, but + /// performing it before those algorithms produces normalized output which + /// better preserves the intent of the original text. + /// + /// Note that many systems today ignore variation selectors, so these + /// may not immediately help text display as intended, but they at + /// least preserve the information in a standardized form, giving + /// implementations the option to recognize them. + fn cjk_compat_variants(self) -> Replacements; + + /// An Iterator over the string with Conjoining Grapheme Joiner characters + /// inserted according to the Stream-Safe Text Process (UAX15-D4) + fn stream_safe(self) -> StreamSafe; +} + +impl<'a> UnicodeNormalization> for &'a str { + #[inline] + fn nfd(self) -> Decompositions> { + Decompositions::new_canonical(self.chars()) + } + + #[inline] + fn nfkd(self) -> Decompositions> { + Decompositions::new_compatible(self.chars()) + } + + #[inline] + fn nfc(self) -> Recompositions> { + Recompositions::new_canonical(self.chars()) + } + + #[inline] + fn nfkc(self) -> Recompositions> { + Recompositions::new_compatible(self.chars()) + } + + #[inline] + fn cjk_compat_variants(self) -> Replacements> { + replace::new_cjk_compat_variants(self.chars()) + } + + #[inline] + fn stream_safe(self) -> StreamSafe> { + StreamSafe::new(self.chars()) + } +} + +impl UnicodeNormalization> for char { + #[inline] + fn nfd(self) -> Decompositions> { + Decompositions::new_canonical(Some(self).into_iter()) + } + + #[inline] + fn nfkd(self) -> Decompositions> { + Decompositions::new_compatible(Some(self).into_iter()) + } + + #[inline] + fn nfc(self) -> Recompositions> { + Recompositions::new_canonical(Some(self).into_iter()) + } + + #[inline] + fn nfkc(self) -> Recompositions> { + Recompositions::new_compatible(Some(self).into_iter()) + } + + #[inline] + fn cjk_compat_variants(self) -> Replacements> { + replace::new_cjk_compat_variants(Some(self).into_iter()) + } + + #[inline] + fn stream_safe(self) -> StreamSafe> { + StreamSafe::new(Some(self).into_iter()) + } +} + +impl> UnicodeNormalization for I { + #[inline] + fn nfd(self) -> Decompositions { + Decompositions::new_canonical(self) + } + + #[inline] + fn nfkd(self) -> Decompositions { + Decompositions::new_compatible(self) + } + + #[inline] + fn nfc(self) -> Recompositions { + Recompositions::new_canonical(self) + } + + #[inline] + fn nfkc(self) -> Recompositions { + Recompositions::new_compatible(self) + } + + #[inline] + fn cjk_compat_variants(self) -> Replacements { + replace::new_cjk_compat_variants(self) + } + + #[inline] + fn stream_safe(self) -> StreamSafe { + StreamSafe::new(self) + } +} diff --git a/third_party/rust/unicode-normalization/src/lookups.rs b/third_party/rust/unicode-normalization/src/lookups.rs new file mode 100644 index 000000000000..ea7a96c49a08 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/lookups.rs @@ -0,0 +1,138 @@ +// Copyright 2019 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Lookups of unicode properties using minimal perfect hashing. + +use crate::perfect_hash::mph_lookup; +use crate::tables::*; + +/// Look up the canonical combining class for a codepoint. +/// +/// The value returned is as defined in the Unicode Character Database. +pub fn canonical_combining_class(c: char) -> u8 { + mph_lookup( + c.into(), + CANONICAL_COMBINING_CLASS_SALT, + CANONICAL_COMBINING_CLASS_KV, + u8_lookup_fk, + u8_lookup_fv, + 0, + ) +} + +pub(crate) fn composition_table(c1: char, c2: char) -> Option { + if c1 < '\u{10000}' && c2 < '\u{10000}' { + mph_lookup( + (c1 as u32) << 16 | (c2 as u32), + COMPOSITION_TABLE_SALT, + COMPOSITION_TABLE_KV, + pair_lookup_fk, + pair_lookup_fv_opt, + None, + ) + } else { + composition_table_astral(c1, c2) + } +} + +pub(crate) fn canonical_fully_decomposed(c: char) -> Option<&'static [char]> { + mph_lookup( + c.into(), + CANONICAL_DECOMPOSED_SALT, + CANONICAL_DECOMPOSED_KV, + pair_lookup_fk, + pair_lookup_fv_opt, + None, + ) + .map(|(start, len)| &CANONICAL_DECOMPOSED_CHARS[start as usize..][..len as usize]) +} + +pub(crate) fn compatibility_fully_decomposed(c: char) -> Option<&'static [char]> { + mph_lookup( + c.into(), + COMPATIBILITY_DECOMPOSED_SALT, + COMPATIBILITY_DECOMPOSED_KV, + pair_lookup_fk, + pair_lookup_fv_opt, + None, + ) + .map(|(start, len)| &COMPATIBILITY_DECOMPOSED_CHARS[start as usize..][..len as usize]) +} + +pub(crate) fn cjk_compat_variants_fully_decomposed(c: char) -> Option<&'static [char]> { + mph_lookup( + c.into(), + CJK_COMPAT_VARIANTS_DECOMPOSED_SALT, + CJK_COMPAT_VARIANTS_DECOMPOSED_KV, + pair_lookup_fk, + pair_lookup_fv_opt, + None, + ) + .map(|(start, len)| &CJK_COMPAT_VARIANTS_DECOMPOSED_CHARS[start as usize..][..len as usize]) +} + +/// Return whether the given character is a combining mark (`General_Category=Mark`) +pub fn is_combining_mark(c: char) -> bool { + mph_lookup( + c.into(), + COMBINING_MARK_SALT, + COMBINING_MARK_KV, + bool_lookup_fk, + bool_lookup_fv, + false, + ) +} + +pub fn stream_safe_trailing_nonstarters(c: char) -> usize { + mph_lookup( + c.into(), + TRAILING_NONSTARTERS_SALT, + TRAILING_NONSTARTERS_KV, + u8_lookup_fk, + u8_lookup_fv, + 0, + ) as usize +} + +/// Extract the key in a 24 bit key and 8 bit value packed in a u32. +#[inline] +fn u8_lookup_fk(kv: u32) -> u32 { + kv >> 8 +} + +/// Extract the value in a 24 bit key and 8 bit value packed in a u32. +#[inline] +fn u8_lookup_fv(kv: u32) -> u8 { + (kv & 0xff) as u8 +} + +/// Extract the key for a boolean lookup. +#[inline] +fn bool_lookup_fk(kv: u32) -> u32 { + kv +} + +/// Extract the value for a boolean lookup. +#[inline] +fn bool_lookup_fv(_kv: u32) -> bool { + true +} + +/// Extract the key in a pair. +#[inline] +fn pair_lookup_fk(kv: (u32, T)) -> u32 { + kv.0 +} + +/// Extract the value in a pair, returning an option. +#[inline] +fn pair_lookup_fv_opt(kv: (u32, T)) -> Option { + Some(kv.1) +} diff --git a/third_party/rust/unicode-normalization/src/normalize.rs b/third_party/rust/unicode-normalization/src/normalize.rs new file mode 100644 index 000000000000..e59b667ff102 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/normalize.rs @@ -0,0 +1,224 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Functions for computing canonical and compatible decompositions for Unicode characters. +use crate::lookups::{ + canonical_fully_decomposed, cjk_compat_variants_fully_decomposed, + compatibility_fully_decomposed, composition_table, +}; + +use core::char; + +/// Compute canonical Unicode decomposition for character. +/// See [Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/) +/// for more information. +#[inline] +pub fn decompose_canonical(c: char, emit_char: F) +where + F: FnMut(char), +{ + decompose(c, canonical_fully_decomposed, emit_char) +} + +/// Compute canonical or compatible Unicode decomposition for character. +/// See [Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/) +/// for more information. +#[inline] +pub fn decompose_compatible(c: char, emit_char: F) { + let decompose_char = + |c| compatibility_fully_decomposed(c).or_else(|| canonical_fully_decomposed(c)); + decompose(c, decompose_char, emit_char) +} + +/// Compute standard-variation decomposition for character. +/// +/// [Standardized Variation Sequences] are used instead of the standard canonical +/// decompositions, notably for CJK codepoints with singleton canonical decompositions, +/// to avoid losing information. See the +/// [Unicode Variation Sequence FAQ](http://unicode.org/faq/vs.html) and the +/// "Other Enhancements" section of the +/// [Unicode 6.3 Release Summary](https://www.unicode.org/versions/Unicode6.3.0/#Summary) +/// for more information. +#[inline] +pub fn decompose_cjk_compat_variants(c: char, mut emit_char: F) +where + F: FnMut(char), +{ + // 7-bit ASCII never decomposes + if c <= '\x7f' { + emit_char(c); + return; + } + + // Don't perform decomposition for Hangul + + if let Some(decomposed) = cjk_compat_variants_fully_decomposed(c) { + for &d in decomposed { + emit_char(d); + } + return; + } + + // Finally bottom out. + emit_char(c); +} + +#[inline] +#[allow(unsafe_code)] +fn decompose(c: char, decompose_char: D, mut emit_char: F) +where + D: Fn(char) -> Option<&'static [char]>, + F: FnMut(char), +{ + // 7-bit ASCII never decomposes + if c <= '\x7f' { + emit_char(c); + return; + } + + // Perform decomposition for Hangul + if is_hangul_syllable(c) { + // Safety: Hangul Syllables invariant checked by is_hangul_syllable above + unsafe { + decompose_hangul(c, emit_char); + } + return; + } + + if let Some(decomposed) = decompose_char(c) { + for &d in decomposed { + emit_char(d); + } + return; + } + + // Finally bottom out. + emit_char(c); +} + +/// Compose two characters into a single character, if possible. +/// See [Unicode Standard Annex #15](http://www.unicode.org/reports/tr15/) +/// for more information. +pub fn compose(a: char, b: char) -> Option { + compose_hangul(a, b).or_else(|| composition_table(a, b)) +} + +// Constants from Unicode 9.0.0 Section 3.12 Conjoining Jamo Behavior +// http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#M9.32468.Heading.310.Combining.Jamo.Behavior +const S_BASE: u32 = 0xAC00; +const L_BASE: u32 = 0x1100; +const V_BASE: u32 = 0x1161; +const T_BASE: u32 = 0x11A7; +const L_COUNT: u32 = 19; +const V_COUNT: u32 = 21; +const T_COUNT: u32 = 28; +const N_COUNT: u32 = V_COUNT * T_COUNT; +const S_COUNT: u32 = L_COUNT * N_COUNT; + +const S_LAST: u32 = S_BASE + S_COUNT - 1; +const L_LAST: u32 = L_BASE + L_COUNT - 1; +const V_LAST: u32 = V_BASE + V_COUNT - 1; +const T_LAST: u32 = T_BASE + T_COUNT - 1; + +// Composition only occurs for `TPart`s in `U+11A8 ..= U+11C2`, +// i.e. `T_BASE + 1 ..= T_LAST`. +const T_FIRST: u32 = T_BASE + 1; + +// Safety-usable invariant: This ensures that c is a valid Hangul Syllable character (U+AC00..U+D7AF) +pub(crate) fn is_hangul_syllable(c: char) -> bool { + // Safety: This checks the range 0xAC00 (S_BASE) to 0xD7A4 (S_BASE + S_COUNT), upholding the safety-usable invariant + (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) +} + +// Decompose a precomposed Hangul syllable +// Safety: `s` MUST be a valid Hangul Syllable character, between U+AC00..U+D7AF +#[allow(unsafe_code, unused_unsafe)] +#[inline(always)] +unsafe fn decompose_hangul(s: char, mut emit_char: F) +where + F: FnMut(char), +{ + // This will be at most 0x2baf, the size of the Hangul Syllables block + let s_index = s as u32 - S_BASE; + // This will be at most 0x2baf / (21 * 28), 19 + let l_index = s_index / N_COUNT; + unsafe { + // Safety: L_BASE (0x1100) plus at most 19 is still going to be in range for a valid Unicode code point in the BMP (< 0xD800) + emit_char(char::from_u32_unchecked(L_BASE + l_index)); + + // Safety: This will be at most (N_COUNT - 1) / T_COUNT = (V*T - 1) / T, which gives us an upper bound of V_COUNT = 21 + let v_index = (s_index % N_COUNT) / T_COUNT; + // Safety: V_BASE (0x1161) plus at most 21 is still going to be in range for a valid Unicode code point in the BMP (< 0xD800) + emit_char(char::from_u32_unchecked(V_BASE + v_index)); + + // Safety: This will be at most T_COUNT - 1 (27) + let t_index = s_index % T_COUNT; + if t_index > 0 { + // Safety: T_BASE (0x11A7) plus at most 27 is still going to be in range for a valid Unicode code point in the BMP (< 0xD800) + emit_char(char::from_u32_unchecked(T_BASE + t_index)); + } + } +} + +#[inline] +pub(crate) fn hangul_decomposition_length(s: char) -> usize { + let si = s as u32 - S_BASE; + let ti = si % T_COUNT; + if ti > 0 { + 3 + } else { + 2 + } +} + +// Compose a pair of Hangul Jamo +#[allow(unsafe_code)] +#[inline(always)] +#[allow(ellipsis_inclusive_range_patterns)] +fn compose_hangul(a: char, b: char) -> Option { + let (a, b) = (a as u32, b as u32); + match (a, b) { + // Compose a leading consonant and a vowel together into an LV_Syllable + (L_BASE..=L_LAST, V_BASE..=V_LAST) => { + // Safety: based on the above bounds, l_index will be less than or equal to L_COUNT (19) + // and v_index will be <= V_COUNT (21) + let l_index = a - L_BASE; + let v_index = b - V_BASE; + // Safety: This will be <= 19 * (20 * 21) + (21 * 20), which is 8400. + let lv_index = l_index * N_COUNT + v_index * T_COUNT; + // Safety: This is between 0xAC00 and 0xCCD0, which are in range for Hangul Syllables (U+AC00..U+D7AF) and also in range + // for BMP unicode + let s = S_BASE + lv_index; + // Safety: We've verified this is in-range + Some(unsafe { char::from_u32_unchecked(s) }) + } + // Compose an LV_Syllable and a trailing consonant into an LVT_Syllable + (S_BASE..=S_LAST, T_FIRST..=T_LAST) if (a - S_BASE) % T_COUNT == 0 => { + // Safety: a is between 0xAC00 and (0xAC00 + 19 * 21 * 28). b - T_BASE is between 0 and 19. + // Adding a number 0 to 19 to a number that is at largest 0xD7A4 will not go out of bounds to 0xD800 (where the + // surrogates start), so this is safe. + Some(unsafe { char::from_u32_unchecked(a + (b - T_BASE)) }) + } + _ => None, + } +} + +#[cfg(test)] +mod tests { + use super::compose_hangul; + + // Regression test from a bugfix where we were composing an LV_Syllable with + // T_BASE directly. (We should only compose an LV_Syllable with a character + // in the range `T_BASE + 1 ..= T_LAST`.) + #[test] + fn test_hangul_composition() { + assert_eq!(compose_hangul('\u{c8e0}', '\u{11a7}'), None); + } +} diff --git a/third_party/rust/unicode-normalization/src/perfect_hash.rs b/third_party/rust/unicode-normalization/src/perfect_hash.rs new file mode 100644 index 000000000000..3dbc166396b5 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/perfect_hash.rs @@ -0,0 +1,50 @@ +// Copyright 2019 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Support for lookups based on minimal perfect hashing. + +// This function is based on multiplication being fast and is "good enough". Also +// it can share some work between the unsalted and salted versions. +#[inline] +fn my_hash(key: u32, salt: u32, n: usize) -> usize { + let y = key.wrapping_add(salt).wrapping_mul(2654435769); + let y = y ^ key.wrapping_mul(0x31415926); + (((y as u64) * (n as u64)) >> 32) as usize +} + +/// Do a lookup using minimal perfect hashing. +/// +/// The table is stored as a sequence of "salt" values, then a sequence of +/// values that contain packed key/value pairs. The strategy is to hash twice. +/// The first hash retrieves a salt value that makes the second hash unique. +/// The hash function doesn't have to be very good, just good enough that the +/// resulting map is unique. +#[inline] +pub(crate) fn mph_lookup( + x: u32, + salt: &[u16], + kv: &[KV], + fk: FK, + fv: FV, + default: V, +) -> V +where + KV: Copy, + FK: Fn(KV) -> u32, + FV: Fn(KV) -> V, +{ + let s = salt[my_hash(x, 0, salt.len())] as u32; + let key_val = kv[my_hash(x, s, salt.len())]; + if x == fk(key_val) { + fv(key_val) + } else { + default + } +} diff --git a/third_party/rust/unicode-normalization/src/quick_check.rs b/third_party/rust/unicode-normalization/src/quick_check.rs new file mode 100644 index 000000000000..728e341d27be --- /dev/null +++ b/third_party/rust/unicode-normalization/src/quick_check.rs @@ -0,0 +1,190 @@ +use crate::lookups::canonical_combining_class; +use crate::stream_safe; +use crate::tables; +use crate::UnicodeNormalization; + +/// QuickCheck quickly determines if a string is normalized, it can return +/// `Maybe` +/// +/// The QuickCheck algorithm can quickly determine if a text is or isn't +/// normalized without any allocations in many cases, but it has to be able to +/// return `Maybe` when a full decomposition and recomposition is necessary. +#[derive(Debug, Eq, PartialEq)] +pub enum IsNormalized { + /// The text is definitely normalized. + Yes, + /// The text is definitely not normalized. + No, + /// The text may be normalized. + Maybe, +} + +// https://unicode.org/reports/tr15/#Detecting_Normalization_Forms +#[inline] +fn quick_check(s: I, is_allowed: F, stream_safe: bool) -> IsNormalized +where + I: Iterator, + F: Fn(char) -> IsNormalized, +{ + let mut last_cc = 0u8; + let mut nonstarter_count = 0; + let mut result = IsNormalized::Yes; + for ch in s { + // For ASCII we know it's always allowed and a starter + if ch <= '\x7f' { + last_cc = 0; + nonstarter_count = 0; + continue; + } + + // Otherwise, lookup the combining class and QC property + let cc = canonical_combining_class(ch); + if last_cc > cc && cc != 0 { + return IsNormalized::No; + } + match is_allowed(ch) { + IsNormalized::Yes => (), + IsNormalized::No => return IsNormalized::No, + IsNormalized::Maybe => { + result = IsNormalized::Maybe; + } + } + if stream_safe { + let decomp = stream_safe::classify_nonstarters(ch); + + // If we're above `MAX_NONSTARTERS`, we're definitely *not* + // stream-safe normalized. + if nonstarter_count + decomp.leading_nonstarters > stream_safe::MAX_NONSTARTERS { + return IsNormalized::No; + } + if decomp.leading_nonstarters == decomp.decomposition_len { + nonstarter_count += decomp.decomposition_len; + } else { + nonstarter_count = decomp.trailing_nonstarters; + } + } + last_cc = cc; + } + result +} + +/// Quickly check if a string is in NFC, potentially returning +/// `IsNormalized::Maybe` if further checks are necessary. In this case a check +/// like `s.chars().nfc().eq(s.chars())` should suffice. +#[inline] +pub fn is_nfc_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfc, false) +} + +/// Quickly check if a string is in NFKC. +#[inline] +pub fn is_nfkc_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfkc, false) +} + +/// Quickly check if a string is in NFD. +#[inline] +pub fn is_nfd_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfd, false) +} + +/// Quickly check if a string is in NFKD. +#[inline] +pub fn is_nfkd_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfkd, false) +} + +/// Quickly check if a string is Stream-Safe NFC. +#[inline] +pub fn is_nfc_stream_safe_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfc, true) +} + +/// Quickly check if a string is Stream-Safe NFD. +#[inline] +pub fn is_nfd_stream_safe_quick>(s: I) -> IsNormalized { + quick_check(s, tables::qc_nfd, true) +} + +/// Authoritatively check if a string is in NFC. +#[inline] +pub fn is_nfc(s: &str) -> bool { + match is_nfc_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().nfc()), + } +} + +/// Authoritatively check if a string is in NFKC. +#[inline] +pub fn is_nfkc(s: &str) -> bool { + match is_nfkc_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().nfkc()), + } +} + +/// Authoritatively check if a string is in NFD. +#[inline] +pub fn is_nfd(s: &str) -> bool { + match is_nfd_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().nfd()), + } +} + +/// Authoritatively check if a string is in NFKD. +#[inline] +pub fn is_nfkd(s: &str) -> bool { + match is_nfkd_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().nfkd()), + } +} + +/// Authoritatively check if a string is Stream-Safe NFC. +#[inline] +pub fn is_nfc_stream_safe(s: &str) -> bool { + match is_nfc_stream_safe_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().stream_safe().nfc()), + } +} + +/// Authoritatively check if a string is Stream-Safe NFD. +#[inline] +pub fn is_nfd_stream_safe(s: &str) -> bool { + match is_nfd_stream_safe_quick(s.chars()) { + IsNormalized::Yes => true, + IsNormalized::No => false, + IsNormalized::Maybe => s.chars().eq(s.chars().stream_safe().nfd()), + } +} + +#[cfg(test)] +mod tests { + use super::{is_nfc_stream_safe_quick, is_nfd_stream_safe_quick, IsNormalized}; + + #[test] + fn test_stream_safe_nfd() { + let okay = "Da\u{031b}\u{0316}\u{0317}\u{0318}\u{0319}\u{031c}\u{031d}\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{031a}ngerzone"; + assert_eq!(is_nfd_stream_safe_quick(okay.chars()), IsNormalized::Yes); + + let too_much = "Da\u{031b}\u{0316}\u{0317}\u{0318}\u{0319}\u{031c}\u{031d}\u{031e}\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{031a}ngerzone"; + assert_eq!(is_nfd_stream_safe_quick(too_much.chars()), IsNormalized::No); + } + + #[test] + fn test_stream_safe_nfc() { + let okay = "ok\u{e0}\u{031b}\u{0316}\u{0317}\u{0318}\u{0319}\u{031c}\u{031d}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{031a}y"; + assert_eq!(is_nfc_stream_safe_quick(okay.chars()), IsNormalized::Maybe); + + let too_much = "not ok\u{e0}\u{031b}\u{0316}\u{0317}\u{0318}\u{0319}\u{031c}\u{031d}\u{031e}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{031a}y"; + assert_eq!(is_nfc_stream_safe_quick(too_much.chars()), IsNormalized::No); + } +} diff --git a/third_party/rust/unicode-normalization/src/recompose.rs b/third_party/rust/unicode-normalization/src/recompose.rs new file mode 100644 index 000000000000..4effa86119fa --- /dev/null +++ b/third_party/rust/unicode-normalization/src/recompose.rs @@ -0,0 +1,169 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::decompose::Decompositions; +use core::{ + fmt::{self, Write}, + iter::FusedIterator, +}; +use tinyvec::TinyVec; + +#[derive(Clone)] +enum RecompositionState { + Composing, + Purging(usize), + Finished(usize), +} + +/// External iterator for a string recomposition's characters. +#[derive(Clone)] +pub struct Recompositions { + iter: Decompositions, + state: RecompositionState, + buffer: TinyVec<[char; 4]>, + composee: Option, + last_ccc: Option, +} + +impl> Recompositions { + /// Create a new recomposition iterator for canonical compositions (NFC) + /// + /// Note that this iterator can also be obtained by directly calling [`.nfc()`](crate::UnicodeNormalization::nfc) + /// on the iterator. + #[inline] + pub fn new_canonical(iter: I) -> Self { + Recompositions { + iter: Decompositions::new_canonical(iter), + state: self::RecompositionState::Composing, + buffer: TinyVec::new(), + composee: None, + last_ccc: None, + } + } + + /// Create a new recomposition iterator for compatability compositions (NFkC) + /// + /// Note that this iterator can also be obtained by directly calling [`.nfkc()`](crate::UnicodeNormalization::nfkc) + /// on the iterator. + #[inline] + pub fn new_compatible(iter: I) -> Self { + Recompositions { + iter: Decompositions::new_compatible(iter), + state: self::RecompositionState::Composing, + buffer: TinyVec::new(), + composee: None, + last_ccc: None, + } + } +} + +impl> Iterator for Recompositions { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + use self::RecompositionState::*; + + loop { + match self.state { + Composing => { + for ch in self.iter.by_ref() { + let ch_class = super::char::canonical_combining_class(ch); + let k = match self.composee { + None => { + if ch_class != 0 { + return Some(ch); + } + self.composee = Some(ch); + continue; + } + Some(k) => k, + }; + match self.last_ccc { + None => match super::char::compose(k, ch) { + Some(r) => { + self.composee = Some(r); + continue; + } + None => { + if ch_class == 0 { + self.composee = Some(ch); + return Some(k); + } + self.buffer.push(ch); + self.last_ccc = Some(ch_class); + } + }, + Some(l_class) => { + if l_class >= ch_class { + // `ch` is blocked from `composee` + if ch_class == 0 { + self.composee = Some(ch); + self.last_ccc = None; + self.state = Purging(0); + return Some(k); + } + self.buffer.push(ch); + self.last_ccc = Some(ch_class); + continue; + } + match super::char::compose(k, ch) { + Some(r) => { + self.composee = Some(r); + continue; + } + None => { + self.buffer.push(ch); + self.last_ccc = Some(ch_class); + } + } + } + } + } + self.state = Finished(0); + if self.composee.is_some() { + return self.composee.take(); + } + } + Purging(next) => match self.buffer.get(next).cloned() { + None => { + self.buffer.clear(); + self.state = Composing; + } + s => { + self.state = Purging(next + 1); + return s; + } + }, + Finished(next) => match self.buffer.get(next).cloned() { + None => { + self.buffer.clear(); + return self.composee.take(); + } + s => { + self.state = Finished(next + 1); + return s; + } + }, + } + } + } +} + +impl + FusedIterator> FusedIterator for Recompositions {} + +impl + Clone> fmt::Display for Recompositions { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for c in self.clone() { + f.write_char(c)?; + } + Ok(()) + } +} diff --git a/third_party/rust/unicode-normalization/src/replace.rs b/third_party/rust/unicode-normalization/src/replace.rs new file mode 100644 index 000000000000..3ab2a573d26b --- /dev/null +++ b/third_party/rust/unicode-normalization/src/replace.rs @@ -0,0 +1,66 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +use core::{ + fmt::{self, Write}, + iter::FusedIterator, +}; +use tinyvec::ArrayVec; + +/// External iterator for replacements for a string's characters. +#[derive(Clone)] +pub struct Replacements { + iter: I, + // At this time, the longest replacement sequence has length 2, so we just + // need buffer space for 1 codepoint. + buffer: Option, +} + +#[inline] +pub fn new_cjk_compat_variants>(iter: I) -> Replacements { + Replacements { iter, buffer: None } +} + +impl> Iterator for Replacements { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + if let Some(c) = self.buffer.take() { + return Some(c); + } + + match self.iter.next() { + Some(ch) => { + // At this time, the longest replacement sequence has length 2. + let mut buffer = ArrayVec::<[char; 2]>::new(); + super::char::decompose_cjk_compat_variants(ch, |d| buffer.push(d)); + self.buffer = buffer.get(1).copied(); + Some(buffer[0]) + } + None => None, + } + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, _) = self.iter.size_hint(); + (lower, None) + } +} + +impl + FusedIterator> FusedIterator for Replacements {} + +impl + Clone> fmt::Display for Replacements { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for c in self.clone() { + f.write_char(c)?; + } + Ok(()) + } +} diff --git a/third_party/rust/unicode-normalization/src/stream_safe.rs b/third_party/rust/unicode-normalization/src/stream_safe.rs new file mode 100644 index 000000000000..86498d666de9 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/stream_safe.rs @@ -0,0 +1,174 @@ +use core::iter::FusedIterator; + +use crate::lookups::{ + canonical_combining_class, canonical_fully_decomposed, compatibility_fully_decomposed, + stream_safe_trailing_nonstarters, +}; +use crate::normalize::{hangul_decomposition_length, is_hangul_syllable}; +use crate::tables::stream_safe_leading_nonstarters; + +pub(crate) const MAX_NONSTARTERS: usize = 30; +const COMBINING_GRAPHEME_JOINER: char = '\u{034F}'; + +/// UAX15-D4: This iterator keeps track of how many non-starters there have been +/// since the last starter in *NFKD* and will emit a Combining Grapheme Joiner +/// (U+034F) if the count exceeds 30. +pub struct StreamSafe { + iter: I, + nonstarter_count: usize, + buffer: Option, +} + +impl StreamSafe { + pub(crate) fn new(iter: I) -> Self { + Self { + iter, + nonstarter_count: 0, + buffer: None, + } + } +} + +impl> Iterator for StreamSafe { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + let next_ch = match self.buffer.take().or_else(|| self.iter.next()) { + None => return None, + Some(c) => c, + }; + let d = classify_nonstarters(next_ch); + if self.nonstarter_count + d.leading_nonstarters > MAX_NONSTARTERS { + // Since we're emitting a CGJ, the suffix of the emitted string in NFKD has no trailing + // nonstarters, so we can reset the counter to zero. Put `next_ch` back into the + // iterator (via `self.buffer`), and we'll reclassify it next iteration. + self.nonstarter_count = 0; + self.buffer = Some(next_ch); + return Some(COMBINING_GRAPHEME_JOINER); + } + + // Is the character all nonstarters in NFKD? If so, increment our counter of contiguous + // nonstarters in NKFD. + if d.leading_nonstarters == d.decomposition_len { + self.nonstarter_count += d.decomposition_len; + } + // Otherwise, reset the counter to the decomposition's number of trailing nonstarters. + else { + self.nonstarter_count = d.trailing_nonstarters; + } + Some(next_ch) + } +} + +impl + FusedIterator> FusedIterator for StreamSafe {} + +#[derive(Debug)] +pub(crate) struct Decomposition { + pub(crate) leading_nonstarters: usize, + pub(crate) trailing_nonstarters: usize, + pub(crate) decomposition_len: usize, +} + +#[inline] +pub(crate) fn classify_nonstarters(c: char) -> Decomposition { + // As usual, fast path for ASCII (which is always a starter) + if c <= '\x7f' { + return Decomposition { + leading_nonstarters: 0, + trailing_nonstarters: 0, + decomposition_len: 1, + }; + } + // Next, special case Hangul, since it's not handled by our tables. + if is_hangul_syllable(c) { + return Decomposition { + leading_nonstarters: 0, + trailing_nonstarters: 0, + decomposition_len: hangul_decomposition_length(c), + }; + } + let decomp = compatibility_fully_decomposed(c).or_else(|| canonical_fully_decomposed(c)); + match decomp { + Some(decomp) => Decomposition { + leading_nonstarters: stream_safe_leading_nonstarters(c), + trailing_nonstarters: stream_safe_trailing_nonstarters(c), + decomposition_len: decomp.len(), + }, + None => { + let is_nonstarter = canonical_combining_class(c) != 0; + let nonstarter = if is_nonstarter { 1 } else { 0 }; + Decomposition { + leading_nonstarters: nonstarter, + trailing_nonstarters: nonstarter, + decomposition_len: 1, + } + } + } +} + +#[cfg(test)] +mod tests { + use super::{classify_nonstarters, StreamSafe}; + use crate::lookups::canonical_combining_class; + use crate::normalize::decompose_compatible; + + #[cfg(not(feature = "std"))] + use alloc::{string::String, vec::Vec}; + + use core::char; + + fn stream_safe(s: &str) -> String { + StreamSafe::new(s.chars()).collect() + } + + #[test] + fn test_simple() { + let technically_okay = "Da\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}ngerzone"; + assert_eq!(stream_safe(technically_okay), technically_okay); + + let too_much = "Da\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{032e}ngerzone"; + let fixed_it = "Da\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{034f}\u{032e}ngerzone"; + assert_eq!(stream_safe(too_much), fixed_it); + + let woah_nelly = "Da\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{032e}\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{032e}ngerzone"; + let its_cool = "Da\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{031d}\u{034f}\u{032e}\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}\u{0305}\u{0306}\u{0307}\u{0308}\u{0309}\u{030a}\u{030b}\u{030c}\u{030d}\u{030e}\u{030f}\u{0310}\u{0311}\u{0312}\u{0313}\u{0314}\u{0315}\u{0316}\u{0317}\u{0318}\u{0319}\u{031a}\u{031b}\u{031c}\u{034f}\u{031d}\u{032e}ngerzone"; + assert_eq!(stream_safe(woah_nelly), its_cool); + } + + #[test] + fn test_all_nonstarters() { + let s = "\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}"; + let expected = "\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{034F}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}\u{300}"; + assert_eq!(stream_safe(s), expected); + } + + #[test] + fn test_classify_nonstarters() { + // Highest character in the `compat_fully_decomp` table is 2FA1D + for ch in 0..0x2FA1E { + let ch = match char::from_u32(ch) { + Some(c) => c, + None => continue, + }; + let c = classify_nonstarters(ch); + let mut s = Vec::new(); + decompose_compatible(ch, |c| s.push(c)); + + assert_eq!(s.len(), c.decomposition_len); + + let num_leading = s + .iter() + .take_while(|&c| canonical_combining_class(*c) != 0) + .count(); + let num_trailing = s + .iter() + .rev() + .take_while(|&c| canonical_combining_class(*c) != 0) + .count(); + + assert_eq!(num_leading, c.leading_nonstarters); + assert_eq!(num_trailing, c.trailing_nonstarters); + } + } +} diff --git a/third_party/rust/unicode-normalization/src/tables.rs b/third_party/rust/unicode-normalization/src/tables.rs new file mode 100644 index 000000000000..09c161d1a316 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/tables.rs @@ -0,0 +1,22803 @@ +// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// NOTE: The following code was generated by "scripts/unicode.py", do not edit directly + +#![allow(missing_docs)] +use crate::quick_check::IsNormalized; +use crate::quick_check::IsNormalized::*; + +#[allow(unused)] +pub const UNICODE_VERSION: (u8, u8, u8) = (16, 0, 0); + +pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ + 0x000, 0x001, 0x2E5, 0x085, 0x014, 0x000, 0x023, 0x092, 0x01C, 0x07A, 0x000, 0x001, 0x000, + 0x000, 0x06C, 0x02B, 0x006, 0x000, 0x000, 0x000, 0x00F, 0x000, 0x001, 0x007, 0x03A, 0x009, + 0x10D, 0x002, 0x01A, 0x000, 0x004, 0x008, 0x069, 0x000, 0x000, 0x002, 0x011, 0x000, 0x01E, + 0x000, 0x07E, 0x01B, 0x005, 0x002, 0x008, 0x000, 0x007, 0x004, 0x006, 0x00E, 0x000, 0x00A, + 0x002, 0x057, 0x022, 0x000, 0x013, 0x001, 0x005, 0x000, 0x000, 0x02D, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x049, 0x003, 0x001, 0x057, 0x000, 0x012, 0x000, 0x000, 0x000, 0x005, 0x041, + 0x000, 0x000, 0x003, 0x000, 0x003, 0x002, 0x002, 0x01D, 0x000, 0x000, 0x000, 0x011, 0x001, + 0x000, 0x002, 0x001, 0x000, 0x00E, 0x000, 0x00B, 0x001, 0x006, 0x005, 0x000, 0x001, 0x000, + 0x017, 0x000, 0x000, 0x001, 0x000, 0x000, 0x00A, 0x002, 0x000, 0x004, 0x00B, 0x018, 0x021, + 0x00C, 0x001, 0x038, 0x000, 0x000, 0x002, 0x003, 0x001, 0x005, 0x000, 0x000, 0x00A, 0x01B, + 0x001, 0x000, 0x000, 0x000, 0x019, 0x01A, 0x000, 0x000, 0x000, 0x004, 0x024, 0x003, 0x019, + 0x004, 0x000, 0x00D, 0x001, 0x013, 0x000, 0x012, 0x004, 0x000, 0x006, 0x003, 0x006, 0x000, + 0x002, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x011, 0x001, 0x011, 0x011, 0x005, 0x000, + 0x00B, 0x013, 0x01E, 0x00A, 0x004, 0x001, 0x00C, 0x00A, 0x000, 0x000, 0x005, 0x003, 0x006, + 0x000, 0x005, 0x009, 0x002, 0x000, 0x000, 0x009, 0x000, 0x001, 0x000, 0x029, 0x000, 0x012, + 0x019, 0x004, 0x000, 0x000, 0x002, 0x00E, 0x003, 0x001, 0x00F, 0x005, 0x002, 0x001, 0x004, + 0x007, 0x005, 0x000, 0x005, 0x002, 0x000, 0x000, 0x009, 0x000, 0x005, 0x003, 0x009, 0x001, + 0x000, 0x000, 0x001, 0x000, 0x000, 0x009, 0x007, 0x007, 0x000, 0x000, 0x000, 0x006, 0x003, + 0x000, 0x00A, 0x000, 0x000, 0x003, 0x007, 0x001, 0x000, 0x000, 0x001, 0x01A, 0x006, 0x000, + 0x001, 0x009, 0x002, 0x008, 0x000, 0x001, 0x000, 0x008, 0x001, 0x009, 0x006, 0x015, 0x001, + 0x000, 0x004, 0x000, 0x000, 0x000, 0x00C, 0x000, 0x005, 0x003, 0x000, 0x006, 0x000, 0x000, + 0x008, 0x000, 0x000, 0x003, 0x007, 0x001, 0x000, 0x005, 0x001, 0x010, 0x007, 0x001, 0x005, + 0x000, 0x000, 0x004, 0x004, 0x009, 0x00B, 0x001, 0x005, 0x004, 0x00A, 0x008, 0x003, 0x018, + 0x000, 0x001, 0x002, 0x003, 0x000, 0x002, 0x000, 0x007, 0x000, 0x003, 0x000, 0x005, 0x007, + 0x009, 0x00F, 0x006, 0x000, 0x005, 0x003, 0x009, 0x00B, 0x013, 0x002, 0x001, 0x000, 0x001, + 0x001, 0x000, 0x001, 0x000, 0x001, 0x003, 0x00F, 0x000, 0x004, 0x000, 0x000, 0x007, 0x007, + 0x002, 0x000, 0x000, 0x000, 0x002, 0x004, 0x00B, 0x000, 0x00C, 0x001, 0x000, 0x000, 0x002, + 0x004, 0x008, 0x002, 0x002, 0x000, 0x006, 0x000, 0x00B, 0x001, 0x001, 0x00C, 0x006, 0x000, + 0x004, 0x002, 0x00B, 0x001, 0x000, 0x001, 0x000, 0x000, 0x005, 0x001, 0x001, 0x00E, 0x003, + 0x005, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, 0x000, 0x00A, 0x003, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x013, 0x000, 0x002, 0x00A, 0x000, 0x000, 0x003, + 0x003, 0x001, 0x003, 0x007, 0x004, 0x002, 0x000, 0x002, 0x000, 0x004, 0x000, 0x001, 0x001, + 0x00E, 0x001, 0x005, 0x001, 0x002, 0x006, 0x002, 0x003, 0x004, 0x006, 0x002, 0x003, 0x001, + 0x001, 0x005, 0x001, 0x000, 0x00E, 0x003, 0x002, 0x007, 0x000, 0x000, 0x00A, 0x004, 0x000, + 0x000, 0x000, 0x006, 0x000, 0x000, 0x000, 0x000, 0x005, 0x000, 0x006, 0x001, 0x000, 0x003, + 0x005, 0x003, 0x001, 0x007, 0x001, 0x002, 0x008, 0x008, 0x002, 0x001, 0x004, 0x000, 0x005, + 0x009, 0x002, 0x000, 0x001, 0x003, 0x010, 0x001, 0x004, 0x004, 0x004, 0x003, 0x000, 0x000, + 0x001, 0x000, 0x002, 0x000, 0x000, 0x001, 0x001, 0x010, 0x002, 0x003, 0x000, 0x000, 0x000, + 0x003, 0x001, 0x001, 0x003, 0x000, 0x000, 0x002, 0x000, 0x001, 0x001, 0x000, 0x005, 0x002, + 0x000, 0x002, 0x003, 0x000, 0x006, 0x000, 0x000, 0x001, 0x001, 0x000, 0x000, 0x001, 0x000, + 0x00A, 0x000, 0x007, 0x000, 0x001, 0x001, 0x000, 0x001, 0x001, 0x004, 0x003, 0x003, 0x002, + 0x007, 0x003, 0x000, 0x007, 0x000, 0x000, 0x003, 0x000, 0x001, 0x00B, 0x001, 0x002, 0x005, + 0x000, 0x003, 0x001, 0x000, 0x000, 0x003, 0x000, 0x002, 0x000, 0x000, 0x000, 0x002, 0x001, + 0x000, 0x001, 0x002, 0x001, 0x004, 0x005, 0x004, 0x000, 0x003, 0x002, 0x000, 0x000, 0x001, + 0x005, 0x002, 0x007, 0x001, 0x001, 0x000, 0x001, 0x000, 0x001, 0x003, 0x003, 0x002, 0x004, + 0x000, 0x001, 0x001, 0x001, 0x000, 0x000, 0x003, 0x002, 0x005, 0x000, 0x005, 0x00F, 0x002, + 0x000, 0x001, 0x001, 0x000, 0x002, 0x000, 0x000, 0x000, 0x001, 0x000, 0x003, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x001, 0x001, 0x003, 0x000, 0x001, 0x003, 0x001, + 0x000, 0x000, 0x002, 0x000, 0x005, 0x003, 0x000, 0x006, 0x001, 0x002, 0x002, 0x003, 0x001, + 0x003, 0x005, 0x006, 0x000, 0x002, 0x003, 0x00A, 0x000, 0x001, 0x001, 0x002, 0x002, 0x002, + 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x005, 0x004, 0x001, 0x000, 0x000, 0x003, + 0x001, 0x000, 0x000, 0x002, 0x000, 0x002, 0x001, 0x001, 0x002, 0x003, 0x000, 0x002, 0x000, + 0x001, 0x000, 0x002, 0x003, 0x000, 0x002, 0x002, 0x001, 0x000, 0x001, 0x000, 0x001, 0x004, + 0x001, 0x000, 0x004, 0x004, 0x001, 0x000, 0x000, 0x001, 0x001, 0x003, 0x001, 0x000, 0x000, + 0x001, 0x002, 0x002, 0x009, 0x001, 0x005, 0x002, 0x002, 0x001, 0x000, 0x002, 0x006, 0x00D, + 0x001, 0x002, 0x006, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x007, 0x000, 0x004, + 0x002, 0x000, 0x002, 0x003, 0x001, 0x000, 0x002, 0x000, 0x001, 0x003, 0x000, 0x001, 0x000, + 0x001, 0x000, 0x003, 0x002, 0x001, 0x006, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, + 0x003, 0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x009, 0x000, 0x000, 0x000, 0x002, 0x001, + 0x001, 0x003, 0x001, 0x001, 0x000, 0x005, 0x000, 0x003, 0x002, 0x003, 0x001, 0x001, 0x002, + 0x000, 0x003, 0x001, 0x001, 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x002, 0x003, 0x001, + 0x001, 0x000, 0x001, 0x005, 0x004, 0x000, 0x003, 0x003, 0x000, 0x002, 0x003, 0x001, 0x001, + 0x005, 0x003, 0x001, 0x000, 0x000, 0x001, 0x002, 0x001, 0x003, 0x00A, 0x004, 0x000, 0x001, + 0x003, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x005, 0x002, 0x000, 0x001, 0x001, + 0x000, 0x000, 0x006, 0x005, 0x003, 0x000, 0x000, 0x002, 0x000, 0x001, 0x000, 0x001, 0x001, + 0x001, 0x001, 0x001, 0x000, 0x000, 0x00B, 0x004, 0x000, 0x002, 0x001, 0x002, 0x002, 0x001, + 0x001, 0x000, 0x001, 0x002, 0x001, 0x001, 0x001, 0x002, 0x002, 0x000, 0x004, 0x001, 0x002, + 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x000, 0x000, 0x008, 0x001, 0x001, 0x000, 0x002, 0x002, 0x003, 0x002, 0x001, 0x001, 0x002, + 0x000, 0x001, 0x000, 0x000, 0x009, 0x001, 0x001, 0x000, 0x001, 0x000, 0x003, 0x000, 0x001, + 0x006, 0x001, 0x001, 0x000, 0x003, 0x001, 0x001, 0x001, 0x001, 0x004, 0x002, 0x002, 0x001, + 0x000, 0x001, 0x003, 0x004, 0x000, 0x003, 0x000, 0x000, 0x001, 0x001, 0x001, +]; +pub(crate) const CANONICAL_COMBINING_CLASS_KV: &[u32] = &[ + 0x0034AE6, 0x00E3A09, 0x01DFADA, 0x00818E6, 0x0FE20E6, 0x0A67CE6, 0x020D201, 0x02DFEE6, + 0x008CCE6, 0x00737DC, 0x01DEBE6, 0x0FE26E6, 0x0089DE6, 0x01A7AE6, 0x006EADC, 0x0A675E6, + 0x02DF7E6, 0x0A8EBE6, 0x1193D09, 0x0064F1F, 0x00741E6, 0x10D6AE6, 0x0FE2DDC, 0x1E024E6, + 0x00322CA, 0x1E023E6, 0x01ACBE6, 0x005BB14, 0x00359DC, 0x008CEE6, 0x00F7484, 0x01B6DE6, + 0x0A8E6E6, 0x0030DE6, 0x00F7A82, 0x1117307, 0x00356DC, 0x00592E6, 0x0FE2BDC, 0x01DEEE6, + 0x00360EA, 0x1E947E6, 0x1133B07, 0x02CF1E6, 0x1E02AE6, 0x1D182DC, 0x01DE6E6, 0x10EFDDC, + 0x00736E6, 0x01DECE6, 0x008D6E6, 0x10D25E6, 0x008FDE6, 0x00744DC, 0x00ECA7A, 0x1136CE6, + 0x009BC07, 0x01AB9DC, 0x1D1ADE6, 0x008E4E6, 0x01A79E6, 0x10F4DDC, 0x00825E6, 0x0AABFE6, + 0x0AABEE6, 0x00953E6, 0x0A8E9E6, 0x008E3DC, 0x0064E1E, 0x006D6E6, 0x111CA07, 0x10D69E6, + 0x00364E6, 0x10A3ADC, 0x01DC4E6, 0x0103A09, 0x00349DC, 0x00358E8, 0x00487E6, 0x01AB1E6, + 0x0065020, 0x01CD0E6, 0x0FE28DC, 0x005B711, 0x020D5E6, 0x00819E6, 0x01C3707, 0x16AF301, + 0x01DCADC, 0x01BF309, 0x01DDAE6, 0x0035FE9, 0x01DDDE6, 0x10F82E6, 0x00361EA, 0x11D4509, + 0x00352E6, 0x01DF0E6, 0x0034CE6, 0x01CD7DC, 0x0033701, 0x1E2EDE6, 0x11373E6, 0x01B6EE6, + 0x020EA01, 0x10EABE6, 0x007EFE6, 0x0081DE6, 0x1D16801, 0x1E8D6DC, 0x01CD401, 0x00367E6, + 0x1D188E6, 0x01CE0E6, 0x008EAE6, 0x01CDAE6, 0x00735E6, 0x005C712, 0x00C4D09, 0x00323DC, + 0x00598E6, 0x10F4AE6, 0x01DDFE6, 0x020E8DC, 0x11D9709, 0x01DE1E6, 0x00316DC, 0x01A7CE6, + 0x1E945E6, 0x01DD9E6, 0x0085BDC, 0x00EC97A, 0x00D4D09, 0x02DF0E6, 0x0309908, 0x017D209, + 0x0A67AE6, 0x1D1AAE6, 0x005B40E, 0x01DE3E6, 0x111C009, 0x1D1ACE6, 0x00357E6, 0x119E009, + 0x0030BE6, 0x0033EE6, 0x01CE301, 0x01CF8E6, 0x00F8409, 0x01DCBE6, 0x00317DC, 0x00483E6, + 0x10F4BDC, 0x00326DC, 0x01CD2E6, 0x020D0E6, 0x005C4E6, 0x01AB0E6, 0x0089ADC, 0x0081CE6, + 0x01DE4E6, 0x1144607, 0x115C007, 0x1183A07, 0x10F49E6, 0x00659E6, 0x01B6FE6, 0x0032DDC, + 0x00EB876, 0x1BC9E01, 0x00734DC, 0x1136AE6, 0x0032EDC, 0x020E501, 0x008FBE6, 0x02D7F09, + 0x1E944E6, 0x1E018E6, 0x01DEFE6, 0x1E949E6, 0x02DEEE6, 0x0135FE6, 0x00309E6, 0x01AC2E6, + 0x00485E6, 0x01DF8E4, 0x00F86E6, 0x00613E6, 0x008D9E6, 0x01CDDDC, 0x1104609, 0x00304E6, + 0x008E6DC, 0x0081EE6, 0x01DF6E8, 0x0093C07, 0x0A8ECE6, 0x1D1ABE6, 0x006ECE6, 0x0064C1C, + 0x008F5E6, 0x1D244E6, 0x1E014E6, 0x00FC6DC, 0x0A8E1E6, 0x005AADC, 0x00658E6, 0x1E020E6, + 0x008D4E6, 0x1133C07, 0x00302E6, 0x01AC4DC, 0x01DC6E6, 0x01AB4E6, 0x1D170D8, 0x0135EE6, + 0x0059EE6, 0x008FFE6, 0x00739DC, 0x10AE5E6, 0x1E8D2DC, 0x1107009, 0x00308E6, 0x02CF0E6, + 0x01DF3E6, 0x0A67DE6, 0x01DCED6, 0x0033ADC, 0x1D166D8, 0x00733E6, 0x11F4109, 0x0036BE6, + 0x01CDEDC, 0x1E012E6, 0x0108DDC, 0x00611E6, 0x00ABC07, 0x01CEDDC, 0x1E026E6, 0x00343E6, + 0x020D901, 0x1E948E6, 0x116B707, 0x00746DC, 0x01DE8E6, 0x020D7E6, 0x02DEFE6, 0x00355DC, + 0x01A77E6, 0x00E3867, 0x0FE24E6, 0x1113309, 0x11369E6, 0x02DF4E6, 0x10EFFDC, 0x006EDDC, + 0x0FE29DC, 0x0031EDC, 0x01DFCE9, 0x00F35DC, 0x1E4EEDC, 0x10D6DE6, 0x1D171D8, 0x11A9909, + 0x00303E6, 0x10377E6, 0x1E015E6, 0x00313E6, 0x00332DC, 0x11368E6, 0x10D6CE6, 0x0A92DDC, + 0x006E1E6, 0x00362E9, 0x00596DC, 0x0067023, 0x10F4FDC, 0x1123509, 0x01DC3E6, 0x10A0FE6, + 0x02DF8E6, 0x0A8E4E6, 0x0032CDC, 0x00D3B09, 0x1D165D8, 0x0171409, 0x01CE601, 0x01ABBE6, + 0x008DAE6, 0x00B3C07, 0x008F11C, 0x10AE6DC, 0x1E8D5DC, 0x00745E6, 0x01AC0DC, 0x020EEDC, + 0x01CDFDC, 0x02DF9E6, 0x01AC5E6, 0x00597E6, 0x0302BE4, 0x00897E6, 0x1144209, 0x006DBE6, + 0x0A80609, 0x113CE09, 0x0035DEA, 0x0FE2FE6, 0x00CBC07, 0x01DC7E6, 0x006E7E6, 0x00321CA, + 0x00369E6, 0x00F7C82, 0x0031AE8, 0x02DF1E6, 0x008E8E6, 0x16AF201, 0x00740E6, 0x01DFDDC, + 0x1E5EEE6, 0x11D4207, 0x01ABADC, 0x0A8E2E6, 0x112E907, 0x1D16901, 0x1E010E6, 0x1E000E6, + 0x005B00A, 0x005C5DC, 0x0302FE0, 0x01A78E6, 0x1113409, 0x1E006E6, 0x01DE9E6, 0x008CFDC, + 0x01DCCE6, 0x00F7D82, 0x006DCE6, 0x0173409, 0x0103909, 0x01BE607, 0x00731DC, 0x00312E6, + 0x1E8D4DC, 0x00829E6, 0x008FADC, 0x1E029E6, 0x00823E6, 0x0030CE6, 0x01AB6DC, 0x1E135E6, + 0x01DC8E6, 0x01DEDE6, 0x0035ADC, 0x00732E6, 0x0A8EDE6, 0x0AAB3E6, 0x1E028E6, 0x008F6DC, + 0x008E7E6, 0x1E4ECE8, 0x0073CDC, 0x01DF7E4, 0x005ACE6, 0x020EFDC, 0x01CF4E6, 0x00368E6, + 0x1E01CE6, 0x1D18ADC, 0x0FE21E6, 0x01DDCE6, 0x020D4E6, 0x0059BDC, 0x16B32E6, 0x0035BE6, + 0x008D2DC, 0x0031BD8, 0x0A677E6, 0x1E003E6, 0x00DCA09, 0x0031DDC, 0x10F4CE6, 0x00F19DC, + 0x01DFFDC, 0x0135DE6, 0x0030FE6, 0x02DE5E6, 0x0033801, 0x01ACEE6, 0x00743E6, 0x0193AE6, + 0x10A3F09, 0x00CCD09, 0x01B71E6, 0x00954E6, 0x0089CE6, 0x020E601, 0x008F01B, 0x00657E6, + 0x0FE23E6, 0x00311E6, 0x10EACE6, 0x020D301, 0x0064B1B, 0x020DBE6, 0x008DEE6, 0x0065DE6, + 0x1E009E6, 0x0A674E6, 0x008CDE6, 0x01CE701, 0x008F21D, 0x0089EE6, 0x01DD1E6, 0x00324DC, + 0x10A38E6, 0x01CD1E6, 0x01CD5DC, 0x1E132E6, 0x00EC87A, 0x01DCDEA, 0x0FE25E6, 0x0061A20, + 0x00301E6, 0x005A1E6, 0x008F8E6, 0x1D186E6, 0x00305E6, 0x16B30E6, 0x01DF4E6, 0x00730E6, + 0x00821E6, 0x007F1E6, 0x114C307, 0x0033DE6, 0x01DC2DC, 0x00615E6, 0x006E3DC, 0x01A17E6, + 0x0089FE6, 0x0AAB0E6, 0x01DD5E6, 0x1E01FE6, 0x0082AE6, 0x00325DC, 0x11374E6, 0x10376E6, + 0x0081BE6, 0x02DFFE6, 0x1D16FD8, 0x00484E6, 0x00318DC, 0x1E8D0DC, 0x005A6DC, 0x1193E09, + 0x00F39D8, 0x1E00CE6, 0x00591DC, 0x1D187E6, 0x01B6CDC, 0x01DD0CA, 0x006D8E6, 0x01B3407, + 0x02DEAE6, 0x1163F09, 0x008DDE6, 0x00F87E6, 0x02DE3E6, 0x00300E6, 0x0A6F1E6, 0x02DF2E6, + 0x005A7DC, 0x01DF2E6, 0x00820E6, 0x00365E6, 0x1D17BDC, 0x01AB7DC, 0x1D16ED8, 0x0034DDC, + 0x1E2EEE6, 0x0ABED09, 0x0AAB7E6, 0x0A8EFE6, 0x00614E6, 0x11C3F09, 0x102E0DC, 0x00ACD09, + 0x0171509, 0x01AC6E6, 0x005B610, 0x11A3409, 0x0035EEA, 0x00310E6, 0x16AF401, 0x1E01EE6, + 0x0032ADC, 0x0AAB2E6, 0x0A9C009, 0x00366E6, 0x005B50F, 0x009FEE6, 0x006DFE6, 0x0FE22E6, + 0x1E8D3DC, 0x00340E6, 0x01DD8E6, 0x10F48E6, 0x02DFAE6, 0x1D17CDC, 0x0A678E6, 0x00826E6, + 0x0A82C09, 0x01DE0E6, 0x0A8E0E6, 0x10F83DC, 0x0302DDE, 0x01DF5E6, 0x01B73E6, 0x1E00FE6, + 0x1D16701, 0x01A6009, 0x02DE1E6, 0x0036CE6, 0x006EBE6, 0x00C565B, 0x01DE7E6, 0x00B4D09, + 0x1E00DE6, 0x02DFDE6, 0x008F7E6, 0x00655DC, 0x0A67BE6, 0x00333DC, 0x005C118, 0x11366E6, + 0x1D16DE2, 0x006181E, 0x0033FE6, 0x1E946E6, 0x0FE27DC, 0x007F0E6, 0x1E002E6, 0x114C209, + 0x1E01DE6, 0x0A95309, 0x16B33E6, 0x1E01BE6, 0x01CE201, 0x01ACDE6, 0x00610E6, 0x0FE2CDC, + 0x0A676E6, 0x16AF001, 0x020D6E6, 0x1D17FDC, 0x1D181DC, 0x005B913, 0x00827E6, 0x008D3DC, + 0x115BF09, 0x005A0E6, 0x0065222, 0x008DFE6, 0x00653E6, 0x01CE401, 0x113CF09, 0x01A76E6, + 0x006E2E6, 0x110B909, 0x10F46DC, 0x11A4709, 0x11370E6, 0x01CF9E6, 0x0065EE6, 0x00616E6, + 0x02DFBE6, 0x1136BE6, 0x00656DC, 0x00348DC, 0x10D26E6, 0x01DD6E6, 0x008FCE6, 0x1145EE6, + 0x00654E6, 0x008ECE6, 0x008CAE6, 0x020F0E6, 0x01DD7E6, 0x0030AE6, 0x00328CA, 0x00314E6, + 0x0085ADC, 0x0034BE6, 0x1D189E6, 0x1E00AE6, 0x008DBE6, 0x10F4EDC, 0x005B812, 0x00320DC, + 0x01DDEE6, 0x01B6BE6, 0x01AC3DC, 0x0033BDC, 0x01ACCE6, 0x005B30D, 0x0073FE6, 0x01AC1E6, + 0x0302CE8, 0x01CD6DC, 0x00F37DC, 0x01DC1E6, 0x01DFEE6, 0x018A9E4, 0x020EB01, 0x008EFDC, + 0x00347DC, 0x1123607, 0x00486E6, 0x00749E6, 0x017DDE6, 0x11102E6, 0x00617E6, 0x00D3C09, + 0x0A8EAE6, 0x008EDDC, 0x00351E6, 0x00A3C07, 0x1E2ECE6, 0x116B609, 0x1E011E6, 0x020E1E6, + 0x10D6BE6, 0x005C219, 0x01A7BE6, 0x007EEE6, 0x0036EE6, 0x008F9DC, 0x01DEAE6, 0x00BCD09, + 0x005B10B, 0x01AB3E6, 0x11372E6, 0x008D7E6, 0x1D17EDC, 0x0A8EEE6, 0x008DCE6, 0x16B31E6, + 0x02DE7E6, 0x0065121, 0x006E4E6, 0x0059CE6, 0x00342E6, 0x0AAB4DC, 0x00595E6, 0x16B36E6, + 0x0030EE6, 0x0033501, 0x0036FE6, 0x00816E6, 0x0302EE0, 0x00353DC, 0x0031CDC, 0x00315E8, + 0x01B72E6, 0x005A2DC, 0x02DF6E6, 0x008EEDC, 0x0082DE6, 0x01CD8DC, 0x005BA13, 0x01AC7E6, + 0x01AB2E6, 0x0033CDC, 0x01939DE, 0x0103707, 0x0A8F1E6, 0x00612E6, 0x10F84E6, 0x0073BDC, + 0x1E008E6, 0x007EDE6, 0x020EDDC, 0x00E4A6B, 0x16FF106, 0x110BA07, 0x00346E6, 0x008FEE6, + 0x00331DC, 0x00C3C07, 0x1E00EE6, 0x00ECB7A, 0x005ABE6, 0x16AF101, 0x01ABCE6, 0x0081FE6, + 0x01BAA09, 0x10D24E6, 0x0A92CDC, 0x005A8E6, 0x1037AE6, 0x0059DE6, 0x01B70E6, 0x006E8E6, + 0x00F7181, 0x02DE4E6, 0x16B34E6, 0x02DEDE6, 0x00A4D09, 0x0A92BDC, 0x0082CE6, 0x1E2EFE6, + 0x1D242E6, 0x00354DC, 0x0032BDC, 0x0193BDC, 0x008D1DC, 0x0073EDC, 0x1E005E6, 0x00319DC, + 0x02DEBE6, 0x0073AE6, 0x01AC8E6, 0x00F82E6, 0x1E133E6, 0x1D180DC, 0x0033601, 0x00EBA09, + 0x0AAF609, 0x02DF5E6, 0x00307E6, 0x01DC0E6, 0x10F85DC, 0x0032FDC, 0x0035CE9, 0x01CDBE6, + 0x00330DC, 0x01AB5DC, 0x01DDBE6, 0x02DE9E6, 0x00F7282, 0x1E131E6, 0x00363E6, 0x16FF006, + 0x007ECE6, 0x112EA09, 0x10378E6, 0x007FDDC, 0x0302ADA, 0x0065BE6, 0x006191F, 0x00F18DC, + 0x1172B09, 0x00952DC, 0x00F83E6, 0x00898E6, 0x00899DC, 0x10A3901, 0x1134D09, 0x01DF1E6, + 0x0309A08, 0x00747E6, 0x01DE2E6, 0x1E8D1DC, 0x10EFEDC, 0x1E013E6, 0x0034EDC, 0x005B20C, + 0x16B35E6, 0x00859DC, 0x1107F09, 0x00738DC, 0x005A3DC, 0x11367E6, 0x01ACADC, 0x01A7FDC, + 0x1E08FE6, 0x11100E6, 0x0065AE6, 0x11D4409, 0x01DCFDC, 0x0065CDC, 0x01DD3E6, 0x005AEE4, + 0x1E016E6, 0x008EBE6, 0x0031FDC, 0x00EB976, 0x1E004E6, 0x0033401, 0x0074AE6, 0x01DF9DC, + 0x01CE801, 0x0064D1D, 0x020D1E6, 0x0A8E5E6, 0x1D243E6, 0x0094D09, 0x00E4B6B, 0x007F3E6, + 0x005ADDE, 0x005A4DC, 0x008F4E6, 0x11F4209, 0x0AAC1E6, 0x1D185E6, 0x02DECE6, 0x0A8F0E6, + 0x01DE5E6, 0x00306E6, 0x0A8E3E6, 0x00951E6, 0x11101E6, 0x02DE8E6, 0x00748DC, 0x0A8E8E6, + 0x1E4EDE8, 0x006DAE6, 0x01CE501, 0x0AAB8E6, 0x10A0DDC, 0x00822E6, 0x00327CA, 0x1612F09, + 0x1E017E6, 0x00339DC, 0x02DE6E6, 0x020E7E6, 0x00345F0, 0x0FE2EE6, 0x10379E6, 0x0071124, + 0x101FDDC, 0x0082BE6, 0x01B4409, 0x00329DC, 0x00350E6, 0x005AFE6, 0x02DFCE6, 0x008D8E6, + 0x00C5554, 0x00817E6, 0x1E021E6, 0x01AC9E6, 0x00593E6, 0x01DD2E6, 0x0A9B307, 0x01DC9E6, + 0x00341E6, 0x008D0DC, 0x0A6F0E6, 0x008E0E6, 0x01A75E6, 0x01DC5E6, 0x0059FE6, 0x01ABDDC, + 0x01ABFDC, 0x1E5EFDC, 0x00594E6, 0x005A5DC, 0x007F2DC, 0x01BAB09, 0x01BF209, 0x1E4EFE6, + 0x005A9E6, 0x008F3E6, 0x1E00BE6, 0x1D172D8, 0x006D7E6, 0x006D9E6, 0x0036AE6, 0x01CD9DC, + 0x10F47DC, 0x0A69FE6, 0x005BC15, 0x008E1E6, 0x1E134E6, 0x0065FDC, 0x0A8E7E6, 0x1E001E6, + 0x1E027E6, 0x1E2AEE6, 0x01DFBE6, 0x00E486B, 0x01AB8DC, 0x01A18DC, 0x020D801, 0x0FB1E1A, + 0x0A66FE6, 0x02DE2E6, 0x02DF3E6, 0x00599E6, 0x1183909, 0x113D009, 0x00E3967, 0x0059ADE, + 0x10D27E6, 0x0073DE6, 0x10F50DC, 0x008CBE6, 0x01DD4E6, 0x02CEFE6, 0x00742DC, 0x1D18BDC, + 0x008D5E6, 0x01CDCDC, 0x02DE0E6, 0x0089BDC, 0x0A679E6, 0x020E9E6, 0x008E9DC, 0x1E130E6, + 0x020DA01, 0x020DCE6, 0x1194307, 0x006E0E6, 0x0A69EE6, 0x008E5E6, 0x1E136E6, 0x020ECDC, + 0x00E496B, 0x0036DE6, 0x11371E6, 0x005BF17, 0x0A8C409, 0x007EBE6, 0x0FE2ADC, 0x1D17DDC, + 0x009CD09, 0x005BD16, 0x00F8082, 0x00344E6, 0x00F7B82, 0x1E94A07, +]; + +pub(crate) const COMPOSITION_TABLE_SALT: &[u16] = &[ + 0x000, 0x000, 0x000, 0x000, 0x25D, 0x003, 0x05D, 0x000, 0x002, 0x009, 0x004, 0x087, 0x006, + 0x135, 0x001, 0x000, 0x000, 0x004, 0x003, 0x0E1, 0x078, 0x000, 0x002, 0x029, 0x008, 0x08F, + 0x024, 0x000, 0x000, 0x000, 0x031, 0x000, 0x000, 0x06D, 0x000, 0x033, 0x001, 0x04C, 0x000, + 0x001, 0x000, 0x000, 0x008, 0x07C, 0x006, 0x04C, 0x045, 0x02A, 0x002, 0x000, 0x000, 0x000, + 0x00A, 0x000, 0x000, 0x059, 0x000, 0x010, 0x003, 0x009, 0x00E, 0x006, 0x001, 0x00C, 0x010, + 0x000, 0x000, 0x000, 0x03D, 0x000, 0x000, 0x02A, 0x000, 0x000, 0x001, 0x020, 0x00A, 0x000, + 0x001, 0x00E, 0x002, 0x010, 0x022, 0x000, 0x061, 0x000, 0x004, 0x015, 0x000, 0x004, 0x003, + 0x000, 0x000, 0x003, 0x000, 0x00D, 0x001, 0x001, 0x024, 0x003, 0x004, 0x000, 0x000, 0x018, + 0x058, 0x000, 0x000, 0x00A, 0x019, 0x010, 0x000, 0x002, 0x000, 0x000, 0x012, 0x015, 0x000, + 0x00C, 0x007, 0x003, 0x000, 0x01A, 0x007, 0x00C, 0x001, 0x005, 0x004, 0x021, 0x001, 0x002, + 0x000, 0x000, 0x001, 0x00A, 0x000, 0x00A, 0x000, 0x004, 0x009, 0x005, 0x00D, 0x005, 0x000, + 0x003, 0x006, 0x026, 0x00B, 0x000, 0x004, 0x006, 0x000, 0x013, 0x000, 0x000, 0x004, 0x001, + 0x000, 0x000, 0x000, 0x024, 0x001, 0x01D, 0x001, 0x000, 0x000, 0x010, 0x000, 0x001, 0x001, + 0x001, 0x000, 0x000, 0x00A, 0x000, 0x00D, 0x000, 0x010, 0x000, 0x006, 0x005, 0x000, 0x000, + 0x009, 0x003, 0x001, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x002, 0x000, 0x000, 0x016, + 0x001, 0x002, 0x000, 0x001, 0x000, 0x006, 0x001, 0x025, 0x005, 0x000, 0x00A, 0x00D, 0x002, + 0x000, 0x001, 0x000, 0x000, 0x012, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x001, 0x000, + 0x004, 0x009, 0x000, 0x001, 0x004, 0x000, 0x004, 0x001, 0x006, 0x00B, 0x003, 0x006, 0x007, + 0x000, 0x000, 0x000, 0x00D, 0x00F, 0x00E, 0x000, 0x001, 0x001, 0x004, 0x00F, 0x010, 0x000, + 0x005, 0x000, 0x019, 0x001, 0x00E, 0x000, 0x008, 0x001, 0x003, 0x000, 0x000, 0x005, 0x001, + 0x000, 0x000, 0x011, 0x000, 0x004, 0x005, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x002, + 0x001, 0x000, 0x000, 0x002, 0x001, 0x001, 0x005, 0x008, 0x000, 0x000, 0x00C, 0x00A, 0x000, + 0x006, 0x009, 0x003, 0x001, 0x006, 0x001, 0x000, 0x01B, 0x001, 0x00E, 0x000, 0x008, 0x005, + 0x003, 0x015, 0x000, 0x002, 0x007, 0x00B, 0x003, 0x000, 0x00A, 0x003, 0x000, 0x006, 0x000, + 0x00A, 0x000, 0x001, 0x003, 0x008, 0x000, 0x009, 0x000, 0x001, 0x002, 0x000, 0x005, 0x000, + 0x001, 0x000, 0x000, 0x000, 0x017, 0x000, 0x000, 0x002, 0x000, 0x005, 0x016, 0x000, 0x010, + 0x003, 0x004, 0x011, 0x001, 0x003, 0x000, 0x000, 0x000, 0x004, 0x001, 0x000, 0x005, 0x000, + 0x002, 0x001, 0x000, 0x002, 0x000, 0x002, 0x002, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, + 0x012, 0x001, 0x004, 0x00A, 0x00B, 0x004, 0x000, 0x002, 0x000, 0x003, 0x000, 0x004, 0x005, + 0x000, 0x000, 0x011, 0x001, 0x006, 0x006, 0x000, 0x002, 0x000, 0x001, 0x000, 0x004, 0x000, + 0x000, 0x001, 0x001, 0x007, 0x000, 0x003, 0x00A, 0x000, 0x001, 0x00A, 0x002, 0x000, 0x001, + 0x000, 0x000, 0x00D, 0x005, 0x001, 0x001, 0x000, 0x000, 0x005, 0x006, 0x008, 0x004, 0x005, + 0x000, 0x00B, 0x000, 0x004, 0x00B, 0x000, 0x000, 0x001, 0x005, 0x000, 0x00B, 0x000, 0x006, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x004, 0x000, 0x006, 0x000, 0x000, 0x007, 0x013, + 0x004, 0x019, 0x003, 0x001, 0x000, 0x001, 0x006, 0x006, 0x000, 0x000, 0x000, 0x000, 0x00C, + 0x002, 0x003, 0x000, 0x004, 0x000, 0x001, 0x000, 0x001, 0x005, 0x001, 0x001, 0x002, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x009, 0x000, 0x000, 0x007, 0x001, 0x009, 0x006, 0x004, 0x001, + 0x005, 0x000, 0x001, 0x002, 0x008, 0x000, 0x009, 0x000, 0x000, 0x001, 0x003, 0x00B, 0x000, + 0x001, 0x000, 0x000, 0x005, 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, 0x002, 0x001, + 0x002, 0x000, 0x000, 0x000, 0x004, 0x001, 0x000, 0x006, 0x002, 0x005, 0x008, 0x012, 0x000, + 0x000, 0x000, 0x003, 0x001, 0x000, 0x000, 0x000, 0x002, 0x003, 0x003, 0x000, 0x000, 0x001, + 0x000, 0x001, 0x000, 0x003, 0x000, 0x000, 0x002, 0x001, 0x004, 0x00D, 0x000, 0x000, 0x00B, + 0x000, 0x001, 0x000, 0x000, 0x00C, 0x000, 0x000, 0x000, 0x005, 0x008, 0x002, 0x000, 0x002, + 0x001, 0x006, 0x001, 0x001, 0x001, 0x000, 0x002, 0x000, 0x005, 0x001, 0x001, 0x000, 0x002, + 0x000, 0x000, 0x000, 0x000, 0x00E, 0x010, 0x000, 0x005, 0x004, 0x002, 0x001, 0x000, 0x000, + 0x003, 0x001, 0x000, 0x002, 0x001, 0x004, 0x000, 0x000, 0x003, 0x000, 0x001, 0x001, 0x003, + 0x001, 0x005, 0x002, 0x003, 0x004, 0x000, 0x003, 0x003, 0x006, 0x000, 0x000, 0x001, 0x000, + 0x002, 0x00E, 0x001, 0x002, 0x001, 0x004, 0x002, 0x005, 0x002, 0x001, 0x001, 0x000, 0x001, + 0x000, 0x005, 0x005, 0x006, 0x006, 0x005, 0x000, 0x002, 0x001, 0x000, 0x002, 0x004, 0x001, + 0x000, 0x005, 0x000, 0x006, 0x002, 0x008, 0x000, 0x000, 0x007, 0x001, 0x002, 0x002, 0x005, + 0x004, 0x011, 0x000, 0x003, 0x000, 0x001, 0x000, 0x001, 0x004, 0x000, 0x003, 0x002, 0x000, + 0x001, 0x003, 0x000, 0x00B, 0x006, 0x000, 0x006, 0x000, 0x004, 0x001, 0x002, 0x000, 0x001, + 0x000, 0x002, 0x001, 0x002, 0x000, 0x005, 0x001, 0x000, 0x000, 0x000, 0x001, 0x003, 0x002, + 0x006, 0x000, 0x000, 0x002, 0x004, 0x006, 0x000, 0x000, 0x000, 0x000, 0x00C, 0x00C, 0x000, + 0x000, 0x000, 0x004, 0x004, 0x000, 0x008, 0x003, 0x001, 0x000, 0x001, 0x000, 0x003, 0x000, + 0x000, 0x005, 0x000, 0x005, 0x001, 0x000, 0x003, 0x004, 0x001, 0x002, 0x003, 0x000, 0x001, + 0x007, 0x000, 0x000, 0x007, 0x000, 0x002, 0x002, 0x000, 0x000, 0x001, 0x001, 0x001, 0x001, + 0x00B, 0x000, 0x004, 0x000, 0x001, 0x001, 0x000, 0x002, 0x001, 0x001, 0x005, 0x000, 0x000, + 0x003, 0x006, 0x000, 0x000, 0x004, 0x002, 0x001, 0x003, 0x003, 0x00A, 0x007, 0x000, 0x004, + 0x001, 0x006, 0x000, 0x001, 0x000, 0x000, 0x002, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x002, 0x001, 0x001, 0x001, 0x004, 0x000, 0x003, 0x000, 0x001, 0x000, 0x000, 0x001, + 0x000, 0x001, 0x000, 0x004, 0x000, 0x001, 0x000, 0x006, 0x000, 0x001, 0x000, 0x004, 0x000, + 0x001, 0x002, 0x006, 0x000, 0x002, 0x000, 0x003, 0x007, 0x000, 0x003, 0x000, 0x001, 0x001, + 0x000, 0x000, 0x003, 0x005, 0x002, 0x000, 0x001, 0x001, 0x002, 0x002, 0x004, 0x001, 0x000, + 0x000, 0x001, 0x000, 0x003, 0x002, 0x000, 0x001, 0x000, 0x002, 0x004, 0x002, 0x000, 0x001, + 0x005, 0x000, 0x000, 0x002, 0x001, 0x001, 0x000, 0x000, 0x001, 0x000, 0x005, 0x002, 0x000, + 0x008, 0x003, 0x001, 0x001, 0x001, 0x003, 0x004, 0x000, 0x002, 0x000, 0x001, 0x002, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x006, 0x000, 0x000, 0x000, 0x003, 0x000, 0x000, + 0x002, 0x002, 0x000, 0x001, 0x003, 0x001, 0x003, 0x001, 0x002, 0x000, 0x001, 0x002, 0x000, + 0x000, 0x001, 0x000, 0x003, 0x001, 0x002, 0x000, 0x002, 0x001, 0x000, 0x002, 0x004, 0x000, + 0x005, 0x005, 0x000, 0x005, 0x002, 0x000, 0x001, 0x003, 0x001, 0x000, 0x002, 0x006, 0x002, + 0x001, 0x000, 0x000, 0x000, 0x003, +]; +pub(crate) const COMPOSITION_TABLE_KV: &[(u32, char)] = &[ + (0x064A0654, '\u{000626}'), + (0x00690309, '\u{001EC9}'), + (0x00650306, '\u{000115}'), + (0x0423030B, '\u{0004F2}'), + (0x0047030C, '\u{0001E6}'), + (0x00570301, '\u{001E82}'), + (0x00C50301, '\u{0001FA}'), + (0x21D20338, '\u{0021CF}'), + (0x00430307, '\u{00010A}'), + (0x007A0307, '\u{00017C}'), + (0x0049030C, '\u{0001CF}'), + (0x00720307, '\u{001E59}'), + (0x304B3099, '\u{00304C}'), + (0x1F610345, '\u{001FA1}'), + (0x00410307, '\u{000226}'), + (0x006B0323, '\u{001E33}'), + (0x03990304, '\u{001FD9}'), + (0x1F490301, '\u{001F4D}'), + (0x03CA0342, '\u{001FD7}'), + (0x00550304, '\u{00016A}'), + (0x30DB309A, '\u{0030DD}'), + (0x1F6E0345, '\u{001FAE}'), + (0x00420331, '\u{001E06}'), + (0x041E0308, '\u{0004E6}'), + (0x00410325, '\u{001E00}'), + (0x00520331, '\u{001E5E}'), + (0x1FF60345, '\u{001FF7}'), + (0x22720338, '\u{002274}'), + (0x22480338, '\u{002249}'), + (0x1FBF0301, '\u{001FCE}'), + (0x30C63099, '\u{0030C7}'), + (0x00760323, '\u{001E7F}'), + (0x00700307, '\u{001E57}'), + (0x1F510301, '\u{001F55}'), + (0x00750328, '\u{000173}'), + (0x305B3099, '\u{00305C}'), + (0x0041030A, '\u{0000C5}'), + (0x01A10323, '\u{001EE3}'), + (0x00550311, '\u{000216}'), + (0x00530307, '\u{001E60}'), + (0x00DC030C, '\u{0001D9}'), + (0x004F0300, '\u{0000D2}'), + (0x006F0307, '\u{00022F}'), + (0x00470301, '\u{0001F4}'), + (0x00610309, '\u{001EA3}'), + (0x1F080301, '\u{001F0C}'), + (0x03B90301, '\u{0003AF}'), + (0x04330301, '\u{000453}'), + (0x1F200345, '\u{001F90}'), + (0x00620307, '\u{001E03}'), + (0x1F030345, '\u{001F83}'), + (0x00570308, '\u{001E84}'), + (0x005A0307, '\u{00017B}'), + (0x30C13099, '\u{0030C2}'), + (0x01A10309, '\u{001EDF}'), + (0x06270655, '\u{000625}'), + (0x03BF0314, '\u{001F41}'), + (0x00670301, '\u{0001F5}'), + (0x039F0301, '\u{00038C}'), + (0x00EA0301, '\u{001EBF}'), + (0x0063030C, '\u{00010D}'), + (0x1F000345, '\u{001F80}'), + (0x04130301, '\u{000403}'), + (0x004B0323, '\u{001E32}'), + (0x00790301, '\u{0000FD}'), + (0x00770301, '\u{001E83}'), + (0x1F0E0345, '\u{001F8E}'), + (0x00480308, '\u{001E26}'), + (0x30A63099, '\u{0030F4}'), + (0x01020300, '\u{001EB0}'), + (0x006C0301, '\u{00013A}'), + (0x00450309, '\u{001EBA}'), + (0x1F390301, '\u{001F3D}'), + (0x00690311, '\u{00020B}'), + (0x04230304, '\u{0004EE}'), + (0x0061030C, '\u{0001CE}'), + (0x1F100300, '\u{001F12}'), + (0x04380300, '\u{00045D}'), + (0x00480323, '\u{001E24}'), + (0x1B111B35, '\u{001B12}'), + (0x00430301, '\u{000106}'), + (0x00540323, '\u{001E6C}'), + (0x00490303, '\u{000128}'), + (0x1EA10302, '\u{001EAD}'), + (0x04350308, '\u{000451}'), + (0x00610307, '\u{000227}'), + (0x1F000300, '\u{001F02}'), + (0x006D0307, '\u{001E41}'), + (0x00760303, '\u{001E7D}'), + (0x00730327, '\u{00015F}'), + (0x00470304, '\u{001E20}'), + (0x00470306, '\u{00011E}'), + (0x1F6D0345, '\u{001FAD}'), + (0x006F0303, '\u{0000F5}'), + (0x006B0331, '\u{001E35}'), + (0x00720331, '\u{001E5F}'), + (0x01B00300, '\u{001EEB}'), + (0x1B0B1B35, '\u{001B0C}'), + (0x0055032D, '\u{001E76}'), + (0x0061030A, '\u{0000E5}'), + (0x30463099, '\u{003094}'), + (0x1B3A1B35, '\u{001B3B}'), + (0x0055030A, '\u{00016E}'), + (0x0928093C, '\u{000929}'), + (0x03C90313, '\u{001F60}'), + (0x00650330, '\u{001E1B}'), + (0x00590303, '\u{001EF8}'), + (0x00450330, '\u{001E1A}'), + (0x00640331, '\u{001E0F}'), + (0x03B90308, '\u{0003CA}'), + (0x309D3099, '\u{00309E}'), + (0x0443030B, '\u{0004F3}'), + (0x0B470B3E, '\u{000B4B}'), + (0x006F030F, '\u{00020D}'), + (0x006E0323, '\u{001E47}'), + (0x00690308, '\u{0000EF}'), + (0x0065032D, '\u{001E19}'), + (0x015A0307, '\u{001E64}'), + (0x1F180301, '\u{001F1C}'), + (0x1F090301, '\u{001F0D}'), + (0x1F270345, '\u{001F97}'), + (0x007A0302, '\u{001E91}'), + (0x00590301, '\u{0000DD}'), + (0x004C0331, '\u{001E3A}'), + (0x1F640345, '\u{001FA4}'), + (0x1EB90302, '\u{001EC7}'), + (0x1F240345, '\u{001F94}'), + (0x01130300, '\u{001E15}'), + (0x0069030F, '\u{000209}'), + (0x00740331, '\u{001E6F}'), + (0x1F480301, '\u{001F4C}'), + (0x007A0331, '\u{001E95}'), + (0x1F290345, '\u{001F99}'), + (0x00D40301, '\u{001ED0}'), + (0x00C40304, '\u{0001DE}'), + (0x03970301, '\u{000389}'), + (0x0072030C, '\u{000159}'), + (0x1F110301, '\u{001F15}'), + (0x00F40309, '\u{001ED5}'), + (0x00450327, '\u{000228}'), + (0x006F031B, '\u{0001A1}'), + (0x00C60304, '\u{0001E2}'), + (0x03990308, '\u{0003AA}'), + (0x03CE0345, '\u{001FF4}'), + (0x006D0301, '\u{001E3F}'), + (0x01030309, '\u{001EB3}'), + (0x006F0302, '\u{0000F4}'), + (0x0073030C, '\u{000161}'), + (0x00750301, '\u{0000FA}'), + (0x1F690301, '\u{001F6D}'), + (0x03A90301, '\u{00038F}'), + (0x003D0338, '\u{002260}'), + (0x1FC60345, '\u{001FC7}'), + (0x00770300, '\u{001E81}'), + (0x02280306, '\u{001E1C}'), + (0x006C0331, '\u{001E3B}'), + (0x30AD3099, '\u{0030AE}'), + (0x1EB80302, '\u{001EC6}'), + (0x00550302, '\u{0000DB}'), + (0x0DD90DCF, '\u{000DDC}'), + (0x03A50304, '\u{001FE9}'), + (0x03A90314, '\u{001F69}'), + (0x00740327, '\u{000163}'), + (0x00530326, '\u{000218}'), + (0x0055030B, '\u{000170}'), + (0x306F309A, '\u{003071}'), + (0x006B0327, '\u{000137}'), + (0x00750330, '\u{001E75}'), + (0x00730301, '\u{00015B}'), + (0x1F300342, '\u{001F36}'), + (0x00470307, '\u{000120}'), + (0x0CC60CD5, '\u{000CC7}'), + (0x1F690300, '\u{001F6B}'), + (0x01030301, '\u{001EAF}'), + (0x00750311, '\u{000217}'), + (0x0930093C, '\u{000931}'), + (0x30613099, '\u{003062}'), + (0x00770323, '\u{001E89}'), + (0x00F50301, '\u{001E4D}'), + (0x00FC0300, '\u{0001DC}'), + (0x0049030F, '\u{000208}'), + (0x00690302, '\u{0000EE}'), + (0x1F230345, '\u{001F93}'), + (0x00F40300, '\u{001ED3}'), + (0x044B0308, '\u{0004F9}'), + (0x1F2E0345, '\u{001F9E}'), + (0x00650300, '\u{0000E8}'), + (0x00490308, '\u{0000CF}'), + (0x1F280301, '\u{001F2C}'), + (0x1F180300, '\u{001F1A}'), + (0x06270653, '\u{000622}'), + (0x1F200301, '\u{001F24}'), + (0x22030338, '\u{002204}'), + (0x00790304, '\u{000233}'), + (0x1F390300, '\u{001F3B}'), + (0x00610325, '\u{001E01}'), + (0x00790309, '\u{001EF7}'), + (0x01AF0303, '\u{001EEE}'), + (0x006F0301, '\u{0000F3}'), + (0x00640323, '\u{001E0D}'), + (0x304F3099, '\u{003050}'), + (0x1F010345, '\u{001F81}'), + (0x00CA0309, '\u{001EC2}'), + (0x03D20308, '\u{0003D4}'), + (0x1F500301, '\u{001F54}'), + (0x1F010300, '\u{001F03}'), + (0x03A90345, '\u{001FFC}'), + (0x04270308, '\u{0004F4}'), + (0x00530302, '\u{00015C}'), + (0x00520301, '\u{000154}'), + (0x00450306, '\u{000114}'), + (0x00530323, '\u{001E62}'), + (0x00670306, '\u{00011F}'), + (0x22760338, '\u{002278}'), + (0x04350300, '\u{000450}'), + (0x30B53099, '\u{0030B6}'), + (0x006F030B, '\u{000151}'), + (0x04180304, '\u{0004E2}'), + (0x00630307, '\u{00010B}'), + (0x03D20301, '\u{0003D3}'), + (0x227C0338, '\u{0022E0}'), + (0x00610304, '\u{000101}'), + (0x00A80300, '\u{001FED}'), + (0x00440331, '\u{001E0E}'), + (0x00650311, '\u{000207}'), + (0x00F80301, '\u{0001FF}'), + (0x0075030C, '\u{0001D4}'), + (0x00530327, '\u{00015E}'), + (0x30573099, '\u{003058}'), + (0x03B70345, '\u{001FC3}'), + (0x0069030C, '\u{0001D0}'), + (0x006E0327, '\u{000146}'), + (0x00780307, '\u{001E8B}'), + (0x1F000342, '\u{001F06}'), + (0x01B00303, '\u{001EEF}'), + (0x00470327, '\u{000122}'), + (0x00C20309, '\u{001EA8}'), + (0x006C032D, '\u{001E3D}'), + (0x304D3099, '\u{00304E}'), + (0x00690303, '\u{000129}'), + (0x01AF0323, '\u{001EF0}'), + (0x004F0302, '\u{0000D4}'), + (0x01020301, '\u{001EAE}'), + (0x04470308, '\u{0004F5}'), + (0x22A80338, '\u{0022AD}'), + (0x03C50300, '\u{001F7A}'), + (0x03910313, '\u{001F08}'), + (0x0064032D, '\u{001E13}'), + (0x00CF0301, '\u{001E2E}'), + (0x0061030F, '\u{000201}'), + (0x1EA10306, '\u{001EB7}'), + (0x00790323, '\u{001EF5}'), + (0x21900338, '\u{00219A}'), + (0x1F250345, '\u{001F95}'), + (0x004F0304, '\u{00014C}'), + (0x004F0306, '\u{00014E}'), + (0x30B33099, '\u{0030B4}'), + (0x00440327, '\u{001E10}'), + (0x0B920BD7, '\u{000B94}'), + (0x00550308, '\u{0000DC}'), + (0x00650323, '\u{001EB9}'), + (0x307B3099, '\u{00307C}'), + (0x004F030C, '\u{0001D1}'), + (0x00670304, '\u{001E21}'), + (0x006A030C, '\u{0001F0}'), + (0x00550323, '\u{001EE4}'), + (0x01A10301, '\u{001EDB}'), + (0x00590323, '\u{001EF4}'), + (0x00410300, '\u{0000C0}'), + (0x30B93099, '\u{0030BA}'), + (0x04230308, '\u{0004F0}'), + (0x00530301, '\u{00015A}'), + (0x30D8309A, '\u{0030DA}'), + (0x00750309, '\u{001EE7}'), + (0x00550330, '\u{001E74}'), + (0x00520327, '\u{000156}'), + (0x04370308, '\u{0004DF}'), + (0x00CA0300, '\u{001EC0}'), + (0x21940338, '\u{0021AE}'), + (0x03B10306, '\u{001FB0}'), + (0x1F610342, '\u{001F67}'), + (0x223C0338, '\u{002241}'), + (0x30D23099, '\u{0030D3}'), + (0x1F6B0345, '\u{001FAB}'), + (0x00490307, '\u{000130}'), + (0x00410323, '\u{001EA0}'), + (0x00550309, '\u{001EE6}'), + (0x0075030B, '\u{000171}'), + (0x30533099, '\u{003054}'), + (0x305D3099, '\u{00305E}'), + (0x004C0323, '\u{001E36}'), + (0x02260304, '\u{0001E0}'), + (0x0475030F, '\u{000477}'), + (0x00490328, '\u{00012E}'), + (0x1F210300, '\u{001F23}'), + (0x1F610301, '\u{001F65}'), + (0x1F210342, '\u{001F27}'), + (0x00670302, '\u{00011D}'), + (0x004E0301, '\u{000143}'), + (0x004E0303, '\u{0000D1}'), + (0x03990300, '\u{001FDA}'), + (0x03BF0301, '\u{0003CC}'), + (0x04150300, '\u{000400}'), + (0x03C90314, '\u{001F61}'), + (0x22A20338, '\u{0022AC}'), + (0x30DB3099, '\u{0030DC}'), + (0x03A50314, '\u{001F59}'), + (0x0052030F, '\u{000210}'), + (0x004E0323, '\u{001E46}'), + (0x1F0D0345, '\u{001F8D}'), + (0x1ECD0302, '\u{001ED9}'), + (0x00FC030C, '\u{0001DA}'), + (0x00D60304, '\u{00022A}'), + (0x1F000301, '\u{001F04}'), + (0x30CF3099, '\u{0030D0}'), + (0x04350306, '\u{0004D7}'), + (0x220B0338, '\u{00220C}'), + (0x00590300, '\u{001EF2}'), + (0x04170308, '\u{0004DE}'), + (0x006E030C, '\u{000148}'), + (0x004C030C, '\u{00013D}'), + (0x01690301, '\u{001E79}'), + (0x04100308, '\u{0004D2}'), + (0x01A00301, '\u{001EDA}'), + (0x0041030F, '\u{000200}'), + (0x00720301, '\u{000155}'), + (0x00450303, '\u{001EBC}'), + (0x1B0D1B35, '\u{001B0E}'), + (0x01120301, '\u{001E16}'), + (0x004A0302, '\u{000134}'), + (0x03BF0300, '\u{001F78}'), + (0x30593099, '\u{00305A}'), + (0x004F030B, '\u{000150}'), + (0x00610328, '\u{000105}'), + (0x30D83099, '\u{0030D9}'), + (0x1F2B0345, '\u{001F9B}'), + (0x1F400301, '\u{001F44}'), + (0x0065030F, '\u{000205}'), + (0x03AE0345, '\u{001FC4}'), + (0x01680301, '\u{001E78}'), + (0x00740326, '\u{00021B}'), + (0x03B90342, '\u{001FD6}'), + (0x1F6F0345, '\u{001FAF}'), + (0x03A50301, '\u{00038E}'), + (0x1F090345, '\u{001F89}'), + (0x00550300, '\u{0000D9}'), + (0x0041030C, '\u{0001CD}'), + (0x00430327, '\u{0000C7}'), + (0x00460307, '\u{001E1E}'), + (0x03B50301, '\u{0003AD}'), + (0x0D470D3E, '\u{000D4B}'), + (0x00610311, '\u{000203}'), + (0x00D50308, '\u{001E4E}'), + (0x03C90300, '\u{001F7C}'), + (0x04430306, '\u{00045E}'), + (0x1FFE0301, '\u{001FDE}'), + (0x03990301, '\u{00038A}'), + (0x00790307, '\u{001E8F}'), + (0x1E5A0304, '\u{001E5C}'), + (0x0075030F, '\u{000215}'), + (0x09C709BE, '\u{0009CB}'), + (0x1B071B35, '\u{001B08}'), + (0x00690330, '\u{001E2D}'), + (0x307B309A, '\u{00307D}'), + (0x30C83099, '\u{0030C9}'), + (0x22B30338, '\u{0022EB}'), + (0x01B00301, '\u{001EE9}'), + (0x00790300, '\u{001EF3}'), + (0x00570307, '\u{001E86}'), + (0x00690328, '\u{00012F}'), + (0x005A0323, '\u{001E92}'), + (0x03C50342, '\u{001FE6}'), + (0x004F0309, '\u{001ECE}'), + (0x1F290342, '\u{001F2F}'), + (0x01A00300, '\u{001EDC}'), + (0x1F2A0345, '\u{001F9A}'), + (0x014D0301, '\u{001E53}'), + (0x21D00338, '\u{0021CD}'), + (0x00550328, '\u{000172}'), + (0x00680331, '\u{001E96}'), + (0x0068030C, '\u{00021F}'), + (0x004C0301, '\u{000139}'), + (0x22860338, '\u{002288}'), + (0x039F0314, '\u{001F49}'), + (0x03A50306, '\u{001FE8}'), + (0x0B470B56, '\u{000B48}'), + (0x30753099, '\u{003076}'), + (0x1E5B0304, '\u{001E5D}'), + (0x1F6A0345, '\u{001FAA}'), + (0x00540327, '\u{000162}'), + (0x01020303, '\u{001EB4}'), + (0x039F0313, '\u{001F48}'), + (0x1F090342, '\u{001F0F}'), + (0x04100306, '\u{0004D0}'), + (0x014D0300, '\u{001E51}'), + (0x04430304, '\u{0004EF}'), + (0x21920338, '\u{00219B}'), + (0x22610338, '\u{002262}'), + (0x00F50304, '\u{00022D}'), + (0x03B90313, '\u{001F30}'), + (0x006F0308, '\u{0000F6}'), + (0x00730307, '\u{001E61}'), + (0x0075031B, '\u{0001B0}'), + (0x30B73099, '\u{0030B8}'), + (0x1E620307, '\u{001E68}'), + (0x00410306, '\u{000102}'), + (0x03970314, '\u{001F29}'), + (0x00630302, '\u{000109}'), + (0x006A0302, '\u{000135}'), + (0x00E50301, '\u{0001FB}'), + (0x00730326, '\u{000219}'), + (0x1F740345, '\u{001FC2}'), + (0x00650309, '\u{001EBB}'), + (0x005A030C, '\u{00017D}'), + (0x22250338, '\u{002226}'), + (0x03A90313, '\u{001F68}'), + (0x00720327, '\u{000157}'), + (0x1F090300, '\u{001F0B}'), + (0x04360308, '\u{0004DD}'), + (0x1F080345, '\u{001F88}'), + (0x00620331, '\u{001E07}'), + (0x22730338, '\u{002275}'), + (0x00560323, '\u{001E7E}'), + (0x004F0323, '\u{001ECC}'), + (0x022E0304, '\u{000230}'), + (0x06D50654, '\u{0006C0}'), + (0x03B10313, '\u{001F00}'), + (0x004F0303, '\u{0000D5}'), + (0x1F010301, '\u{001F05}'), + (0x00650304, '\u{000113}'), + (0x00450323, '\u{001EB8}'), + (0x0BC60BBE, '\u{000BCA}'), + (0x22650338, '\u{002271}'), + (0x03910314, '\u{001F09}'), + (0x01120300, '\u{001E14}'), + (0x004E0307, '\u{001E44}'), + (0x00680308, '\u{001E27}'), + (0x004F0311, '\u{00020E}'), + (0x00550303, '\u{000168}'), + (0x03A10314, '\u{001FEC}'), + (0x03B10301, '\u{0003AC}'), + (0x0055030F, '\u{000214}'), + (0x003E0338, '\u{00226F}'), + (0x01610307, '\u{001E67}'), + (0x1F040345, '\u{001F84}'), + (0x00450300, '\u{0000C8}'), + (0x1B091B35, '\u{001B0A}'), + (0x30FD3099, '\u{0030FE}'), + (0x1F680301, '\u{001F6C}'), + (0x00650303, '\u{001EBD}'), + (0x03B90304, '\u{001FD1}'), + (0x09C709D7, '\u{0009CC}'), + (0x042B0308, '\u{0004F8}'), + (0x004E0327, '\u{000145}'), + (0x1F630345, '\u{001FA3}'), + (0x04380306, '\u{000439}'), + (0x03B10314, '\u{001F01}'), + (0x00540326, '\u{00021A}'), + (0x00740307, '\u{001E6B}'), + (0x03C90301, '\u{0003CE}'), + (0x03990314, '\u{001F39}'), + (0x30B13099, '\u{0030B2}'), + (0x00750302, '\u{0000FB}'), + (0x0CC60CD6, '\u{000CC8}'), + (0x30BD3099, '\u{0030BE}'), + (0x006E0300, '\u{0001F9}'), + (0x1F390342, '\u{001F3F}'), + (0x02270304, '\u{0001E1}'), + (0x22080338, '\u{002209}'), + (0x04180306, '\u{000419}'), + (0x0044030C, '\u{00010E}'), + (0x0075030A, '\u{00016F}'), + (0x06270654, '\u{000623}'), + (0x00750306, '\u{00016D}'), + (0x03B70300, '\u{001F74}'), + (0x1F660345, '\u{001FA6}'), + (0x1F690345, '\u{001FA9}'), + (0x015B0307, '\u{001E65}'), + (0x1F280342, '\u{001F2E}'), + (0x1F700345, '\u{001FB2}'), + (0x1F0F0345, '\u{001F8F}'), + (0x00540331, '\u{001E6E}'), + (0x227B0338, '\u{002281}'), + (0x22870338, '\u{002289}'), + (0x1F010342, '\u{001F07}'), + (0x03A50308, '\u{0003AB}'), + (0x1F650345, '\u{001FA5}'), + (0x00D40300, '\u{001ED2}'), + (0x00F60304, '\u{00022B}'), + (0x0CBF0CD5, '\u{000CC0}'), + (0x1F380342, '\u{001F3E}'), + (0x22B20338, '\u{0022EA}'), + (0x0072030F, '\u{000211}'), + (0x30BF3099, '\u{0030C0}'), + (0x04E90308, '\u{0004EB}'), + (0x22830338, '\u{002285}'), + (0x03CB0300, '\u{001FE2}'), + (0x00CA0301, '\u{001EBE}'), + (0x00590304, '\u{000232}'), + (0x00690301, '\u{0000ED}'), + (0x305F3099, '\u{003060}'), + (0x00440307, '\u{001E0A}'), + (0x1ECC0302, '\u{001ED8}'), + (0x1F210345, '\u{001F91}'), + (0x00410311, '\u{000202}'), + (0x00720311, '\u{000213}'), + (0x03A50300, '\u{001FEA}'), + (0x1F590300, '\u{001F5B}'), + (0x00E40304, '\u{0001DF}'), + (0x1F500300, '\u{001F52}'), + (0x224D0338, '\u{00226D}'), + (0x006E0301, '\u{000144}'), + (0x0075032D, '\u{001E77}'), + (0x00F40301, '\u{001ED1}'), + (0x03C90342, '\u{001FF6}'), + (0x03B70301, '\u{0003AE}'), + (0x006E0307, '\u{001E45}'), + (0x00410304, '\u{000100}'), + (0x1F190301, '\u{001F1D}'), + (0x03B10304, '\u{001FB1}'), + (0x3078309A, '\u{00307A}'), + (0x00570323, '\u{001E88}'), + (0x04430308, '\u{0004F1}'), + (0x0045032D, '\u{001E18}'), + (0x04150308, '\u{000401}'), + (0x004F0328, '\u{0001EA}'), + (0x04D90308, '\u{0004DB}'), + (0x04060308, '\u{000407}'), + (0x00F40303, '\u{001ED7}'), + (0x03B90306, '\u{001FD0}'), + (0x00650307, '\u{000117}'), + (0x1F680342, '\u{001F6E}'), + (0x04380304, '\u{0004E3}'), + (0x1F410300, '\u{001F43}'), + (0x1FFE0300, '\u{001FDD}'), + (0x004F0301, '\u{0000D3}'), + (0x00640327, '\u{001E11}'), + (0x02290306, '\u{001E1D}'), + (0x007A0301, '\u{00017A}'), + (0x00620323, '\u{001E05}'), + (0x1F7C0345, '\u{001FF2}'), + (0x01B00323, '\u{001EF1}'), + (0x1F600301, '\u{001F64}'), + (0x30663099, '\u{003067}'), + (0x22640338, '\u{002270}'), + (0x1F310300, '\u{001F33}'), + (0x00610323, '\u{001EA1}'), + (0x1F480300, '\u{001F4A}'), + (0x00550301, '\u{0000DA}'), + (0x0C460C56, '\u{000C48}'), + (0x03CA0300, '\u{001FD2}'), + (0x01B7030C, '\u{0001EE}'), + (0x00720323, '\u{001E5B}'), + (0x1F200342, '\u{001F26}'), + (0x04300308, '\u{0004D3}'), + (0x22820338, '\u{002284}'), + (0x1F590301, '\u{001F5D}'), + (0x1F080342, '\u{001F0E}'), + (0x00440323, '\u{001E0C}'), + (0x1025102E, '\u{001026}'), + (0x03910304, '\u{001FB9}'), + (0x004B0331, '\u{001E34}'), + (0x00690300, '\u{0000EC}'), + (0x0048032E, '\u{001E2A}'), + (0x00630301, '\u{000107}'), + (0x1F690342, '\u{001F6F}'), + (0x03B50313, '\u{001F10}'), + (0x30CF309A, '\u{0030D1}'), + (0x004E030C, '\u{000147}'), + (0x0B470B57, '\u{000B4C}'), + (0x03910301, '\u{000386}'), + (0x00650328, '\u{000119}'), + (0x1FBF0300, '\u{001FCD}'), + (0x03B70342, '\u{001FC6}'), + (0x00450307, '\u{000116}'), + (0x1F380301, '\u{001F3C}'), + (0x3075309A, '\u{003077}'), + (0x004B0301, '\u{001E30}'), + (0x01030300, '\u{001EB1}'), + (0x00E20303, '\u{001EAB}'), + (0x00410302, '\u{0000C2}'), + (0x00650308, '\u{0000EB}'), + (0x00580307, '\u{001E8A}'), + (0x0054030C, '\u{000164}'), + (0x03C50313, '\u{001F50}'), + (0x03B50314, '\u{001F11}'), + (0x1B3E1B35, '\u{001B40}'), + (0x1F100301, '\u{001F14}'), + (0x3072309A, '\u{003074}'), + (0x1F280345, '\u{001F98}'), + (0x22770338, '\u{002279}'), + (0x227A0338, '\u{002280}'), + (0x00470302, '\u{00011C}'), + (0x00450308, '\u{0000CB}'), + (0x00550324, '\u{001E72}'), + (0x1F2C0345, '\u{001F9C}'), + (0x004B0327, '\u{000136}'), + (0x00490302, '\u{0000CE}'), + (0x00680302, '\u{000125}'), + (0x00520307, '\u{001E58}'), + (0x00610301, '\u{0000E1}'), + (0x004B030C, '\u{0001E8}'), + (0x00490309, '\u{001EC8}'), + (0x006C030C, '\u{00013E}'), + (0x004D0307, '\u{001E40}'), + (0x1E360304, '\u{001E38}'), + (0x03C50304, '\u{001FE1}'), + (0x0079030A, '\u{001E99}'), + (0x03970313, '\u{001F28}'), + (0x0054032D, '\u{001E70}'), + (0x1F490300, '\u{001F4B}'), + (0x1B421B35, '\u{001B43}'), + (0x03B70313, '\u{001F20}'), + (0x00EF0301, '\u{001E2F}'), + (0x00E70301, '\u{001E09}'), + (0x016A0308, '\u{001E7A}'), + (0x00CA0303, '\u{001EC4}'), + (0x03B10300, '\u{001F70}'), + (0x06D20654, '\u{0006D3}'), + (0x30D53099, '\u{0030D6}'), + (0x1F2F0345, '\u{001F9F}'), + (0x03B50300, '\u{001F72}'), + (0x00750324, '\u{001E73}'), + (0x04150306, '\u{0004D6}'), + (0x0065030C, '\u{00011B}'), + (0x00570302, '\u{000174}'), + (0x1EA00306, '\u{001EB6}'), + (0x1F070345, '\u{001F87}'), + (0x00A80301, '\u{000385}'), + (0x00790302, '\u{000177}'), + (0x006E032D, '\u{001E4B}'), + (0x006F030C, '\u{0001D2}'), + (0x03C90345, '\u{001FF3}'), + (0x00430302, '\u{000108}'), + (0x00790303, '\u{001EF9}'), + (0x00740323, '\u{001E6D}'), + (0x00E20309, '\u{001EA9}'), + (0x1F300300, '\u{001F32}'), + (0x006B0301, '\u{001E31}'), + (0x22920338, '\u{0022E3}'), + (0x03950314, '\u{001F19}'), + (0x1F290301, '\u{001F2D}'), + (0x00450328, '\u{000118}'), + (0x1FB60345, '\u{001FB7}'), + (0x00D50304, '\u{00022C}'), + (0x04300306, '\u{0004D1}'), + (0x00F50308, '\u{001E4F}'), + (0x1EA00302, '\u{001EAC}'), + (0x1F680300, '\u{001F6A}'), + (0x03970300, '\u{001FCA}'), + (0x00450301, '\u{0000C9}'), + (0x00690304, '\u{00012B}'), + (0x0BC60BD7, '\u{000BCC}'), + (0x006F0304, '\u{00014D}'), + (0x004F0308, '\u{0000D6}'), + (0x0BC70BBE, '\u{000BCB}'), + (0x0055030C, '\u{0001D3}'), + (0x03AC0345, '\u{001FB4}'), + (0x1FBF0342, '\u{001FCF}'), + (0x30D2309A, '\u{0030D4}'), + (0x00660307, '\u{001E1F}'), + (0x004E0300, '\u{0001F8}'), + (0x00790308, '\u{0000FF}'), + (0x0068032E, '\u{001E2B}'), + (0x0064030C, '\u{00010F}'), + (0x004F0307, '\u{00022E}'), + (0x1F590342, '\u{001F5F}'), + (0x30AF3099, '\u{0030B0}'), + (0x00E60304, '\u{0001E3}'), + (0x03C50301, '\u{0003CD}'), + (0x00770308, '\u{001E85}'), + (0x03B90314, '\u{001F31}'), + (0x00750323, '\u{001EE5}'), + (0x00590309, '\u{001EF6}'), + (0x0292030C, '\u{0001EF}'), + (0x00550306, '\u{00016C}'), + (0x00E60301, '\u{0001FD}'), + (0x016B0308, '\u{001E7B}'), + (0x004F030F, '\u{00020C}'), + (0x03BF0313, '\u{001F40}'), + (0x00D80301, '\u{0001FE}'), + (0x00C20303, '\u{001EAA}'), + (0x1F510300, '\u{001F53}'), + (0x01B00309, '\u{001EED}'), + (0x004E032D, '\u{001E4A}'), + (0x006F0309, '\u{001ECF}'), + (0x04180300, '\u{00040D}'), + (0x22A90338, '\u{0022AE}'), + (0x1F680345, '\u{001FA8}'), + (0x1B3C1B35, '\u{001B3D}'), + (0x1F400300, '\u{001F42}'), + (0x1F0B0345, '\u{001F8B}'), + (0x03C50306, '\u{001FE0}'), + (0x0044032D, '\u{001E12}'), + (0x0CCA0CD5, '\u{000CCB}'), + (0x00EA0303, '\u{001EC5}'), + (0x04230306, '\u{00040E}'), + (0x00C70301, '\u{001E08}'), + (0x007A030C, '\u{00017E}'), + (0x00670307, '\u{000121}'), + (0x00450311, '\u{000206}'), + (0x006F0300, '\u{0000F2}'), + (0x30BB3099, '\u{0030BC}'), + (0x04180308, '\u{0004E4}'), + (0x30513099, '\u{003052}'), + (0x006C0323, '\u{001E37}'), + (0x03B70314, '\u{001F21}'), + (0x0077030A, '\u{001E98}'), + (0x00690323, '\u{001ECB}'), + (0x00610303, '\u{0000E3}'), + (0x30F13099, '\u{0030F9}'), + (0x03B10345, '\u{001FB3}'), + (0x0D460D3E, '\u{000D4A}'), + (0x03B90300, '\u{001F76}'), + (0x21D40338, '\u{0021CE}'), + (0x1F620345, '\u{001FA2}'), + (0x00770302, '\u{000175}'), + (0x00FC0304, '\u{0001D6}'), + (0x01130301, '\u{001E17}'), + (0x30683099, '\u{003069}'), + (0x1F600342, '\u{001F66}'), + (0x00680323, '\u{001E25}'), + (0x03950313, '\u{001F18}'), + (0x00EA0300, '\u{001EC1}'), + (0x03CB0342, '\u{001FE7}'), + (0x22430338, '\u{002244}'), + (0x30783099, '\u{003079}'), + (0x03990313, '\u{001F38}'), + (0x00490330, '\u{001E2C}'), + (0x00770307, '\u{001E87}'), + (0x00650301, '\u{0000E9}'), + (0x00680327, '\u{001E29}'), + (0x22B50338, '\u{0022ED}'), + (0x03B10342, '\u{001FB6}'), + (0x03910306, '\u{001FB8}'), + (0x004D0301, '\u{001E3E}'), + (0x00410309, '\u{001EA2}'), + (0x1B051B35, '\u{001B06}'), + (0x003C0338, '\u{00226E}'), + (0x00590308, '\u{000178}'), + (0x01030303, '\u{001EB5}'), + (0x00480327, '\u{001E28}'), + (0x006D0323, '\u{001E43}'), + (0x30643099, '\u{003065}'), + (0x04560308, '\u{000457}'), + (0x00590302, '\u{000176}'), + (0x06C10654, '\u{0006C2}'), + (0x043A0301, '\u{00045C}'), + (0x00E20300, '\u{001EA7}'), + (0x03950301, '\u{000388}'), + (0x00630327, '\u{0000E7}'), + (0x017F0307, '\u{001E9B}'), + (0x06480654, '\u{000624}'), + (0x30AB3099, '\u{0030AC}'), + (0x01A00323, '\u{001EE2}'), + (0x04D80308, '\u{0004DA}'), + (0x005A0331, '\u{001E94}'), + (0x0067030C, '\u{0001E7}'), + (0x039F0300, '\u{001FF8}'), + (0x00650327, '\u{000229}'), + (0x00490323, '\u{001ECA}'), + (0x1F110300, '\u{001F13}'), + (0x1F510342, '\u{001F57}'), + (0x004D0323, '\u{001E42}'), + (0x1F300301, '\u{001F34}'), + (0x006C0327, '\u{00013C}'), + (0x1F050345, '\u{001F85}'), + (0x01A10300, '\u{001EDD}'), + (0x04160308, '\u{0004DC}'), + (0x00640307, '\u{001E0B}'), + (0x004C032D, '\u{001E3C}'), + (0x03C10314, '\u{001FE5}'), + (0x01EA0304, '\u{0001EC}'), + (0x1F080300, '\u{001F0A}'), + (0x00650302, '\u{0000EA}'), + (0x03910300, '\u{001FBA}'), + (0x00700301, '\u{001E55}'), + (0x1F020345, '\u{001F82}'), + (0x01020309, '\u{001EB2}'), + (0x00750303, '\u{000169}'), + (0x1F0C0345, '\u{001F8C}'), + (0x03CB0301, '\u{0003B0}'), + (0x00740308, '\u{001E97}'), + (0x03950300, '\u{001FC8}'), + (0x227D0338, '\u{0022E1}'), + (0x007A0323, '\u{001E93}'), + (0x006F0311, '\u{00020F}'), + (0x006F0328, '\u{0001EB}'), + (0x1F200300, '\u{001F22}'), + (0x1F190300, '\u{001F1B}'), + (0x00560303, '\u{001E7C}'), + (0x006B030C, '\u{0001E9}'), + (0x04E80308, '\u{0004EA}'), + (0x03A90300, '\u{001FFA}'), + (0x00A80342, '\u{001FC1}'), + (0x04360306, '\u{0004C2}'), + (0x00DC0301, '\u{0001D7}'), + (0x00750304, '\u{00016B}'), + (0x22450338, '\u{002247}'), + (0x00490304, '\u{00012A}'), + (0x04380308, '\u{0004E5}'), + (0x0D460D57, '\u{000D4C}'), + (0x00750300, '\u{0000F9}'), + (0x22B40338, '\u{0022EC}'), + (0x00750308, '\u{0000FC}'), + (0x03C50314, '\u{001F51}'), + (0x01600307, '\u{001E66}'), + (0x04160306, '\u{0004C1}'), + (0x0055031B, '\u{0001AF}'), + (0x22AB0338, '\u{0022AF}'), + (0x014C0300, '\u{001E50}'), + (0x1F310342, '\u{001F37}'), + (0x1F260345, '\u{001F96}'), + (0x22910338, '\u{0022E2}'), + (0x00500301, '\u{001E54}'), + (0x004C0327, '\u{00013B}'), + (0x005A0301, '\u{000179}'), + (0x00420307, '\u{001E02}'), + (0x03C10313, '\u{001FE4}'), + (0x1F410301, '\u{001F45}'), + (0x00500307, '\u{001E56}'), + (0x0043030C, '\u{00010C}'), + (0x00730323, '\u{001E63}'), + (0x30553099, '\u{003056}'), + (0x306F3099, '\u{003070}'), + (0x044D0308, '\u{0004ED}'), + (0x1F670345, '\u{001FA7}'), + (0x01AF0301, '\u{001EE8}'), + (0x1F290300, '\u{001F2B}'), + (0x1B3F1B35, '\u{001B41}'), + (0x00450302, '\u{0000CA}'), + (0x006F0306, '\u{00014F}'), + (0x00FC0301, '\u{0001D8}'), + (0x30F23099, '\u{0030FA}'), + (0x1F2D0345, '\u{001F9D}'), + (0x014C0301, '\u{001E52}'), + (0x00610308, '\u{0000E4}'), + (0x1F600345, '\u{001FA0}'), + (0x1F0A0345, '\u{001F8A}'), + (0x00610306, '\u{000103}'), + (0x1F600300, '\u{001F62}'), + (0x01AF0300, '\u{001EEA}'), + (0x043E0308, '\u{0004E7}'), + (0x22230338, '\u{002224}'), + (0x03CA0301, '\u{000390}'), + (0x30D5309A, '\u{0030D7}'), + (0x1F220345, '\u{001F92}'), + (0x00D50301, '\u{001E4C}'), + (0x1F6C0345, '\u{001FAC}'), + (0x00540307, '\u{001E6A}'), + (0x1E370304, '\u{001E39}'), + (0x0DD90DCA, '\u{000DDA}'), + (0x01A10303, '\u{001EE1}'), + (0x0048030C, '\u{00021E}'), + (0x00EA0309, '\u{001EC3}'), + (0x0052030C, '\u{000158}'), + (0x00D40303, '\u{001ED6}'), + (0x0045030C, '\u{00011A}'), + (0x30EF3099, '\u{0030F7}'), + (0x00480302, '\u{000124}'), + (0x00520323, '\u{001E5A}'), + (0x00C20300, '\u{001EA6}'), + (0x0074032D, '\u{001E71}'), + (0x042D0308, '\u{0004EC}'), + (0x0DD90DDF, '\u{000DDE}'), + (0x00410308, '\u{0000C4}'), + (0x0474030F, '\u{000476}'), + (0x00C60301, '\u{0001FC}'), + (0x1F310301, '\u{001F35}'), + (0x1F610300, '\u{001F63}'), + (0x0CC60CC2, '\u{000CCA}'), + (0x00C20301, '\u{001EA4}'), + (0x03C50308, '\u{0003CB}'), + (0x00E20301, '\u{001EA5}'), + (0x1F500342, '\u{001F56}'), + (0x00610300, '\u{0000E0}'), + (0x00490311, '\u{00020A}'), + (0x00670327, '\u{000123}'), + (0x00590307, '\u{001E8E}'), + (0x03970345, '\u{001FCC}'), + (0x00D40309, '\u{001ED4}'), + (0x01A00303, '\u{001EE0}'), + (0x1FFE0342, '\u{001FDF}'), + (0x041A0301, '\u{00040C}'), + (0x0074030C, '\u{000165}'), + (0x00DC0300, '\u{0001DB}'), + (0x00780308, '\u{001E8D}'), + (0x00DC0304, '\u{0001D5}'), + (0x00610302, '\u{0000E2}'), + (0x005A0302, '\u{001E90}'), + (0x0933093C, '\u{000934}'), + (0x004F031B, '\u{0001A0}'), + (0x00520311, '\u{000212}'), + (0x006E0303, '\u{0000F1}'), + (0x0045030F, '\u{000204}'), + (0x01AF0309, '\u{001EEC}'), + (0x00450304, '\u{000112}'), + (0x1F210301, '\u{001F25}'), + (0x022F0304, '\u{000231}'), + (0x03990306, '\u{001FD8}'), + (0x004E0331, '\u{001E48}'), + (0x1F380300, '\u{001F3A}'), + (0x00490306, '\u{00012C}'), + (0x00690306, '\u{00012D}'), + (0x1F060345, '\u{001F86}'), + (0x00490301, '\u{0000CD}'), + (0x00570300, '\u{001E80}'), + (0x30F03099, '\u{0030F8}'), + (0x0053030C, '\u{000160}'), + (0x00490300, '\u{0000CC}'), + (0x30723099, '\u{003073}'), + (0x1F280300, '\u{001F2A}'), + (0x00480307, '\u{001E22}'), + (0x01A00309, '\u{001EDE}'), + (0x01EB0304, '\u{0001ED}'), + (0x1E630307, '\u{001E69}'), + (0x006F0323, '\u{001ECD}'), + (0x00410303, '\u{0000C3}'), + (0x03910345, '\u{001FBC}'), + (0x00410328, '\u{000104}'), + (0x00680307, '\u{001E23}'), + (0x006E0331, '\u{001E49}'), + (0x0DDC0DCA, '\u{000DDD}'), + (0x00580308, '\u{001E8C}'), + (0x00410301, '\u{0000C1}'), + (0x30C43099, '\u{0030C5}'), + (0x00420323, '\u{001E04}'), + (0x00730302, '\u{00015D}'), +]; +pub(crate) fn composition_table_astral(c1: char, c2: char) -> Option { + match (c1, c2) { + ('\u{105D2}', '\u{0307}') => Some('\u{105C9}'), + ('\u{105DA}', '\u{0307}') => Some('\u{105E4}'), + ('\u{11099}', '\u{110BA}') => Some('\u{1109A}'), + ('\u{1109B}', '\u{110BA}') => Some('\u{1109C}'), + ('\u{110A5}', '\u{110BA}') => Some('\u{110AB}'), + ('\u{11131}', '\u{11127}') => Some('\u{1112E}'), + ('\u{11132}', '\u{11127}') => Some('\u{1112F}'), + ('\u{11347}', '\u{1133E}') => Some('\u{1134B}'), + ('\u{11347}', '\u{11357}') => Some('\u{1134C}'), + ('\u{11382}', '\u{113C9}') => Some('\u{11383}'), + ('\u{11384}', '\u{113BB}') => Some('\u{11385}'), + ('\u{1138B}', '\u{113C2}') => Some('\u{1138E}'), + ('\u{11390}', '\u{113C9}') => Some('\u{11391}'), + ('\u{113C2}', '\u{113B8}') => Some('\u{113C7}'), + ('\u{113C2}', '\u{113C2}') => Some('\u{113C5}'), + ('\u{113C2}', '\u{113C9}') => Some('\u{113C8}'), + ('\u{114B9}', '\u{114B0}') => Some('\u{114BC}'), + ('\u{114B9}', '\u{114BA}') => Some('\u{114BB}'), + ('\u{114B9}', '\u{114BD}') => Some('\u{114BE}'), + ('\u{115B8}', '\u{115AF}') => Some('\u{115BA}'), + ('\u{115B9}', '\u{115AF}') => Some('\u{115BB}'), + ('\u{11935}', '\u{11930}') => Some('\u{11938}'), + ('\u{1611E}', '\u{1611E}') => Some('\u{16121}'), + ('\u{1611E}', '\u{1611F}') => Some('\u{16123}'), + ('\u{1611E}', '\u{16120}') => Some('\u{16125}'), + ('\u{1611E}', '\u{16129}') => Some('\u{16122}'), + ('\u{16121}', '\u{1611F}') => Some('\u{16126}'), + ('\u{16121}', '\u{16120}') => Some('\u{16128}'), + ('\u{16122}', '\u{1611F}') => Some('\u{16127}'), + ('\u{16129}', '\u{1611F}') => Some('\u{16124}'), + ('\u{16D63}', '\u{16D67}') => Some('\u{16D69}'), + ('\u{16D67}', '\u{16D67}') => Some('\u{16D68}'), + ('\u{16D69}', '\u{16D67}') => Some('\u{16D6A}'), + _ => None, + } +} +pub(crate) const CANONICAL_DECOMPOSED_CHARS: &[char] = &[ + '\u{0041}', + '\u{0300}', + '\u{0041}', + '\u{0301}', + '\u{0041}', + '\u{0302}', + '\u{0041}', + '\u{0303}', + '\u{0041}', + '\u{0308}', + '\u{0041}', + '\u{030A}', + '\u{0043}', + '\u{0327}', + '\u{0045}', + '\u{0300}', + '\u{0045}', + '\u{0301}', + '\u{0045}', + '\u{0302}', + '\u{0045}', + '\u{0308}', + '\u{0049}', + '\u{0300}', + '\u{0049}', + '\u{0301}', + '\u{0049}', + '\u{0302}', + '\u{0049}', + '\u{0308}', + '\u{004E}', + '\u{0303}', + '\u{004F}', + '\u{0300}', + '\u{004F}', + '\u{0301}', + '\u{004F}', + '\u{0302}', + '\u{004F}', + '\u{0303}', + '\u{004F}', + '\u{0308}', + '\u{0055}', + '\u{0300}', + '\u{0055}', + '\u{0301}', + '\u{0055}', + '\u{0302}', + '\u{0055}', + '\u{0308}', + '\u{0059}', + '\u{0301}', + '\u{0061}', + '\u{0300}', + '\u{0061}', + '\u{0301}', + '\u{0061}', + '\u{0302}', + '\u{0061}', + '\u{0303}', + '\u{0061}', + '\u{0308}', + '\u{0061}', + '\u{030A}', + '\u{0063}', + '\u{0327}', + '\u{0065}', + '\u{0300}', + '\u{0065}', + '\u{0301}', + '\u{0065}', + '\u{0302}', + '\u{0065}', + '\u{0308}', + '\u{0069}', + '\u{0300}', + '\u{0069}', + '\u{0301}', + '\u{0069}', + '\u{0302}', + '\u{0069}', + '\u{0308}', + '\u{006E}', + '\u{0303}', + '\u{006F}', + '\u{0300}', + '\u{006F}', + '\u{0301}', + '\u{006F}', + '\u{0302}', + '\u{006F}', + '\u{0303}', + '\u{006F}', + '\u{0308}', + '\u{0075}', + '\u{0300}', + '\u{0075}', + '\u{0301}', + '\u{0075}', + '\u{0302}', + '\u{0075}', + '\u{0308}', + '\u{0079}', + '\u{0301}', + '\u{0079}', + '\u{0308}', + '\u{0041}', + '\u{0304}', + '\u{0061}', + '\u{0304}', + '\u{0041}', + '\u{0306}', + '\u{0061}', + '\u{0306}', + '\u{0041}', + '\u{0328}', + '\u{0061}', + '\u{0328}', + '\u{0043}', + '\u{0301}', + '\u{0063}', + '\u{0301}', + '\u{0043}', + '\u{0302}', + '\u{0063}', + '\u{0302}', + '\u{0043}', + '\u{0307}', + '\u{0063}', + '\u{0307}', + '\u{0043}', + '\u{030C}', + '\u{0063}', + '\u{030C}', + '\u{0044}', + '\u{030C}', + '\u{0064}', + '\u{030C}', + '\u{0045}', + '\u{0304}', + '\u{0065}', + '\u{0304}', + '\u{0045}', + '\u{0306}', + '\u{0065}', + '\u{0306}', + '\u{0045}', + '\u{0307}', + '\u{0065}', + '\u{0307}', + '\u{0045}', + '\u{0328}', + '\u{0065}', + '\u{0328}', + '\u{0045}', + '\u{030C}', + '\u{0065}', + '\u{030C}', + '\u{0047}', + '\u{0302}', + '\u{0067}', + '\u{0302}', + '\u{0047}', + '\u{0306}', + '\u{0067}', + '\u{0306}', + '\u{0047}', + '\u{0307}', + '\u{0067}', + '\u{0307}', + '\u{0047}', + '\u{0327}', + '\u{0067}', + '\u{0327}', + '\u{0048}', + '\u{0302}', + '\u{0068}', + '\u{0302}', + '\u{0049}', + '\u{0303}', + '\u{0069}', + '\u{0303}', + '\u{0049}', + '\u{0304}', + '\u{0069}', + '\u{0304}', + '\u{0049}', + '\u{0306}', + '\u{0069}', + '\u{0306}', + '\u{0049}', + '\u{0328}', + '\u{0069}', + '\u{0328}', + '\u{0049}', + '\u{0307}', + '\u{004A}', + '\u{0302}', + '\u{006A}', + '\u{0302}', + '\u{004B}', + '\u{0327}', + '\u{006B}', + '\u{0327}', + '\u{004C}', + '\u{0301}', + '\u{006C}', + '\u{0301}', + '\u{004C}', + '\u{0327}', + '\u{006C}', + '\u{0327}', + '\u{004C}', + '\u{030C}', + '\u{006C}', + '\u{030C}', + '\u{004E}', + '\u{0301}', + '\u{006E}', + '\u{0301}', + '\u{004E}', + '\u{0327}', + '\u{006E}', + '\u{0327}', + '\u{004E}', + '\u{030C}', + '\u{006E}', + '\u{030C}', + '\u{004F}', + '\u{0304}', + '\u{006F}', + '\u{0304}', + '\u{004F}', + '\u{0306}', + '\u{006F}', + '\u{0306}', + '\u{004F}', + '\u{030B}', + '\u{006F}', + '\u{030B}', + '\u{0052}', + '\u{0301}', + '\u{0072}', + '\u{0301}', + '\u{0052}', + '\u{0327}', + '\u{0072}', + '\u{0327}', + '\u{0052}', + '\u{030C}', + '\u{0072}', + '\u{030C}', + '\u{0053}', + '\u{0301}', + '\u{0073}', + '\u{0301}', + '\u{0053}', + '\u{0302}', + '\u{0073}', + '\u{0302}', + '\u{0053}', + '\u{0327}', + '\u{0073}', + '\u{0327}', + '\u{0053}', + '\u{030C}', + '\u{0073}', + '\u{030C}', + '\u{0054}', + '\u{0327}', + '\u{0074}', + '\u{0327}', + '\u{0054}', + '\u{030C}', + '\u{0074}', + '\u{030C}', + '\u{0055}', + '\u{0303}', + '\u{0075}', + '\u{0303}', + '\u{0055}', + '\u{0304}', + '\u{0075}', + '\u{0304}', + '\u{0055}', + '\u{0306}', + '\u{0075}', + '\u{0306}', + '\u{0055}', + '\u{030A}', + '\u{0075}', + '\u{030A}', + '\u{0055}', + '\u{030B}', + '\u{0075}', + '\u{030B}', + '\u{0055}', + '\u{0328}', + '\u{0075}', + '\u{0328}', + '\u{0057}', + '\u{0302}', + '\u{0077}', + '\u{0302}', + '\u{0059}', + '\u{0302}', + '\u{0079}', + '\u{0302}', + '\u{0059}', + '\u{0308}', + '\u{005A}', + '\u{0301}', + '\u{007A}', + '\u{0301}', + '\u{005A}', + '\u{0307}', + '\u{007A}', + '\u{0307}', + '\u{005A}', + '\u{030C}', + '\u{007A}', + '\u{030C}', + '\u{004F}', + '\u{031B}', + '\u{006F}', + '\u{031B}', + '\u{0055}', + '\u{031B}', + '\u{0075}', + '\u{031B}', + '\u{0041}', + '\u{030C}', + '\u{0061}', + '\u{030C}', + '\u{0049}', + '\u{030C}', + '\u{0069}', + '\u{030C}', + '\u{004F}', + '\u{030C}', + '\u{006F}', + '\u{030C}', + '\u{0055}', + '\u{030C}', + '\u{0075}', + '\u{030C}', + '\u{0055}', + '\u{0308}', + '\u{0304}', + '\u{0075}', + '\u{0308}', + '\u{0304}', + '\u{0055}', + '\u{0308}', + '\u{0301}', + '\u{0075}', + '\u{0308}', + '\u{0301}', + '\u{0055}', + '\u{0308}', + '\u{030C}', + '\u{0075}', + '\u{0308}', + '\u{030C}', + '\u{0055}', + '\u{0308}', + '\u{0300}', + '\u{0075}', + '\u{0308}', + '\u{0300}', + '\u{0041}', + '\u{0308}', + '\u{0304}', + '\u{0061}', + '\u{0308}', + '\u{0304}', + '\u{0041}', + '\u{0307}', + '\u{0304}', + '\u{0061}', + '\u{0307}', + '\u{0304}', + '\u{00C6}', + '\u{0304}', + '\u{00E6}', + '\u{0304}', + '\u{0047}', + '\u{030C}', + '\u{0067}', + '\u{030C}', + '\u{004B}', + '\u{030C}', + '\u{006B}', + '\u{030C}', + '\u{004F}', + '\u{0328}', + '\u{006F}', + '\u{0328}', + '\u{004F}', + '\u{0328}', + '\u{0304}', + '\u{006F}', + '\u{0328}', + '\u{0304}', + '\u{01B7}', + '\u{030C}', + '\u{0292}', + '\u{030C}', + '\u{006A}', + '\u{030C}', + '\u{0047}', + '\u{0301}', + '\u{0067}', + '\u{0301}', + '\u{004E}', + '\u{0300}', + '\u{006E}', + '\u{0300}', + '\u{0041}', + '\u{030A}', + '\u{0301}', + '\u{0061}', + '\u{030A}', + '\u{0301}', + '\u{00C6}', + '\u{0301}', + '\u{00E6}', + '\u{0301}', + '\u{00D8}', + '\u{0301}', + '\u{00F8}', + '\u{0301}', + '\u{0041}', + '\u{030F}', + '\u{0061}', + '\u{030F}', + '\u{0041}', + '\u{0311}', + '\u{0061}', + '\u{0311}', + '\u{0045}', + '\u{030F}', + '\u{0065}', + '\u{030F}', + '\u{0045}', + '\u{0311}', + '\u{0065}', + '\u{0311}', + '\u{0049}', + '\u{030F}', + '\u{0069}', + '\u{030F}', + '\u{0049}', + '\u{0311}', + '\u{0069}', + '\u{0311}', + '\u{004F}', + '\u{030F}', + '\u{006F}', + '\u{030F}', + '\u{004F}', + '\u{0311}', + '\u{006F}', + '\u{0311}', + '\u{0052}', + '\u{030F}', + '\u{0072}', + '\u{030F}', + '\u{0052}', + '\u{0311}', + '\u{0072}', + '\u{0311}', + '\u{0055}', + '\u{030F}', + '\u{0075}', + '\u{030F}', + '\u{0055}', + '\u{0311}', + '\u{0075}', + '\u{0311}', + '\u{0053}', + '\u{0326}', + '\u{0073}', + '\u{0326}', + '\u{0054}', + '\u{0326}', + '\u{0074}', + '\u{0326}', + '\u{0048}', + '\u{030C}', + '\u{0068}', + '\u{030C}', + '\u{0041}', + '\u{0307}', + '\u{0061}', + '\u{0307}', + '\u{0045}', + '\u{0327}', + '\u{0065}', + '\u{0327}', + '\u{004F}', + '\u{0308}', + '\u{0304}', + '\u{006F}', + '\u{0308}', + '\u{0304}', + '\u{004F}', + '\u{0303}', + '\u{0304}', + '\u{006F}', + '\u{0303}', + '\u{0304}', + '\u{004F}', + '\u{0307}', + '\u{006F}', + '\u{0307}', + '\u{004F}', + '\u{0307}', + '\u{0304}', + '\u{006F}', + '\u{0307}', + '\u{0304}', + '\u{0059}', + '\u{0304}', + '\u{0079}', + '\u{0304}', + '\u{0300}', + '\u{0301}', + '\u{0313}', + '\u{0308}', + '\u{0301}', + '\u{02B9}', + '\u{003B}', + '\u{00A8}', + '\u{0301}', + '\u{0391}', + '\u{0301}', + '\u{00B7}', + '\u{0395}', + '\u{0301}', + '\u{0397}', + '\u{0301}', + '\u{0399}', + '\u{0301}', + '\u{039F}', + '\u{0301}', + '\u{03A5}', + '\u{0301}', + '\u{03A9}', + '\u{0301}', + '\u{03B9}', + '\u{0308}', + '\u{0301}', + '\u{0399}', + '\u{0308}', + '\u{03A5}', + '\u{0308}', + '\u{03B1}', + '\u{0301}', + '\u{03B5}', + '\u{0301}', + '\u{03B7}', + '\u{0301}', + '\u{03B9}', + '\u{0301}', + '\u{03C5}', + '\u{0308}', + '\u{0301}', + '\u{03B9}', + '\u{0308}', + '\u{03C5}', + '\u{0308}', + '\u{03BF}', + '\u{0301}', + '\u{03C5}', + '\u{0301}', + '\u{03C9}', + '\u{0301}', + '\u{03D2}', + '\u{0301}', + '\u{03D2}', + '\u{0308}', + '\u{0415}', + '\u{0300}', + '\u{0415}', + '\u{0308}', + '\u{0413}', + '\u{0301}', + '\u{0406}', + '\u{0308}', + '\u{041A}', + '\u{0301}', + '\u{0418}', + '\u{0300}', + '\u{0423}', + '\u{0306}', + '\u{0418}', + '\u{0306}', + '\u{0438}', + '\u{0306}', + '\u{0435}', + '\u{0300}', + '\u{0435}', + '\u{0308}', + '\u{0433}', + '\u{0301}', + '\u{0456}', + '\u{0308}', + '\u{043A}', + '\u{0301}', + '\u{0438}', + '\u{0300}', + '\u{0443}', + '\u{0306}', + '\u{0474}', + '\u{030F}', + '\u{0475}', + '\u{030F}', + '\u{0416}', + '\u{0306}', + '\u{0436}', + '\u{0306}', + '\u{0410}', + '\u{0306}', + '\u{0430}', + '\u{0306}', + '\u{0410}', + '\u{0308}', + '\u{0430}', + '\u{0308}', + '\u{0415}', + '\u{0306}', + '\u{0435}', + '\u{0306}', + '\u{04D8}', + '\u{0308}', + '\u{04D9}', + '\u{0308}', + '\u{0416}', + '\u{0308}', + '\u{0436}', + '\u{0308}', + '\u{0417}', + '\u{0308}', + '\u{0437}', + '\u{0308}', + '\u{0418}', + '\u{0304}', + '\u{0438}', + '\u{0304}', + '\u{0418}', + '\u{0308}', + '\u{0438}', + '\u{0308}', + '\u{041E}', + '\u{0308}', + '\u{043E}', + '\u{0308}', + '\u{04E8}', + '\u{0308}', + '\u{04E9}', + '\u{0308}', + '\u{042D}', + '\u{0308}', + '\u{044D}', + '\u{0308}', + '\u{0423}', + '\u{0304}', + '\u{0443}', + '\u{0304}', + '\u{0423}', + '\u{0308}', + '\u{0443}', + '\u{0308}', + '\u{0423}', + '\u{030B}', + '\u{0443}', + '\u{030B}', + '\u{0427}', + '\u{0308}', + '\u{0447}', + '\u{0308}', + '\u{042B}', + '\u{0308}', + '\u{044B}', + '\u{0308}', + '\u{0627}', + '\u{0653}', + '\u{0627}', + '\u{0654}', + '\u{0648}', + '\u{0654}', + '\u{0627}', + '\u{0655}', + '\u{064A}', + '\u{0654}', + '\u{06D5}', + '\u{0654}', + '\u{06C1}', + '\u{0654}', + '\u{06D2}', + '\u{0654}', + '\u{0928}', + '\u{093C}', + '\u{0930}', + '\u{093C}', + '\u{0933}', + '\u{093C}', + '\u{0915}', + '\u{093C}', + '\u{0916}', + '\u{093C}', + '\u{0917}', + '\u{093C}', + '\u{091C}', + '\u{093C}', + '\u{0921}', + '\u{093C}', + '\u{0922}', + '\u{093C}', + '\u{092B}', + '\u{093C}', + '\u{092F}', + '\u{093C}', + '\u{09C7}', + '\u{09BE}', + '\u{09C7}', + '\u{09D7}', + '\u{09A1}', + '\u{09BC}', + '\u{09A2}', + '\u{09BC}', + '\u{09AF}', + '\u{09BC}', + '\u{0A32}', + '\u{0A3C}', + '\u{0A38}', + '\u{0A3C}', + '\u{0A16}', + '\u{0A3C}', + '\u{0A17}', + '\u{0A3C}', + '\u{0A1C}', + '\u{0A3C}', + '\u{0A2B}', + '\u{0A3C}', + '\u{0B47}', + '\u{0B56}', + '\u{0B47}', + '\u{0B3E}', + '\u{0B47}', + '\u{0B57}', + '\u{0B21}', + '\u{0B3C}', + '\u{0B22}', + '\u{0B3C}', + '\u{0B92}', + '\u{0BD7}', + '\u{0BC6}', + '\u{0BBE}', + '\u{0BC7}', + '\u{0BBE}', + '\u{0BC6}', + '\u{0BD7}', + '\u{0C46}', + '\u{0C56}', + '\u{0CBF}', + '\u{0CD5}', + '\u{0CC6}', + '\u{0CD5}', + '\u{0CC6}', + '\u{0CD6}', + '\u{0CC6}', + '\u{0CC2}', + '\u{0CC6}', + '\u{0CC2}', + '\u{0CD5}', + '\u{0D46}', + '\u{0D3E}', + '\u{0D47}', + '\u{0D3E}', + '\u{0D46}', + '\u{0D57}', + '\u{0DD9}', + '\u{0DCA}', + '\u{0DD9}', + '\u{0DCF}', + '\u{0DD9}', + '\u{0DCF}', + '\u{0DCA}', + '\u{0DD9}', + '\u{0DDF}', + '\u{0F42}', + '\u{0FB7}', + '\u{0F4C}', + '\u{0FB7}', + '\u{0F51}', + '\u{0FB7}', + '\u{0F56}', + '\u{0FB7}', + '\u{0F5B}', + '\u{0FB7}', + '\u{0F40}', + '\u{0FB5}', + '\u{0F71}', + '\u{0F72}', + '\u{0F71}', + '\u{0F74}', + '\u{0FB2}', + '\u{0F80}', + '\u{0FB3}', + '\u{0F80}', + '\u{0F71}', + '\u{0F80}', + '\u{0F92}', + '\u{0FB7}', + '\u{0F9C}', + '\u{0FB7}', + '\u{0FA1}', + '\u{0FB7}', + '\u{0FA6}', + '\u{0FB7}', + '\u{0FAB}', + '\u{0FB7}', + '\u{0F90}', + '\u{0FB5}', + '\u{1025}', + '\u{102E}', + '\u{1B05}', + '\u{1B35}', + '\u{1B07}', + '\u{1B35}', + '\u{1B09}', + '\u{1B35}', + '\u{1B0B}', + '\u{1B35}', + '\u{1B0D}', + '\u{1B35}', + '\u{1B11}', + '\u{1B35}', + '\u{1B3A}', + '\u{1B35}', + '\u{1B3C}', + '\u{1B35}', + '\u{1B3E}', + '\u{1B35}', + '\u{1B3F}', + '\u{1B35}', + '\u{1B42}', + '\u{1B35}', + '\u{0041}', + '\u{0325}', + '\u{0061}', + '\u{0325}', + '\u{0042}', + '\u{0307}', + '\u{0062}', + '\u{0307}', + '\u{0042}', + '\u{0323}', + '\u{0062}', + '\u{0323}', + '\u{0042}', + '\u{0331}', + '\u{0062}', + '\u{0331}', + '\u{0043}', + '\u{0327}', + '\u{0301}', + '\u{0063}', + '\u{0327}', + '\u{0301}', + '\u{0044}', + '\u{0307}', + '\u{0064}', + '\u{0307}', + '\u{0044}', + '\u{0323}', + '\u{0064}', + '\u{0323}', + '\u{0044}', + '\u{0331}', + '\u{0064}', + '\u{0331}', + '\u{0044}', + '\u{0327}', + '\u{0064}', + '\u{0327}', + '\u{0044}', + '\u{032D}', + '\u{0064}', + '\u{032D}', + '\u{0045}', + '\u{0304}', + '\u{0300}', + '\u{0065}', + '\u{0304}', + '\u{0300}', + '\u{0045}', + '\u{0304}', + '\u{0301}', + '\u{0065}', + '\u{0304}', + '\u{0301}', + '\u{0045}', + '\u{032D}', + '\u{0065}', + '\u{032D}', + '\u{0045}', + '\u{0330}', + '\u{0065}', + '\u{0330}', + '\u{0045}', + '\u{0327}', + '\u{0306}', + '\u{0065}', + '\u{0327}', + '\u{0306}', + '\u{0046}', + '\u{0307}', + '\u{0066}', + '\u{0307}', + '\u{0047}', + '\u{0304}', + '\u{0067}', + '\u{0304}', + '\u{0048}', + '\u{0307}', + '\u{0068}', + '\u{0307}', + '\u{0048}', + '\u{0323}', + '\u{0068}', + '\u{0323}', + '\u{0048}', + '\u{0308}', + '\u{0068}', + '\u{0308}', + '\u{0048}', + '\u{0327}', + '\u{0068}', + '\u{0327}', + '\u{0048}', + '\u{032E}', + '\u{0068}', + '\u{032E}', + '\u{0049}', + '\u{0330}', + '\u{0069}', + '\u{0330}', + '\u{0049}', + '\u{0308}', + '\u{0301}', + '\u{0069}', + '\u{0308}', + '\u{0301}', + '\u{004B}', + '\u{0301}', + '\u{006B}', + '\u{0301}', + '\u{004B}', + '\u{0323}', + '\u{006B}', + '\u{0323}', + '\u{004B}', + '\u{0331}', + '\u{006B}', + '\u{0331}', + '\u{004C}', + '\u{0323}', + '\u{006C}', + '\u{0323}', + '\u{004C}', + '\u{0323}', + '\u{0304}', + '\u{006C}', + '\u{0323}', + '\u{0304}', + '\u{004C}', + '\u{0331}', + '\u{006C}', + '\u{0331}', + '\u{004C}', + '\u{032D}', + '\u{006C}', + '\u{032D}', + '\u{004D}', + '\u{0301}', + '\u{006D}', + '\u{0301}', + '\u{004D}', + '\u{0307}', + '\u{006D}', + '\u{0307}', + '\u{004D}', + '\u{0323}', + '\u{006D}', + '\u{0323}', + '\u{004E}', + '\u{0307}', + '\u{006E}', + '\u{0307}', + '\u{004E}', + '\u{0323}', + '\u{006E}', + '\u{0323}', + '\u{004E}', + '\u{0331}', + '\u{006E}', + '\u{0331}', + '\u{004E}', + '\u{032D}', + '\u{006E}', + '\u{032D}', + '\u{004F}', + '\u{0303}', + '\u{0301}', + '\u{006F}', + '\u{0303}', + '\u{0301}', + '\u{004F}', + '\u{0303}', + '\u{0308}', + '\u{006F}', + '\u{0303}', + '\u{0308}', + '\u{004F}', + '\u{0304}', + '\u{0300}', + '\u{006F}', + '\u{0304}', + '\u{0300}', + '\u{004F}', + '\u{0304}', + '\u{0301}', + '\u{006F}', + '\u{0304}', + '\u{0301}', + '\u{0050}', + '\u{0301}', + '\u{0070}', + '\u{0301}', + '\u{0050}', + '\u{0307}', + '\u{0070}', + '\u{0307}', + '\u{0052}', + '\u{0307}', + '\u{0072}', + '\u{0307}', + '\u{0052}', + '\u{0323}', + '\u{0072}', + '\u{0323}', + '\u{0052}', + '\u{0323}', + '\u{0304}', + '\u{0072}', + '\u{0323}', + '\u{0304}', + '\u{0052}', + '\u{0331}', + '\u{0072}', + '\u{0331}', + '\u{0053}', + '\u{0307}', + '\u{0073}', + '\u{0307}', + '\u{0053}', + '\u{0323}', + '\u{0073}', + '\u{0323}', + '\u{0053}', + '\u{0301}', + '\u{0307}', + '\u{0073}', + '\u{0301}', + '\u{0307}', + '\u{0053}', + '\u{030C}', + '\u{0307}', + '\u{0073}', + '\u{030C}', + '\u{0307}', + '\u{0053}', + '\u{0323}', + '\u{0307}', + '\u{0073}', + '\u{0323}', + '\u{0307}', + '\u{0054}', + '\u{0307}', + '\u{0074}', + '\u{0307}', + '\u{0054}', + '\u{0323}', + '\u{0074}', + '\u{0323}', + '\u{0054}', + '\u{0331}', + '\u{0074}', + '\u{0331}', + '\u{0054}', + '\u{032D}', + '\u{0074}', + '\u{032D}', + '\u{0055}', + '\u{0324}', + '\u{0075}', + '\u{0324}', + '\u{0055}', + '\u{0330}', + '\u{0075}', + '\u{0330}', + '\u{0055}', + '\u{032D}', + '\u{0075}', + '\u{032D}', + '\u{0055}', + '\u{0303}', + '\u{0301}', + '\u{0075}', + '\u{0303}', + '\u{0301}', + '\u{0055}', + '\u{0304}', + '\u{0308}', + '\u{0075}', + '\u{0304}', + '\u{0308}', + '\u{0056}', + '\u{0303}', + '\u{0076}', + '\u{0303}', + '\u{0056}', + '\u{0323}', + '\u{0076}', + '\u{0323}', + '\u{0057}', + '\u{0300}', + '\u{0077}', + '\u{0300}', + '\u{0057}', + '\u{0301}', + '\u{0077}', + '\u{0301}', + '\u{0057}', + '\u{0308}', + '\u{0077}', + '\u{0308}', + '\u{0057}', + '\u{0307}', + '\u{0077}', + '\u{0307}', + '\u{0057}', + '\u{0323}', + '\u{0077}', + '\u{0323}', + '\u{0058}', + '\u{0307}', + '\u{0078}', + '\u{0307}', + '\u{0058}', + '\u{0308}', + '\u{0078}', + '\u{0308}', + '\u{0059}', + '\u{0307}', + '\u{0079}', + '\u{0307}', + '\u{005A}', + '\u{0302}', + '\u{007A}', + '\u{0302}', + '\u{005A}', + '\u{0323}', + '\u{007A}', + '\u{0323}', + '\u{005A}', + '\u{0331}', + '\u{007A}', + '\u{0331}', + '\u{0068}', + '\u{0331}', + '\u{0074}', + '\u{0308}', + '\u{0077}', + '\u{030A}', + '\u{0079}', + '\u{030A}', + '\u{017F}', + '\u{0307}', + '\u{0041}', + '\u{0323}', + '\u{0061}', + '\u{0323}', + '\u{0041}', + '\u{0309}', + '\u{0061}', + '\u{0309}', + '\u{0041}', + '\u{0302}', + '\u{0301}', + '\u{0061}', + '\u{0302}', + '\u{0301}', + '\u{0041}', + '\u{0302}', + '\u{0300}', + '\u{0061}', + '\u{0302}', + '\u{0300}', + '\u{0041}', + '\u{0302}', + '\u{0309}', + '\u{0061}', + '\u{0302}', + '\u{0309}', + '\u{0041}', + '\u{0302}', + '\u{0303}', + '\u{0061}', + '\u{0302}', + '\u{0303}', + '\u{0041}', + '\u{0323}', + '\u{0302}', + '\u{0061}', + '\u{0323}', + '\u{0302}', + '\u{0041}', + '\u{0306}', + '\u{0301}', + '\u{0061}', + '\u{0306}', + '\u{0301}', + '\u{0041}', + '\u{0306}', + '\u{0300}', + '\u{0061}', + '\u{0306}', + '\u{0300}', + '\u{0041}', + '\u{0306}', + '\u{0309}', + '\u{0061}', + '\u{0306}', + '\u{0309}', + '\u{0041}', + '\u{0306}', + '\u{0303}', + '\u{0061}', + '\u{0306}', + '\u{0303}', + '\u{0041}', + '\u{0323}', + '\u{0306}', + '\u{0061}', + '\u{0323}', + '\u{0306}', + '\u{0045}', + '\u{0323}', + '\u{0065}', + '\u{0323}', + '\u{0045}', + '\u{0309}', + '\u{0065}', + '\u{0309}', + '\u{0045}', + '\u{0303}', + '\u{0065}', + '\u{0303}', + '\u{0045}', + '\u{0302}', + '\u{0301}', + '\u{0065}', + '\u{0302}', + '\u{0301}', + '\u{0045}', + '\u{0302}', + '\u{0300}', + '\u{0065}', + '\u{0302}', + '\u{0300}', + '\u{0045}', + '\u{0302}', + '\u{0309}', + '\u{0065}', + '\u{0302}', + '\u{0309}', + '\u{0045}', + '\u{0302}', + '\u{0303}', + '\u{0065}', + '\u{0302}', + '\u{0303}', + '\u{0045}', + '\u{0323}', + '\u{0302}', + '\u{0065}', + '\u{0323}', + '\u{0302}', + '\u{0049}', + '\u{0309}', + '\u{0069}', + '\u{0309}', + '\u{0049}', + '\u{0323}', + '\u{0069}', + '\u{0323}', + '\u{004F}', + '\u{0323}', + '\u{006F}', + '\u{0323}', + '\u{004F}', + '\u{0309}', + '\u{006F}', + '\u{0309}', + '\u{004F}', + '\u{0302}', + '\u{0301}', + '\u{006F}', + '\u{0302}', + '\u{0301}', + '\u{004F}', + '\u{0302}', + '\u{0300}', + '\u{006F}', + '\u{0302}', + '\u{0300}', + '\u{004F}', + '\u{0302}', + '\u{0309}', + '\u{006F}', + '\u{0302}', + '\u{0309}', + '\u{004F}', + '\u{0302}', + '\u{0303}', + '\u{006F}', + '\u{0302}', + '\u{0303}', + '\u{004F}', + '\u{0323}', + '\u{0302}', + '\u{006F}', + '\u{0323}', + '\u{0302}', + '\u{004F}', + '\u{031B}', + '\u{0301}', + '\u{006F}', + '\u{031B}', + '\u{0301}', + '\u{004F}', + '\u{031B}', + '\u{0300}', + '\u{006F}', + '\u{031B}', + '\u{0300}', + '\u{004F}', + '\u{031B}', + '\u{0309}', + '\u{006F}', + '\u{031B}', + '\u{0309}', + '\u{004F}', + '\u{031B}', + '\u{0303}', + '\u{006F}', + '\u{031B}', + '\u{0303}', + '\u{004F}', + '\u{031B}', + '\u{0323}', + '\u{006F}', + '\u{031B}', + '\u{0323}', + '\u{0055}', + '\u{0323}', + '\u{0075}', + '\u{0323}', + '\u{0055}', + '\u{0309}', + '\u{0075}', + '\u{0309}', + '\u{0055}', + '\u{031B}', + '\u{0301}', + '\u{0075}', + '\u{031B}', + '\u{0301}', + '\u{0055}', + '\u{031B}', + '\u{0300}', + '\u{0075}', + '\u{031B}', + '\u{0300}', + '\u{0055}', + '\u{031B}', + '\u{0309}', + '\u{0075}', + '\u{031B}', + '\u{0309}', + '\u{0055}', + '\u{031B}', + '\u{0303}', + '\u{0075}', + '\u{031B}', + '\u{0303}', + '\u{0055}', + '\u{031B}', + '\u{0323}', + '\u{0075}', + '\u{031B}', + '\u{0323}', + '\u{0059}', + '\u{0300}', + '\u{0079}', + '\u{0300}', + '\u{0059}', + '\u{0323}', + '\u{0079}', + '\u{0323}', + '\u{0059}', + '\u{0309}', + '\u{0079}', + '\u{0309}', + '\u{0059}', + '\u{0303}', + '\u{0079}', + '\u{0303}', + '\u{03B1}', + '\u{0313}', + '\u{03B1}', + '\u{0314}', + '\u{03B1}', + '\u{0313}', + '\u{0300}', + '\u{03B1}', + '\u{0314}', + '\u{0300}', + '\u{03B1}', + '\u{0313}', + '\u{0301}', + '\u{03B1}', + '\u{0314}', + '\u{0301}', + '\u{03B1}', + '\u{0313}', + '\u{0342}', + '\u{03B1}', + '\u{0314}', + '\u{0342}', + '\u{0391}', + '\u{0313}', + '\u{0391}', + '\u{0314}', + '\u{0391}', + '\u{0313}', + '\u{0300}', + '\u{0391}', + '\u{0314}', + '\u{0300}', + '\u{0391}', + '\u{0313}', + '\u{0301}', + '\u{0391}', + '\u{0314}', + '\u{0301}', + '\u{0391}', + '\u{0313}', + '\u{0342}', + '\u{0391}', + '\u{0314}', + '\u{0342}', + '\u{03B5}', + '\u{0313}', + '\u{03B5}', + '\u{0314}', + '\u{03B5}', + '\u{0313}', + '\u{0300}', + '\u{03B5}', + '\u{0314}', + '\u{0300}', + '\u{03B5}', + '\u{0313}', + '\u{0301}', + '\u{03B5}', + '\u{0314}', + '\u{0301}', + '\u{0395}', + '\u{0313}', + '\u{0395}', + '\u{0314}', + '\u{0395}', + '\u{0313}', + '\u{0300}', + '\u{0395}', + '\u{0314}', + '\u{0300}', + '\u{0395}', + '\u{0313}', + '\u{0301}', + '\u{0395}', + '\u{0314}', + '\u{0301}', + '\u{03B7}', + '\u{0313}', + '\u{03B7}', + '\u{0314}', + '\u{03B7}', + '\u{0313}', + '\u{0300}', + '\u{03B7}', + '\u{0314}', + '\u{0300}', + '\u{03B7}', + '\u{0313}', + '\u{0301}', + '\u{03B7}', + '\u{0314}', + '\u{0301}', + '\u{03B7}', + '\u{0313}', + '\u{0342}', + '\u{03B7}', + '\u{0314}', + '\u{0342}', + '\u{0397}', + '\u{0313}', + '\u{0397}', + '\u{0314}', + '\u{0397}', + '\u{0313}', + '\u{0300}', + '\u{0397}', + '\u{0314}', + '\u{0300}', + '\u{0397}', + '\u{0313}', + '\u{0301}', + '\u{0397}', + '\u{0314}', + '\u{0301}', + '\u{0397}', + '\u{0313}', + '\u{0342}', + '\u{0397}', + '\u{0314}', + '\u{0342}', + '\u{03B9}', + '\u{0313}', + '\u{03B9}', + '\u{0314}', + '\u{03B9}', + '\u{0313}', + '\u{0300}', + '\u{03B9}', + '\u{0314}', + '\u{0300}', + '\u{03B9}', + '\u{0313}', + '\u{0301}', + '\u{03B9}', + '\u{0314}', + '\u{0301}', + '\u{03B9}', + '\u{0313}', + '\u{0342}', + '\u{03B9}', + '\u{0314}', + '\u{0342}', + '\u{0399}', + '\u{0313}', + '\u{0399}', + '\u{0314}', + '\u{0399}', + '\u{0313}', + '\u{0300}', + '\u{0399}', + '\u{0314}', + '\u{0300}', + '\u{0399}', + '\u{0313}', + '\u{0301}', + '\u{0399}', + '\u{0314}', + '\u{0301}', + '\u{0399}', + '\u{0313}', + '\u{0342}', + '\u{0399}', + '\u{0314}', + '\u{0342}', + '\u{03BF}', + '\u{0313}', + '\u{03BF}', + '\u{0314}', + '\u{03BF}', + '\u{0313}', + '\u{0300}', + '\u{03BF}', + '\u{0314}', + '\u{0300}', + '\u{03BF}', + '\u{0313}', + '\u{0301}', + '\u{03BF}', + '\u{0314}', + '\u{0301}', + '\u{039F}', + '\u{0313}', + '\u{039F}', + '\u{0314}', + '\u{039F}', + '\u{0313}', + '\u{0300}', + '\u{039F}', + '\u{0314}', + '\u{0300}', + '\u{039F}', + '\u{0313}', + '\u{0301}', + '\u{039F}', + '\u{0314}', + '\u{0301}', + '\u{03C5}', + '\u{0313}', + '\u{03C5}', + '\u{0314}', + '\u{03C5}', + '\u{0313}', + '\u{0300}', + '\u{03C5}', + '\u{0314}', + '\u{0300}', + '\u{03C5}', + '\u{0313}', + '\u{0301}', + '\u{03C5}', + '\u{0314}', + '\u{0301}', + '\u{03C5}', + '\u{0313}', + '\u{0342}', + '\u{03C5}', + '\u{0314}', + '\u{0342}', + '\u{03A5}', + '\u{0314}', + '\u{03A5}', + '\u{0314}', + '\u{0300}', + '\u{03A5}', + '\u{0314}', + '\u{0301}', + '\u{03A5}', + '\u{0314}', + '\u{0342}', + '\u{03C9}', + '\u{0313}', + '\u{03C9}', + '\u{0314}', + '\u{03C9}', + '\u{0313}', + '\u{0300}', + '\u{03C9}', + '\u{0314}', + '\u{0300}', + '\u{03C9}', + '\u{0313}', + '\u{0301}', + '\u{03C9}', + '\u{0314}', + '\u{0301}', + '\u{03C9}', + '\u{0313}', + '\u{0342}', + '\u{03C9}', + '\u{0314}', + '\u{0342}', + '\u{03A9}', + '\u{0313}', + '\u{03A9}', + '\u{0314}', + '\u{03A9}', + '\u{0313}', + '\u{0300}', + '\u{03A9}', + '\u{0314}', + '\u{0300}', + '\u{03A9}', + '\u{0313}', + '\u{0301}', + '\u{03A9}', + '\u{0314}', + '\u{0301}', + '\u{03A9}', + '\u{0313}', + '\u{0342}', + '\u{03A9}', + '\u{0314}', + '\u{0342}', + '\u{03B1}', + '\u{0300}', + '\u{03B1}', + '\u{0301}', + '\u{03B5}', + '\u{0300}', + '\u{03B5}', + '\u{0301}', + '\u{03B7}', + '\u{0300}', + '\u{03B7}', + '\u{0301}', + '\u{03B9}', + '\u{0300}', + '\u{03B9}', + '\u{0301}', + '\u{03BF}', + '\u{0300}', + '\u{03BF}', + '\u{0301}', + '\u{03C5}', + '\u{0300}', + '\u{03C5}', + '\u{0301}', + '\u{03C9}', + '\u{0300}', + '\u{03C9}', + '\u{0301}', + '\u{03B1}', + '\u{0313}', + '\u{0345}', + '\u{03B1}', + '\u{0314}', + '\u{0345}', + '\u{03B1}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{03B1}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{03B1}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{03B1}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{03B1}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{03B1}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{0391}', + '\u{0313}', + '\u{0345}', + '\u{0391}', + '\u{0314}', + '\u{0345}', + '\u{0391}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{0391}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{0391}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{0391}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{0391}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{0391}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{03B7}', + '\u{0313}', + '\u{0345}', + '\u{03B7}', + '\u{0314}', + '\u{0345}', + '\u{03B7}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{03B7}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{03B7}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{03B7}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{03B7}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{03B7}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{0397}', + '\u{0313}', + '\u{0345}', + '\u{0397}', + '\u{0314}', + '\u{0345}', + '\u{0397}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{0397}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{0397}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{0397}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{0397}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{0397}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{03C9}', + '\u{0313}', + '\u{0345}', + '\u{03C9}', + '\u{0314}', + '\u{0345}', + '\u{03C9}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{03C9}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{03C9}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{03C9}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{03C9}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{03C9}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{03A9}', + '\u{0313}', + '\u{0345}', + '\u{03A9}', + '\u{0314}', + '\u{0345}', + '\u{03A9}', + '\u{0313}', + '\u{0300}', + '\u{0345}', + '\u{03A9}', + '\u{0314}', + '\u{0300}', + '\u{0345}', + '\u{03A9}', + '\u{0313}', + '\u{0301}', + '\u{0345}', + '\u{03A9}', + '\u{0314}', + '\u{0301}', + '\u{0345}', + '\u{03A9}', + '\u{0313}', + '\u{0342}', + '\u{0345}', + '\u{03A9}', + '\u{0314}', + '\u{0342}', + '\u{0345}', + '\u{03B1}', + '\u{0306}', + '\u{03B1}', + '\u{0304}', + '\u{03B1}', + '\u{0300}', + '\u{0345}', + '\u{03B1}', + '\u{0345}', + '\u{03B1}', + '\u{0301}', + '\u{0345}', + '\u{03B1}', + '\u{0342}', + '\u{03B1}', + '\u{0342}', + '\u{0345}', + '\u{0391}', + '\u{0306}', + '\u{0391}', + '\u{0304}', + '\u{0391}', + '\u{0300}', + '\u{0391}', + '\u{0301}', + '\u{0391}', + '\u{0345}', + '\u{03B9}', + '\u{00A8}', + '\u{0342}', + '\u{03B7}', + '\u{0300}', + '\u{0345}', + '\u{03B7}', + '\u{0345}', + '\u{03B7}', + '\u{0301}', + '\u{0345}', + '\u{03B7}', + '\u{0342}', + '\u{03B7}', + '\u{0342}', + '\u{0345}', + '\u{0395}', + '\u{0300}', + '\u{0395}', + '\u{0301}', + '\u{0397}', + '\u{0300}', + '\u{0397}', + '\u{0301}', + '\u{0397}', + '\u{0345}', + '\u{1FBF}', + '\u{0300}', + '\u{1FBF}', + '\u{0301}', + '\u{1FBF}', + '\u{0342}', + '\u{03B9}', + '\u{0306}', + '\u{03B9}', + '\u{0304}', + '\u{03B9}', + '\u{0308}', + '\u{0300}', + '\u{03B9}', + '\u{0308}', + '\u{0301}', + '\u{03B9}', + '\u{0342}', + '\u{03B9}', + '\u{0308}', + '\u{0342}', + '\u{0399}', + '\u{0306}', + '\u{0399}', + '\u{0304}', + '\u{0399}', + '\u{0300}', + '\u{0399}', + '\u{0301}', + '\u{1FFE}', + '\u{0300}', + '\u{1FFE}', + '\u{0301}', + '\u{1FFE}', + '\u{0342}', + '\u{03C5}', + '\u{0306}', + '\u{03C5}', + '\u{0304}', + '\u{03C5}', + '\u{0308}', + '\u{0300}', + '\u{03C5}', + '\u{0308}', + '\u{0301}', + '\u{03C1}', + '\u{0313}', + '\u{03C1}', + '\u{0314}', + '\u{03C5}', + '\u{0342}', + '\u{03C5}', + '\u{0308}', + '\u{0342}', + '\u{03A5}', + '\u{0306}', + '\u{03A5}', + '\u{0304}', + '\u{03A5}', + '\u{0300}', + '\u{03A5}', + '\u{0301}', + '\u{03A1}', + '\u{0314}', + '\u{00A8}', + '\u{0300}', + '\u{00A8}', + '\u{0301}', + '\u{0060}', + '\u{03C9}', + '\u{0300}', + '\u{0345}', + '\u{03C9}', + '\u{0345}', + '\u{03C9}', + '\u{0301}', + '\u{0345}', + '\u{03C9}', + '\u{0342}', + '\u{03C9}', + '\u{0342}', + '\u{0345}', + '\u{039F}', + '\u{0300}', + '\u{039F}', + '\u{0301}', + '\u{03A9}', + '\u{0300}', + '\u{03A9}', + '\u{0301}', + '\u{03A9}', + '\u{0345}', + '\u{00B4}', + '\u{2002}', + '\u{2003}', + '\u{03A9}', + '\u{004B}', + '\u{0041}', + '\u{030A}', + '\u{2190}', + '\u{0338}', + '\u{2192}', + '\u{0338}', + '\u{2194}', + '\u{0338}', + '\u{21D0}', + '\u{0338}', + '\u{21D4}', + '\u{0338}', + '\u{21D2}', + '\u{0338}', + '\u{2203}', + '\u{0338}', + '\u{2208}', + '\u{0338}', + '\u{220B}', + '\u{0338}', + '\u{2223}', + '\u{0338}', + '\u{2225}', + '\u{0338}', + '\u{223C}', + '\u{0338}', + '\u{2243}', + '\u{0338}', + '\u{2245}', + '\u{0338}', + '\u{2248}', + '\u{0338}', + '\u{003D}', + '\u{0338}', + '\u{2261}', + '\u{0338}', + '\u{224D}', + '\u{0338}', + '\u{003C}', + '\u{0338}', + '\u{003E}', + '\u{0338}', + '\u{2264}', + '\u{0338}', + '\u{2265}', + '\u{0338}', + '\u{2272}', + '\u{0338}', + '\u{2273}', + '\u{0338}', + '\u{2276}', + '\u{0338}', + '\u{2277}', + '\u{0338}', + '\u{227A}', + '\u{0338}', + '\u{227B}', + '\u{0338}', + '\u{2282}', + '\u{0338}', + '\u{2283}', + '\u{0338}', + '\u{2286}', + '\u{0338}', + '\u{2287}', + '\u{0338}', + '\u{22A2}', + '\u{0338}', + '\u{22A8}', + '\u{0338}', + '\u{22A9}', + '\u{0338}', + '\u{22AB}', + '\u{0338}', + '\u{227C}', + '\u{0338}', + '\u{227D}', + '\u{0338}', + '\u{2291}', + '\u{0338}', + '\u{2292}', + '\u{0338}', + '\u{22B2}', + '\u{0338}', + '\u{22B3}', + '\u{0338}', + '\u{22B4}', + '\u{0338}', + '\u{22B5}', + '\u{0338}', + '\u{3008}', + '\u{3009}', + '\u{2ADD}', + '\u{0338}', + '\u{304B}', + '\u{3099}', + '\u{304D}', + '\u{3099}', + '\u{304F}', + '\u{3099}', + '\u{3051}', + '\u{3099}', + '\u{3053}', + '\u{3099}', + '\u{3055}', + '\u{3099}', + '\u{3057}', + '\u{3099}', + '\u{3059}', + '\u{3099}', + '\u{305B}', + '\u{3099}', + '\u{305D}', + '\u{3099}', + '\u{305F}', + '\u{3099}', + '\u{3061}', + '\u{3099}', + '\u{3064}', + '\u{3099}', + '\u{3066}', + '\u{3099}', + '\u{3068}', + '\u{3099}', + '\u{306F}', + '\u{3099}', + '\u{306F}', + '\u{309A}', + '\u{3072}', + '\u{3099}', + '\u{3072}', + '\u{309A}', + '\u{3075}', + '\u{3099}', + '\u{3075}', + '\u{309A}', + '\u{3078}', + '\u{3099}', + '\u{3078}', + '\u{309A}', + '\u{307B}', + '\u{3099}', + '\u{307B}', + '\u{309A}', + '\u{3046}', + '\u{3099}', + '\u{309D}', + '\u{3099}', + '\u{30AB}', + '\u{3099}', + '\u{30AD}', + '\u{3099}', + '\u{30AF}', + '\u{3099}', + '\u{30B1}', + '\u{3099}', + '\u{30B3}', + '\u{3099}', + '\u{30B5}', + '\u{3099}', + '\u{30B7}', + '\u{3099}', + '\u{30B9}', + '\u{3099}', + '\u{30BB}', + '\u{3099}', + '\u{30BD}', + '\u{3099}', + '\u{30BF}', + '\u{3099}', + '\u{30C1}', + '\u{3099}', + '\u{30C4}', + '\u{3099}', + '\u{30C6}', + '\u{3099}', + '\u{30C8}', + '\u{3099}', + '\u{30CF}', + '\u{3099}', + '\u{30CF}', + '\u{309A}', + '\u{30D2}', + '\u{3099}', + '\u{30D2}', + '\u{309A}', + '\u{30D5}', + '\u{3099}', + '\u{30D5}', + '\u{309A}', + '\u{30D8}', + '\u{3099}', + '\u{30D8}', + '\u{309A}', + '\u{30DB}', + '\u{3099}', + '\u{30DB}', + '\u{309A}', + '\u{30A6}', + '\u{3099}', + '\u{30EF}', + '\u{3099}', + '\u{30F0}', + '\u{3099}', + '\u{30F1}', + '\u{3099}', + '\u{30F2}', + '\u{3099}', + '\u{30FD}', + '\u{3099}', + '\u{8C48}', + '\u{66F4}', + '\u{8ECA}', + '\u{8CC8}', + '\u{6ED1}', + '\u{4E32}', + '\u{53E5}', + '\u{9F9C}', + '\u{9F9C}', + '\u{5951}', + '\u{91D1}', + '\u{5587}', + '\u{5948}', + '\u{61F6}', + '\u{7669}', + '\u{7F85}', + '\u{863F}', + '\u{87BA}', + '\u{88F8}', + '\u{908F}', + '\u{6A02}', + '\u{6D1B}', + '\u{70D9}', + '\u{73DE}', + '\u{843D}', + '\u{916A}', + '\u{99F1}', + '\u{4E82}', + '\u{5375}', + '\u{6B04}', + '\u{721B}', + '\u{862D}', + '\u{9E1E}', + '\u{5D50}', + '\u{6FEB}', + '\u{85CD}', + '\u{8964}', + '\u{62C9}', + '\u{81D8}', + '\u{881F}', + '\u{5ECA}', + '\u{6717}', + '\u{6D6A}', + '\u{72FC}', + '\u{90CE}', + '\u{4F86}', + '\u{51B7}', + '\u{52DE}', + '\u{64C4}', + '\u{6AD3}', + '\u{7210}', + '\u{76E7}', + '\u{8001}', + '\u{8606}', + '\u{865C}', + '\u{8DEF}', + '\u{9732}', + '\u{9B6F}', + '\u{9DFA}', + '\u{788C}', + '\u{797F}', + '\u{7DA0}', + '\u{83C9}', + '\u{9304}', + '\u{9E7F}', + '\u{8AD6}', + '\u{58DF}', + '\u{5F04}', + '\u{7C60}', + '\u{807E}', + '\u{7262}', + '\u{78CA}', + '\u{8CC2}', + '\u{96F7}', + '\u{58D8}', + '\u{5C62}', + '\u{6A13}', + '\u{6DDA}', + '\u{6F0F}', + '\u{7D2F}', + '\u{7E37}', + '\u{964B}', + '\u{52D2}', + '\u{808B}', + '\u{51DC}', + '\u{51CC}', + '\u{7A1C}', + '\u{7DBE}', + '\u{83F1}', + '\u{9675}', + '\u{8B80}', + '\u{62CF}', + '\u{6A02}', + '\u{8AFE}', + '\u{4E39}', + '\u{5BE7}', + '\u{6012}', + '\u{7387}', + '\u{7570}', + '\u{5317}', + '\u{78FB}', + '\u{4FBF}', + '\u{5FA9}', + '\u{4E0D}', + '\u{6CCC}', + '\u{6578}', + '\u{7D22}', + '\u{53C3}', + '\u{585E}', + '\u{7701}', + '\u{8449}', + '\u{8AAA}', + '\u{6BBA}', + '\u{8FB0}', + '\u{6C88}', + '\u{62FE}', + '\u{82E5}', + '\u{63A0}', + '\u{7565}', + '\u{4EAE}', + '\u{5169}', + '\u{51C9}', + '\u{6881}', + '\u{7CE7}', + '\u{826F}', + '\u{8AD2}', + '\u{91CF}', + '\u{52F5}', + '\u{5442}', + '\u{5973}', + '\u{5EEC}', + '\u{65C5}', + '\u{6FFE}', + '\u{792A}', + '\u{95AD}', + '\u{9A6A}', + '\u{9E97}', + '\u{9ECE}', + '\u{529B}', + '\u{66C6}', + '\u{6B77}', + '\u{8F62}', + '\u{5E74}', + '\u{6190}', + '\u{6200}', + '\u{649A}', + '\u{6F23}', + '\u{7149}', + '\u{7489}', + '\u{79CA}', + '\u{7DF4}', + '\u{806F}', + '\u{8F26}', + '\u{84EE}', + '\u{9023}', + '\u{934A}', + '\u{5217}', + '\u{52A3}', + '\u{54BD}', + '\u{70C8}', + '\u{88C2}', + '\u{8AAA}', + '\u{5EC9}', + '\u{5FF5}', + '\u{637B}', + '\u{6BAE}', + '\u{7C3E}', + '\u{7375}', + '\u{4EE4}', + '\u{56F9}', + '\u{5BE7}', + '\u{5DBA}', + '\u{601C}', + '\u{73B2}', + '\u{7469}', + '\u{7F9A}', + '\u{8046}', + '\u{9234}', + '\u{96F6}', + '\u{9748}', + '\u{9818}', + '\u{4F8B}', + '\u{79AE}', + '\u{91B4}', + '\u{96B8}', + '\u{60E1}', + '\u{4E86}', + '\u{50DA}', + '\u{5BEE}', + '\u{5C3F}', + '\u{6599}', + '\u{6A02}', + '\u{71CE}', + '\u{7642}', + '\u{84FC}', + '\u{907C}', + '\u{9F8D}', + '\u{6688}', + '\u{962E}', + '\u{5289}', + '\u{677B}', + '\u{67F3}', + '\u{6D41}', + '\u{6E9C}', + '\u{7409}', + '\u{7559}', + '\u{786B}', + '\u{7D10}', + '\u{985E}', + '\u{516D}', + '\u{622E}', + '\u{9678}', + '\u{502B}', + '\u{5D19}', + '\u{6DEA}', + '\u{8F2A}', + '\u{5F8B}', + '\u{6144}', + '\u{6817}', + '\u{7387}', + '\u{9686}', + '\u{5229}', + '\u{540F}', + '\u{5C65}', + '\u{6613}', + '\u{674E}', + '\u{68A8}', + '\u{6CE5}', + '\u{7406}', + '\u{75E2}', + '\u{7F79}', + '\u{88CF}', + '\u{88E1}', + '\u{91CC}', + '\u{96E2}', + '\u{533F}', + '\u{6EBA}', + '\u{541D}', + '\u{71D0}', + '\u{7498}', + '\u{85FA}', + '\u{96A3}', + '\u{9C57}', + '\u{9E9F}', + '\u{6797}', + '\u{6DCB}', + '\u{81E8}', + '\u{7ACB}', + '\u{7B20}', + '\u{7C92}', + '\u{72C0}', + '\u{7099}', + '\u{8B58}', + '\u{4EC0}', + '\u{8336}', + '\u{523A}', + '\u{5207}', + '\u{5EA6}', + '\u{62D3}', + '\u{7CD6}', + '\u{5B85}', + '\u{6D1E}', + '\u{66B4}', + '\u{8F3B}', + '\u{884C}', + '\u{964D}', + '\u{898B}', + '\u{5ED3}', + '\u{5140}', + '\u{55C0}', + '\u{585A}', + '\u{6674}', + '\u{51DE}', + '\u{732A}', + '\u{76CA}', + '\u{793C}', + '\u{795E}', + '\u{7965}', + '\u{798F}', + '\u{9756}', + '\u{7CBE}', + '\u{7FBD}', + '\u{8612}', + '\u{8AF8}', + '\u{9038}', + '\u{90FD}', + '\u{98EF}', + '\u{98FC}', + '\u{9928}', + '\u{9DB4}', + '\u{90DE}', + '\u{96B7}', + '\u{4FAE}', + '\u{50E7}', + '\u{514D}', + '\u{52C9}', + '\u{52E4}', + '\u{5351}', + '\u{559D}', + '\u{5606}', + '\u{5668}', + '\u{5840}', + '\u{58A8}', + '\u{5C64}', + '\u{5C6E}', + '\u{6094}', + '\u{6168}', + '\u{618E}', + '\u{61F2}', + '\u{654F}', + '\u{65E2}', + '\u{6691}', + '\u{6885}', + '\u{6D77}', + '\u{6E1A}', + '\u{6F22}', + '\u{716E}', + '\u{722B}', + '\u{7422}', + '\u{7891}', + '\u{793E}', + '\u{7949}', + '\u{7948}', + '\u{7950}', + '\u{7956}', + '\u{795D}', + '\u{798D}', + '\u{798E}', + '\u{7A40}', + '\u{7A81}', + '\u{7BC0}', + '\u{7DF4}', + '\u{7E09}', + '\u{7E41}', + '\u{7F72}', + '\u{8005}', + '\u{81ED}', + '\u{8279}', + '\u{8279}', + '\u{8457}', + '\u{8910}', + '\u{8996}', + '\u{8B01}', + '\u{8B39}', + '\u{8CD3}', + '\u{8D08}', + '\u{8FB6}', + '\u{9038}', + '\u{96E3}', + '\u{97FF}', + '\u{983B}', + '\u{6075}', + '\u{242EE}', + '\u{8218}', + '\u{4E26}', + '\u{51B5}', + '\u{5168}', + '\u{4F80}', + '\u{5145}', + '\u{5180}', + '\u{52C7}', + '\u{52FA}', + '\u{559D}', + '\u{5555}', + '\u{5599}', + '\u{55E2}', + '\u{585A}', + '\u{58B3}', + '\u{5944}', + '\u{5954}', + '\u{5A62}', + '\u{5B28}', + '\u{5ED2}', + '\u{5ED9}', + '\u{5F69}', + '\u{5FAD}', + '\u{60D8}', + '\u{614E}', + '\u{6108}', + '\u{618E}', + '\u{6160}', + '\u{61F2}', + '\u{6234}', + '\u{63C4}', + '\u{641C}', + '\u{6452}', + '\u{6556}', + '\u{6674}', + '\u{6717}', + '\u{671B}', + '\u{6756}', + '\u{6B79}', + '\u{6BBA}', + '\u{6D41}', + '\u{6EDB}', + '\u{6ECB}', + '\u{6F22}', + '\u{701E}', + '\u{716E}', + '\u{77A7}', + '\u{7235}', + '\u{72AF}', + '\u{732A}', + '\u{7471}', + '\u{7506}', + '\u{753B}', + '\u{761D}', + '\u{761F}', + '\u{76CA}', + '\u{76DB}', + '\u{76F4}', + '\u{774A}', + '\u{7740}', + '\u{78CC}', + '\u{7AB1}', + '\u{7BC0}', + '\u{7C7B}', + '\u{7D5B}', + '\u{7DF4}', + '\u{7F3E}', + '\u{8005}', + '\u{8352}', + '\u{83EF}', + '\u{8779}', + '\u{8941}', + '\u{8986}', + '\u{8996}', + '\u{8ABF}', + '\u{8AF8}', + '\u{8ACB}', + '\u{8B01}', + '\u{8AFE}', + '\u{8AED}', + '\u{8B39}', + '\u{8B8A}', + '\u{8D08}', + '\u{8F38}', + '\u{9072}', + '\u{9199}', + '\u{9276}', + '\u{967C}', + '\u{96E3}', + '\u{9756}', + '\u{97DB}', + '\u{97FF}', + '\u{980B}', + '\u{983B}', + '\u{9B12}', + '\u{9F9C}', + '\u{2284A}', + '\u{22844}', + '\u{233D5}', + '\u{3B9D}', + '\u{4018}', + '\u{4039}', + '\u{25249}', + '\u{25CD0}', + '\u{27ED3}', + '\u{9F43}', + '\u{9F8E}', + '\u{05D9}', + '\u{05B4}', + '\u{05F2}', + '\u{05B7}', + '\u{05E9}', + '\u{05C1}', + '\u{05E9}', + '\u{05C2}', + '\u{05E9}', + '\u{05BC}', + '\u{05C1}', + '\u{05E9}', + '\u{05BC}', + '\u{05C2}', + '\u{05D0}', + '\u{05B7}', + '\u{05D0}', + '\u{05B8}', + '\u{05D0}', + '\u{05BC}', + '\u{05D1}', + '\u{05BC}', + '\u{05D2}', + '\u{05BC}', + '\u{05D3}', + '\u{05BC}', + '\u{05D4}', + '\u{05BC}', + '\u{05D5}', + '\u{05BC}', + '\u{05D6}', + '\u{05BC}', + '\u{05D8}', + '\u{05BC}', + '\u{05D9}', + '\u{05BC}', + '\u{05DA}', + '\u{05BC}', + '\u{05DB}', + '\u{05BC}', + '\u{05DC}', + '\u{05BC}', + '\u{05DE}', + '\u{05BC}', + '\u{05E0}', + '\u{05BC}', + '\u{05E1}', + '\u{05BC}', + '\u{05E3}', + '\u{05BC}', + '\u{05E4}', + '\u{05BC}', + '\u{05E6}', + '\u{05BC}', + '\u{05E7}', + '\u{05BC}', + '\u{05E8}', + '\u{05BC}', + '\u{05E9}', + '\u{05BC}', + '\u{05EA}', + '\u{05BC}', + '\u{05D5}', + '\u{05B9}', + '\u{05D1}', + '\u{05BF}', + '\u{05DB}', + '\u{05BF}', + '\u{05E4}', + '\u{05BF}', + '\u{105D2}', + '\u{0307}', + '\u{105DA}', + '\u{0307}', + '\u{11099}', + '\u{110BA}', + '\u{1109B}', + '\u{110BA}', + '\u{110A5}', + '\u{110BA}', + '\u{11131}', + '\u{11127}', + '\u{11132}', + '\u{11127}', + '\u{11347}', + '\u{1133E}', + '\u{11347}', + '\u{11357}', + '\u{11382}', + '\u{113C9}', + '\u{11384}', + '\u{113BB}', + '\u{1138B}', + '\u{113C2}', + '\u{11390}', + '\u{113C9}', + '\u{113C2}', + '\u{113C2}', + '\u{113C2}', + '\u{113B8}', + '\u{113C2}', + '\u{113C9}', + '\u{114B9}', + '\u{114BA}', + '\u{114B9}', + '\u{114B0}', + '\u{114B9}', + '\u{114BD}', + '\u{115B8}', + '\u{115AF}', + '\u{115B9}', + '\u{115AF}', + '\u{11935}', + '\u{11930}', + '\u{1611E}', + '\u{1611E}', + '\u{1611E}', + '\u{16129}', + '\u{1611E}', + '\u{1611F}', + '\u{16129}', + '\u{1611F}', + '\u{1611E}', + '\u{16120}', + '\u{1611E}', + '\u{1611E}', + '\u{1611F}', + '\u{1611E}', + '\u{16129}', + '\u{1611F}', + '\u{1611E}', + '\u{1611E}', + '\u{16120}', + '\u{16D67}', + '\u{16D67}', + '\u{16D63}', + '\u{16D67}', + '\u{16D63}', + '\u{16D67}', + '\u{16D67}', + '\u{1D157}', + '\u{1D165}', + '\u{1D158}', + '\u{1D165}', + '\u{1D158}', + '\u{1D165}', + '\u{1D16E}', + '\u{1D158}', + '\u{1D165}', + '\u{1D16F}', + '\u{1D158}', + '\u{1D165}', + '\u{1D170}', + '\u{1D158}', + '\u{1D165}', + '\u{1D171}', + '\u{1D158}', + '\u{1D165}', + '\u{1D172}', + '\u{1D1B9}', + '\u{1D165}', + '\u{1D1BA}', + '\u{1D165}', + '\u{1D1B9}', + '\u{1D165}', + '\u{1D16E}', + '\u{1D1BA}', + '\u{1D165}', + '\u{1D16E}', + '\u{1D1B9}', + '\u{1D165}', + '\u{1D16F}', + '\u{1D1BA}', + '\u{1D165}', + '\u{1D16F}', + '\u{4E3D}', + '\u{4E38}', + '\u{4E41}', + '\u{20122}', + '\u{4F60}', + '\u{4FAE}', + '\u{4FBB}', + '\u{5002}', + '\u{507A}', + '\u{5099}', + '\u{50E7}', + '\u{50CF}', + '\u{349E}', + '\u{2063A}', + '\u{514D}', + '\u{5154}', + '\u{5164}', + '\u{5177}', + '\u{2051C}', + '\u{34B9}', + '\u{5167}', + '\u{518D}', + '\u{2054B}', + '\u{5197}', + '\u{51A4}', + '\u{4ECC}', + '\u{51AC}', + '\u{51B5}', + '\u{291DF}', + '\u{51F5}', + '\u{5203}', + '\u{34DF}', + '\u{523B}', + '\u{5246}', + '\u{5272}', + '\u{5277}', + '\u{3515}', + '\u{52C7}', + '\u{52C9}', + '\u{52E4}', + '\u{52FA}', + '\u{5305}', + '\u{5306}', + '\u{5317}', + '\u{5349}', + '\u{5351}', + '\u{535A}', + '\u{5373}', + '\u{537D}', + '\u{537F}', + '\u{537F}', + '\u{537F}', + '\u{20A2C}', + '\u{7070}', + '\u{53CA}', + '\u{53DF}', + '\u{20B63}', + '\u{53EB}', + '\u{53F1}', + '\u{5406}', + '\u{549E}', + '\u{5438}', + '\u{5448}', + '\u{5468}', + '\u{54A2}', + '\u{54F6}', + '\u{5510}', + '\u{5553}', + '\u{5563}', + '\u{5584}', + '\u{5584}', + '\u{5599}', + '\u{55AB}', + '\u{55B3}', + '\u{55C2}', + '\u{5716}', + '\u{5606}', + '\u{5717}', + '\u{5651}', + '\u{5674}', + '\u{5207}', + '\u{58EE}', + '\u{57CE}', + '\u{57F4}', + '\u{580D}', + '\u{578B}', + '\u{5832}', + '\u{5831}', + '\u{58AC}', + '\u{214E4}', + '\u{58F2}', + '\u{58F7}', + '\u{5906}', + '\u{591A}', + '\u{5922}', + '\u{5962}', + '\u{216A8}', + '\u{216EA}', + '\u{59EC}', + '\u{5A1B}', + '\u{5A27}', + '\u{59D8}', + '\u{5A66}', + '\u{36EE}', + '\u{36FC}', + '\u{5B08}', + '\u{5B3E}', + '\u{5B3E}', + '\u{219C8}', + '\u{5BC3}', + '\u{5BD8}', + '\u{5BE7}', + '\u{5BF3}', + '\u{21B18}', + '\u{5BFF}', + '\u{5C06}', + '\u{5F53}', + '\u{5C22}', + '\u{3781}', + '\u{5C60}', + '\u{5C6E}', + '\u{5CC0}', + '\u{5C8D}', + '\u{21DE4}', + '\u{5D43}', + '\u{21DE6}', + '\u{5D6E}', + '\u{5D6B}', + '\u{5D7C}', + '\u{5DE1}', + '\u{5DE2}', + '\u{382F}', + '\u{5DFD}', + '\u{5E28}', + '\u{5E3D}', + '\u{5E69}', + '\u{3862}', + '\u{22183}', + '\u{387C}', + '\u{5EB0}', + '\u{5EB3}', + '\u{5EB6}', + '\u{5ECA}', + '\u{2A392}', + '\u{5EFE}', + '\u{22331}', + '\u{22331}', + '\u{8201}', + '\u{5F22}', + '\u{5F22}', + '\u{38C7}', + '\u{232B8}', + '\u{261DA}', + '\u{5F62}', + '\u{5F6B}', + '\u{38E3}', + '\u{5F9A}', + '\u{5FCD}', + '\u{5FD7}', + '\u{5FF9}', + '\u{6081}', + '\u{393A}', + '\u{391C}', + '\u{6094}', + '\u{226D4}', + '\u{60C7}', + '\u{6148}', + '\u{614C}', + '\u{614E}', + '\u{614C}', + '\u{617A}', + '\u{618E}', + '\u{61B2}', + '\u{61A4}', + '\u{61AF}', + '\u{61DE}', + '\u{61F2}', + '\u{61F6}', + '\u{6210}', + '\u{621B}', + '\u{625D}', + '\u{62B1}', + '\u{62D4}', + '\u{6350}', + '\u{22B0C}', + '\u{633D}', + '\u{62FC}', + '\u{6368}', + '\u{6383}', + '\u{63E4}', + '\u{22BF1}', + '\u{6422}', + '\u{63C5}', + '\u{63A9}', + '\u{3A2E}', + '\u{6469}', + '\u{647E}', + '\u{649D}', + '\u{6477}', + '\u{3A6C}', + '\u{654F}', + '\u{656C}', + '\u{2300A}', + '\u{65E3}', + '\u{66F8}', + '\u{6649}', + '\u{3B19}', + '\u{6691}', + '\u{3B08}', + '\u{3AE4}', + '\u{5192}', + '\u{5195}', + '\u{6700}', + '\u{669C}', + '\u{80AD}', + '\u{43D9}', + '\u{6717}', + '\u{671B}', + '\u{6721}', + '\u{675E}', + '\u{6753}', + '\u{233C3}', + '\u{3B49}', + '\u{67FA}', + '\u{6785}', + '\u{6852}', + '\u{6885}', + '\u{2346D}', + '\u{688E}', + '\u{681F}', + '\u{6914}', + '\u{3B9D}', + '\u{6942}', + '\u{69A3}', + '\u{69EA}', + '\u{6AA8}', + '\u{236A3}', + '\u{6ADB}', + '\u{3C18}', + '\u{6B21}', + '\u{238A7}', + '\u{6B54}', + '\u{3C4E}', + '\u{6B72}', + '\u{6B9F}', + '\u{6BBA}', + '\u{6BBB}', + '\u{23A8D}', + '\u{21D0B}', + '\u{23AFA}', + '\u{6C4E}', + '\u{23CBC}', + '\u{6CBF}', + '\u{6CCD}', + '\u{6C67}', + '\u{6D16}', + '\u{6D3E}', + '\u{6D77}', + '\u{6D41}', + '\u{6D69}', + '\u{6D78}', + '\u{6D85}', + '\u{23D1E}', + '\u{6D34}', + '\u{6E2F}', + '\u{6E6E}', + '\u{3D33}', + '\u{6ECB}', + '\u{6EC7}', + '\u{23ED1}', + '\u{6DF9}', + '\u{6F6E}', + '\u{23F5E}', + '\u{23F8E}', + '\u{6FC6}', + '\u{7039}', + '\u{701E}', + '\u{701B}', + '\u{3D96}', + '\u{704A}', + '\u{707D}', + '\u{7077}', + '\u{70AD}', + '\u{20525}', + '\u{7145}', + '\u{24263}', + '\u{719C}', + '\u{243AB}', + '\u{7228}', + '\u{7235}', + '\u{7250}', + '\u{24608}', + '\u{7280}', + '\u{7295}', + '\u{24735}', + '\u{24814}', + '\u{737A}', + '\u{738B}', + '\u{3EAC}', + '\u{73A5}', + '\u{3EB8}', + '\u{3EB8}', + '\u{7447}', + '\u{745C}', + '\u{7471}', + '\u{7485}', + '\u{74CA}', + '\u{3F1B}', + '\u{7524}', + '\u{24C36}', + '\u{753E}', + '\u{24C92}', + '\u{7570}', + '\u{2219F}', + '\u{7610}', + '\u{24FA1}', + '\u{24FB8}', + '\u{25044}', + '\u{3FFC}', + '\u{4008}', + '\u{76F4}', + '\u{250F3}', + '\u{250F2}', + '\u{25119}', + '\u{25133}', + '\u{771E}', + '\u{771F}', + '\u{771F}', + '\u{774A}', + '\u{4039}', + '\u{778B}', + '\u{4046}', + '\u{4096}', + '\u{2541D}', + '\u{784E}', + '\u{788C}', + '\u{78CC}', + '\u{40E3}', + '\u{25626}', + '\u{7956}', + '\u{2569A}', + '\u{256C5}', + '\u{798F}', + '\u{79EB}', + '\u{412F}', + '\u{7A40}', + '\u{7A4A}', + '\u{7A4F}', + '\u{2597C}', + '\u{25AA7}', + '\u{25AA7}', + '\u{7AEE}', + '\u{4202}', + '\u{25BAB}', + '\u{7BC6}', + '\u{7BC9}', + '\u{4227}', + '\u{25C80}', + '\u{7CD2}', + '\u{42A0}', + '\u{7CE8}', + '\u{7CE3}', + '\u{7D00}', + '\u{25F86}', + '\u{7D63}', + '\u{4301}', + '\u{7DC7}', + '\u{7E02}', + '\u{7E45}', + '\u{4334}', + '\u{26228}', + '\u{26247}', + '\u{4359}', + '\u{262D9}', + '\u{7F7A}', + '\u{2633E}', + '\u{7F95}', + '\u{7FFA}', + '\u{8005}', + '\u{264DA}', + '\u{26523}', + '\u{8060}', + '\u{265A8}', + '\u{8070}', + '\u{2335F}', + '\u{43D5}', + '\u{80B2}', + '\u{8103}', + '\u{440B}', + '\u{813E}', + '\u{5AB5}', + '\u{267A7}', + '\u{267B5}', + '\u{23393}', + '\u{2339C}', + '\u{8201}', + '\u{8204}', + '\u{8F9E}', + '\u{446B}', + '\u{8291}', + '\u{828B}', + '\u{829D}', + '\u{52B3}', + '\u{82B1}', + '\u{82B3}', + '\u{82BD}', + '\u{82E6}', + '\u{26B3C}', + '\u{82E5}', + '\u{831D}', + '\u{8363}', + '\u{83AD}', + '\u{8323}', + '\u{83BD}', + '\u{83E7}', + '\u{8457}', + '\u{8353}', + '\u{83CA}', + '\u{83CC}', + '\u{83DC}', + '\u{26C36}', + '\u{26D6B}', + '\u{26CD5}', + '\u{452B}', + '\u{84F1}', + '\u{84F3}', + '\u{8516}', + '\u{273CA}', + '\u{8564}', + '\u{26F2C}', + '\u{455D}', + '\u{4561}', + '\u{26FB1}', + '\u{270D2}', + '\u{456B}', + '\u{8650}', + '\u{865C}', + '\u{8667}', + '\u{8669}', + '\u{86A9}', + '\u{8688}', + '\u{870E}', + '\u{86E2}', + '\u{8779}', + '\u{8728}', + '\u{876B}', + '\u{8786}', + '\u{45D7}', + '\u{87E1}', + '\u{8801}', + '\u{45F9}', + '\u{8860}', + '\u{8863}', + '\u{27667}', + '\u{88D7}', + '\u{88DE}', + '\u{4635}', + '\u{88FA}', + '\u{34BB}', + '\u{278AE}', + '\u{27966}', + '\u{46BE}', + '\u{46C7}', + '\u{8AA0}', + '\u{8AED}', + '\u{8B8A}', + '\u{8C55}', + '\u{27CA8}', + '\u{8CAB}', + '\u{8CC1}', + '\u{8D1B}', + '\u{8D77}', + '\u{27F2F}', + '\u{20804}', + '\u{8DCB}', + '\u{8DBC}', + '\u{8DF0}', + '\u{208DE}', + '\u{8ED4}', + '\u{8F38}', + '\u{285D2}', + '\u{285ED}', + '\u{9094}', + '\u{90F1}', + '\u{9111}', + '\u{2872E}', + '\u{911B}', + '\u{9238}', + '\u{92D7}', + '\u{92D8}', + '\u{927C}', + '\u{93F9}', + '\u{9415}', + '\u{28BFA}', + '\u{958B}', + '\u{4995}', + '\u{95B7}', + '\u{28D77}', + '\u{49E6}', + '\u{96C3}', + '\u{5DB2}', + '\u{9723}', + '\u{29145}', + '\u{2921A}', + '\u{4A6E}', + '\u{4A76}', + '\u{97E0}', + '\u{2940A}', + '\u{4AB2}', + '\u{29496}', + '\u{980B}', + '\u{980B}', + '\u{9829}', + '\u{295B6}', + '\u{98E2}', + '\u{4B33}', + '\u{9929}', + '\u{99A7}', + '\u{99C2}', + '\u{99FE}', + '\u{4BCE}', + '\u{29B30}', + '\u{9B12}', + '\u{9C40}', + '\u{9CFD}', + '\u{4CCE}', + '\u{4CED}', + '\u{9D67}', + '\u{2A0CE}', + '\u{4CF8}', + '\u{2A105}', + '\u{2A20E}', + '\u{2A291}', + '\u{9EBB}', + '\u{4D56}', + '\u{9EF9}', + '\u{9EFE}', + '\u{9F05}', + '\u{9F0F}', + '\u{9F16}', + '\u{9F3B}', + '\u{2A600}', +]; + +pub(crate) const CANONICAL_DECOMPOSED_SALT: &[u16] = &[ + 0x571, 0x003, 0x000, 0x000, 0x03D, 0x160, 0x000, 0x27F, 0x0F7, 0x1B1, 0x000, 0x002, 0x004, + 0x033, 0x136, 0x017, 0x001, 0x000, 0x193, 0x1EE, 0x000, 0x006, 0x000, 0x054, 0x034, 0x002, + 0x054, 0x248, 0x008, 0x006, 0x003, 0x000, 0x000, 0x000, 0x064, 0x001, 0x000, 0x000, 0x002, + 0x005, 0x000, 0x000, 0x01E, 0x035, 0x009, 0x07D, 0x004, 0x012, 0x058, 0x000, 0x000, 0x000, + 0x002, 0x04C, 0x000, 0x000, 0x006, 0x068, 0x000, 0x006, 0x000, 0x00A, 0x006, 0x001, 0x0F6, + 0x000, 0x000, 0x002, 0x046, 0x000, 0x001, 0x000, 0x003, 0x000, 0x140, 0x000, 0x00A, 0x0DF, + 0x001, 0x000, 0x003, 0x004, 0x008, 0x005, 0x004, 0x014, 0x030, 0x05B, 0x000, 0x018, 0x0A8, + 0x000, 0x048, 0x004, 0x000, 0x005, 0x000, 0x042, 0x000, 0x068, 0x000, 0x000, 0x02D, 0x000, + 0x000, 0x000, 0x032, 0x006, 0x000, 0x01F, 0x061, 0x000, 0x00D, 0x000, 0x013, 0x005, 0x027, + 0x002, 0x002, 0x002, 0x002, 0x013, 0x037, 0x010, 0x000, 0x019, 0x006, 0x000, 0x02C, 0x05F, + 0x05F, 0x000, 0x001, 0x000, 0x005, 0x000, 0x000, 0x005, 0x006, 0x022, 0x03C, 0x010, 0x000, + 0x000, 0x000, 0x012, 0x002, 0x004, 0x051, 0x000, 0x000, 0x002, 0x032, 0x006, 0x001, 0x000, + 0x011, 0x005, 0x004, 0x075, 0x032, 0x00A, 0x000, 0x016, 0x00E, 0x001, 0x00F, 0x027, 0x000, + 0x005, 0x001, 0x00A, 0x007, 0x010, 0x004, 0x001, 0x000, 0x007, 0x00F, 0x002, 0x005, 0x05E, + 0x000, 0x048, 0x017, 0x000, 0x000, 0x004, 0x000, 0x002, 0x03C, 0x01C, 0x00B, 0x000, 0x004, + 0x023, 0x001, 0x00C, 0x00E, 0x005, 0x01C, 0x000, 0x020, 0x001, 0x003, 0x000, 0x007, 0x008, + 0x004, 0x000, 0x000, 0x02D, 0x008, 0x000, 0x000, 0x033, 0x013, 0x002, 0x000, 0x003, 0x000, + 0x006, 0x03C, 0x020, 0x000, 0x009, 0x000, 0x025, 0x012, 0x009, 0x000, 0x000, 0x03A, 0x022, + 0x000, 0x002, 0x001, 0x01E, 0x009, 0x002, 0x002, 0x003, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x00B, 0x001, 0x001, 0x01B, 0x004, 0x007, 0x00E, 0x003, 0x000, 0x003, 0x007, 0x000, + 0x002, 0x002, 0x026, 0x000, 0x008, 0x003, 0x004, 0x002, 0x002, 0x008, 0x009, 0x000, 0x001, + 0x006, 0x001, 0x003, 0x002, 0x001, 0x008, 0x000, 0x004, 0x009, 0x00C, 0x013, 0x000, 0x000, + 0x005, 0x000, 0x00A, 0x000, 0x014, 0x000, 0x014, 0x000, 0x001, 0x000, 0x000, 0x000, 0x01C, + 0x016, 0x000, 0x000, 0x002, 0x004, 0x000, 0x000, 0x000, 0x00A, 0x000, 0x000, 0x007, 0x002, + 0x000, 0x000, 0x004, 0x001, 0x00A, 0x000, 0x000, 0x009, 0x005, 0x029, 0x000, 0x000, 0x001, + 0x020, 0x003, 0x006, 0x002, 0x001, 0x00E, 0x013, 0x001, 0x024, 0x000, 0x001, 0x001, 0x003, + 0x004, 0x002, 0x002, 0x00A, 0x006, 0x008, 0x000, 0x00A, 0x000, 0x004, 0x000, 0x00D, 0x00B, + 0x000, 0x013, 0x009, 0x000, 0x000, 0x012, 0x000, 0x006, 0x000, 0x000, 0x002, 0x000, 0x000, + 0x00C, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x013, 0x002, 0x000, 0x002, 0x000, + 0x000, 0x000, 0x000, 0x008, 0x000, 0x000, 0x001, 0x001, 0x004, 0x010, 0x000, 0x00B, 0x00B, + 0x002, 0x001, 0x000, 0x001, 0x001, 0x002, 0x002, 0x001, 0x001, 0x002, 0x004, 0x008, 0x000, + 0x000, 0x001, 0x029, 0x001, 0x00E, 0x000, 0x000, 0x00E, 0x000, 0x00B, 0x000, 0x017, 0x005, + 0x000, 0x015, 0x008, 0x006, 0x008, 0x000, 0x002, 0x00C, 0x000, 0x000, 0x000, 0x008, 0x000, + 0x000, 0x000, 0x000, 0x00C, 0x000, 0x000, 0x004, 0x000, 0x000, 0x000, 0x00F, 0x000, 0x000, + 0x001, 0x007, 0x000, 0x011, 0x000, 0x00D, 0x008, 0x00E, 0x00B, 0x000, 0x002, 0x001, 0x000, + 0x004, 0x005, 0x003, 0x003, 0x001, 0x003, 0x008, 0x001, 0x01A, 0x001, 0x005, 0x001, 0x005, + 0x006, 0x000, 0x001, 0x000, 0x000, 0x000, 0x010, 0x00F, 0x002, 0x004, 0x006, 0x002, 0x002, + 0x00C, 0x017, 0x003, 0x000, 0x003, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x022, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x01C, 0x014, 0x001, 0x000, + 0x002, 0x004, 0x00F, 0x000, 0x007, 0x001, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000, 0x006, + 0x009, 0x003, 0x02C, 0x009, 0x005, 0x000, 0x000, 0x00B, 0x008, 0x01D, 0x000, 0x001, 0x000, + 0x000, 0x000, 0x001, 0x008, 0x003, 0x005, 0x000, 0x004, 0x000, 0x000, 0x003, 0x00A, 0x003, + 0x000, 0x005, 0x002, 0x004, 0x00A, 0x000, 0x000, 0x003, 0x002, 0x000, 0x002, 0x000, 0x00E, + 0x000, 0x000, 0x005, 0x000, 0x009, 0x017, 0x003, 0x004, 0x000, 0x001, 0x004, 0x000, 0x000, + 0x007, 0x015, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x009, 0x003, 0x001, 0x001, + 0x001, 0x006, 0x00A, 0x000, 0x000, 0x006, 0x000, 0x001, 0x000, 0x000, 0x002, 0x000, 0x000, + 0x001, 0x001, 0x002, 0x000, 0x000, 0x000, 0x003, 0x003, 0x012, 0x001, 0x006, 0x004, 0x007, + 0x000, 0x001, 0x000, 0x02E, 0x002, 0x001, 0x00B, 0x008, 0x000, 0x005, 0x000, 0x002, 0x004, + 0x009, 0x000, 0x000, 0x008, 0x005, 0x003, 0x001, 0x006, 0x000, 0x000, 0x003, 0x000, 0x003, + 0x006, 0x006, 0x000, 0x003, 0x007, 0x000, 0x006, 0x001, 0x000, 0x000, 0x006, 0x004, 0x000, + 0x000, 0x001, 0x000, 0x002, 0x000, 0x005, 0x000, 0x022, 0x014, 0x006, 0x002, 0x000, 0x000, + 0x000, 0x000, 0x00C, 0x000, 0x00A, 0x001, 0x002, 0x007, 0x000, 0x002, 0x001, 0x001, 0x004, + 0x000, 0x000, 0x012, 0x002, 0x001, 0x000, 0x000, 0x000, 0x003, 0x003, 0x000, 0x005, 0x000, + 0x000, 0x003, 0x000, 0x003, 0x000, 0x006, 0x000, 0x005, 0x001, 0x000, 0x008, 0x004, 0x000, + 0x009, 0x001, 0x00A, 0x00E, 0x000, 0x005, 0x00E, 0x007, 0x000, 0x000, 0x008, 0x000, 0x000, + 0x000, 0x000, 0x004, 0x000, 0x001, 0x001, 0x000, 0x000, 0x002, 0x000, 0x001, 0x000, 0x010, + 0x016, 0x001, 0x001, 0x000, 0x000, 0x000, 0x011, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x002, 0x000, 0x001, 0x006, 0x002, 0x01A, 0x000, 0x00B, 0x004, 0x000, 0x000, 0x003, + 0x006, 0x001, 0x009, 0x00F, 0x002, 0x005, 0x001, 0x01A, 0x000, 0x000, 0x000, 0x001, 0x002, + 0x002, 0x00F, 0x000, 0x000, 0x00A, 0x002, 0x003, 0x002, 0x007, 0x006, 0x000, 0x007, 0x004, + 0x00C, 0x000, 0x000, 0x001, 0x007, 0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x000, 0x000, + 0x000, 0x002, 0x000, 0x000, 0x000, 0x00A, 0x006, 0x000, 0x002, 0x000, 0x000, 0x000, 0x00D, + 0x000, 0x003, 0x001, 0x00A, 0x000, 0x00C, 0x000, 0x001, 0x000, 0x007, 0x003, 0x002, 0x001, + 0x002, 0x001, 0x007, 0x003, 0x002, 0x001, 0x004, 0x001, 0x000, 0x000, 0x008, 0x006, 0x000, + 0x000, 0x001, 0x00D, 0x004, 0x001, 0x002, 0x001, 0x004, 0x000, 0x000, 0x000, 0x007, 0x002, + 0x000, 0x000, 0x000, 0x000, 0x013, 0x000, 0x000, 0x000, 0x000, 0x003, 0x011, 0x001, 0x001, + 0x003, 0x006, 0x000, 0x006, 0x003, 0x001, 0x000, 0x000, 0x000, 0x00B, 0x000, 0x004, 0x006, + 0x000, 0x000, 0x005, 0x000, 0x002, 0x000, 0x001, 0x001, 0x005, 0x001, 0x007, 0x005, 0x000, + 0x001, 0x001, 0x000, 0x001, 0x001, 0x007, 0x009, 0x001, 0x00C, 0x004, 0x002, 0x001, 0x000, + 0x005, 0x000, 0x000, 0x001, 0x002, 0x001, 0x008, 0x005, 0x00B, 0x002, 0x000, 0x007, 0x001, + 0x004, 0x016, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x016, 0x000, + 0x000, 0x00E, 0x000, 0x000, 0x002, 0x004, 0x000, 0x000, 0x002, 0x000, 0x004, 0x006, 0x001, + 0x000, 0x000, 0x000, 0x00C, 0x007, 0x009, 0x004, 0x003, 0x001, 0x001, 0x009, 0x00D, 0x001, + 0x002, 0x003, 0x000, 0x004, 0x004, 0x004, 0x002, 0x000, 0x001, 0x00B, 0x000, 0x012, 0x000, + 0x003, 0x003, 0x001, 0x001, 0x001, 0x00E, 0x000, 0x001, 0x001, 0x004, 0x001, 0x002, 0x000, + 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x013, 0x000, 0x000, 0x000, + 0x000, 0x003, 0x000, 0x000, 0x000, 0x009, 0x000, 0x001, 0x007, 0x000, 0x002, 0x000, 0x00C, + 0x001, 0x003, 0x000, 0x001, 0x000, 0x005, 0x001, 0x000, 0x001, 0x003, 0x002, 0x009, 0x001, + 0x000, 0x008, 0x001, 0x005, 0x002, 0x000, 0x004, 0x000, 0x001, 0x005, 0x000, 0x008, 0x003, + 0x000, 0x004, 0x000, 0x000, 0x006, 0x003, 0x003, 0x002, 0x000, 0x002, 0x000, 0x002, 0x002, + 0x008, 0x000, 0x00A, 0x004, 0x012, 0x006, 0x002, 0x003, 0x002, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x007, 0x001, 0x006, 0x000, 0x001, 0x005, 0x00B, 0x000, 0x00D, 0x012, 0x005, 0x002, + 0x004, 0x000, 0x005, 0x00B, 0x000, 0x007, 0x004, 0x001, 0x003, 0x008, 0x003, 0x002, 0x005, + 0x001, 0x000, 0x002, 0x002, 0x000, 0x000, 0x001, 0x002, 0x000, 0x001, 0x000, 0x000, 0x001, + 0x008, 0x003, 0x000, 0x000, 0x000, 0x000, 0x002, 0x008, 0x000, 0x002, 0x000, 0x001, 0x00E, + 0x000, 0x000, 0x003, 0x002, 0x006, 0x000, 0x001, 0x008, 0x002, 0x005, 0x000, 0x001, 0x001, + 0x007, 0x006, 0x001, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x002, 0x001, 0x001, 0x005, + 0x000, 0x003, 0x009, 0x002, 0x000, 0x001, 0x000, 0x009, 0x001, 0x001, 0x002, 0x001, 0x002, + 0x003, 0x002, 0x000, 0x000, 0x000, 0x006, 0x001, 0x000, 0x001, 0x006, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, + 0x014, 0x000, 0x000, 0x000, 0x001, 0x000, 0x006, 0x001, 0x000, 0x000, 0x012, 0x000, 0x004, + 0x012, 0x003, 0x004, 0x002, 0x000, 0x000, 0x000, 0x005, 0x006, 0x000, 0x001, 0x001, 0x000, + 0x000, 0x006, 0x002, 0x004, 0x004, 0x002, 0x000, 0x000, 0x002, 0x001, 0x001, 0x000, 0x001, + 0x00B, 0x000, 0x006, 0x000, 0x000, 0x000, 0x002, 0x001, 0x009, 0x001, 0x002, 0x010, 0x001, + 0x002, 0x002, 0x001, 0x000, 0x001, 0x00F, 0x009, 0x001, 0x001, 0x000, 0x000, 0x001, 0x001, + 0x001, 0x000, 0x000, 0x000, 0x002, 0x000, 0x002, 0x000, 0x000, 0x000, 0x003, 0x001, 0x007, + 0x00F, 0x005, 0x005, 0x000, 0x000, 0x000, 0x001, 0x004, 0x000, 0x002, 0x004, 0x003, 0x001, + 0x001, 0x002, 0x004, 0x001, 0x002, 0x001, 0x002, 0x002, 0x009, 0x000, 0x001, 0x000, 0x005, + 0x00B, 0x001, 0x000, 0x002, 0x00B, 0x000, 0x004, 0x000, 0x001, 0x001, 0x001, 0x000, 0x009, + 0x002, 0x005, 0x000, 0x004, 0x003, 0x002, 0x001, 0x001, 0x002, 0x000, 0x006, 0x00A, 0x000, + 0x002, 0x001, 0x009, 0x001, 0x001, 0x001, 0x008, 0x001, 0x002, 0x001, 0x001, 0x000, 0x001, + 0x003, 0x001, 0x001, 0x001, 0x003, 0x001, 0x005, 0x001, 0x003, 0x001, 0x000, 0x000, 0x006, + 0x000, 0x004, 0x001, 0x003, 0x001, 0x003, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x00B, 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, 0x006, 0x000, 0x000, + 0x002, 0x003, 0x003, 0x002, 0x002, 0x000, 0x004, 0x002, 0x000, 0x001, 0x001, 0x00A, 0x003, + 0x000, 0x003, 0x004, 0x001, 0x001, 0x003, 0x000, 0x000, 0x004, 0x004, 0x001, 0x002, 0x005, + 0x00C, 0x001, 0x000, 0x007, 0x002, 0x001, 0x002, 0x005, 0x001, 0x000, 0x004, 0x001, 0x000, + 0x000, 0x001, 0x000, 0x000, 0x00B, 0x00D, 0x002, 0x003, 0x000, 0x000, 0x000, 0x000, 0x005, + 0x005, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x006, 0x002, 0x002, + 0x002, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x00B, 0x001, 0x001, + 0x001, 0x002, 0x005, 0x001, 0x001, 0x003, 0x004, 0x001, 0x002, 0x002, 0x008, 0x000, 0x001, + 0x004, 0x003, 0x003, 0x001, 0x008, 0x001, 0x008, 0x001, 0x000, 0x004, 0x008, 0x000, 0x002, + 0x003, 0x003, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x004, 0x000, 0x000, 0x000, 0x00A, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, 0x003, 0x009, + 0x000, 0x002, 0x001, 0x00A, 0x000, 0x001, 0x000, 0x000, 0x003, 0x000, 0x001, 0x001, 0x000, + 0x009, 0x007, 0x001, 0x002, 0x008, 0x001, 0x005, 0x003, 0x002, 0x001, 0x001, 0x002, 0x002, + 0x001, 0x001, 0x001, 0x005, 0x000, 0x000, 0x001, 0x000, 0x00A, 0x003, 0x000, 0x000, 0x001, + 0x000, 0x00C, 0x000, 0x007, 0x003, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x003, + 0x001, 0x000, 0x001, 0x004, 0x00F, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x008, + 0x000, 0x002, 0x006, 0x001, 0x000, 0x004, 0x002, 0x000, 0x001, 0x004, 0x000, 0x002, 0x002, + 0x002, 0x001, 0x000, 0x000, 0x002, 0x001, 0x000, 0x003, 0x001, 0x000, 0x001, 0x000, 0x001, + 0x001, 0x002, 0x002, 0x002, 0x00A, 0x001, 0x001, 0x001, 0x001, 0x002, 0x002, 0x000, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x002, 0x008, 0x001, 0x002, 0x006, 0x001, 0x000, + 0x002, 0x001, 0x000, 0x000, 0x000, 0x001, 0x002, 0x001, 0x004, 0x004, 0x001, 0x000, 0x005, + 0x001, 0x001, 0x001, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000, 0x002, 0x000, 0x001, 0x000, + 0x000, 0x001, 0x004, 0x000, 0x009, 0x002, 0x00C, 0x008, 0x000, 0x001, 0x000, 0x004, 0x000, + 0x000, 0x001, 0x003, 0x004, 0x002, 0x000, 0x001, 0x003, 0x004, 0x000, 0x001, 0x000, 0x007, + 0x002, 0x001, 0x004, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, 0x009, 0x001, 0x001, + 0x002, 0x000, 0x004, 0x001, 0x001, 0x001, 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, + 0x001, 0x001, 0x003, 0x001, 0x001, 0x001, 0x002, 0x000, 0x003, 0x001, 0x000, 0x002, 0x000, + 0x004, 0x001, 0x000, 0x000, 0x000, 0x001, 0x007, 0x000, 0x000, 0x000, 0x000, 0x004, 0x000, + 0x001, 0x007, 0x000, 0x000, 0x000, 0x001, 0x004, 0x001, 0x000, 0x004, 0x002, 0x002, 0x001, + 0x000, 0x001, 0x001, 0x001, 0x002, 0x001, 0x000, 0x007, 0x000, 0x000, 0x006, 0x000, 0x003, + 0x002, 0x002, 0x001, 0x000, 0x000, 0x002, 0x000, 0x001, 0x003, 0x005, 0x001, 0x001, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x006, 0x001, 0x001, 0x003, 0x009, 0x000, 0x001, 0x001, + 0x000, 0x006, 0x000, 0x003, 0x001, 0x002, 0x000, 0x001, 0x002, 0x005, 0x005, 0x002, 0x000, + 0x001, 0x004, 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, + 0x002, 0x000, 0x000, 0x001, 0x002, 0x001, 0x000, 0x000, 0x002, 0x000, 0x001, 0x006, 0x006, + 0x002, 0x002, 0x000, 0x003, 0x002, 0x003, 0x001, 0x001, 0x002, 0x001, 0x002, 0x00B, 0x000, + 0x001, 0x000, 0x001, 0x002, 0x002, 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, + 0x000, 0x000, 0x003, 0x000, 0x000, 0x001, 0x006, 0x000, 0x002, 0x001, 0x000, 0x003, 0x004, + 0x000, 0x003, 0x000, 0x001, 0x004, 0x001, 0x003, 0x002, 0x000, 0x000, 0x002, 0x001, 0x000, + 0x001, 0x001, 0x001, 0x005, 0x006, 0x004, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x001, + 0x001, 0x004, 0x001, 0x001, 0x009, 0x000, 0x002, 0x000, 0x002, 0x003, 0x005, 0x002, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x003, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x007, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x000, 0x00A, 0x001, 0x000, 0x001, 0x010, 0x002, 0x008, 0x001, 0x001, 0x002, 0x001, 0x002, + 0x001, 0x000, 0x003, 0x002, 0x004, 0x000, 0x002, 0x002, 0x000, 0x001, 0x002, 0x001, 0x001, + 0x001, 0x001, 0x000, 0x000, 0x000, 0x006, 0x002, 0x005, 0x000, 0x000, 0x004, 0x004, 0x001, + 0x005, 0x000, 0x005, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, + 0x005, 0x000, 0x000, 0x000, 0x005, 0x002, 0x001, 0x003, 0x009, 0x001, 0x003, 0x000, 0x000, + 0x002, 0x000, 0x001, 0x001, 0x004, 0x002, 0x000, 0x008, 0x002, 0x001, 0x006, 0x000, 0x002, + 0x002, 0x003, 0x000, 0x003, 0x001, 0x001, 0x002, 0x002, 0x000, 0x003, 0x001, 0x000, 0x000, + 0x000, 0x002, 0x002, 0x000, 0x002, 0x005, 0x001, 0x000, 0x000, 0x000, 0x002, 0x002, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x000, 0x007, 0x001, 0x000, 0x002, 0x002, 0x000, 0x001, 0x000, 0x002, 0x000, + 0x006, 0x002, 0x001, 0x008, 0x000, 0x002, 0x002, 0x001, 0x004, 0x001, 0x000, 0x001, 0x001, + 0x002, 0x009, 0x001, 0x001, 0x001, 0x004, 0x001, 0x005, 0x002, 0x001, 0x001, 0x004, 0x003, + 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x000, 0x001, 0x000, 0x001, 0x001, 0x000, 0x004, + 0x004, +]; +pub(crate) const CANONICAL_DECOMPOSED_KV: &[(u32, (u16, u16))] = &[ + (0x2F93B, (0xC97, 0x1)), + (0x2F869, (0xBC5, 0x1)), + (0x0F93E, (0x91F, 0x1)), + (0x01F2E, (0x60A, 0x3)), + (0x2F90A, (0xC66, 0x1)), + (0x0FACB, (0xA9E, 0x1)), + (0x0FA87, (0xA5A, 0x1)), + (0x2F95B, (0xCB7, 0x1)), + (0x0F965, (0x946, 0x1)), + (0x2F8FB, (0xC57, 0x1)), + (0x2F83A, (0xB96, 0x1)), + (0x0095B, (0x2CA, 0x2)), + (0x01FAF, (0x775, 0x4)), + (0x2F92C, (0xC88, 0x1)), + (0x01E88, (0x482, 0x2)), + (0x009CB, (0x2D4, 0x2)), + (0x01F0A, (0x5B2, 0x3)), + (0x00229, (0x1F2, 0x2)), + (0x0FA8B, (0xA5E, 0x1)), + (0x2F8FD, (0xC59, 0x1)), + (0x2F9AD, (0xD09, 0x1)), + (0x01E7A, (0x464, 0x3)), + (0x0F994, (0x975, 0x1)), + (0x2F9EF, (0xD4B, 0x1)), + (0x2F8CE, (0xC2A, 0x1)), + (0x003AF, (0x233, 0x2)), + (0x00211, (0x1D2, 0x2)), + (0x0F9C8, (0x9A9, 0x1)), + (0x0FA95, (0xA68, 0x1)), + (0x2F9C0, (0xD1C, 0x1)), + (0x01EA9, (0x4BF, 0x3)), + (0x000F5, (0x05A, 0x2)), + (0x2F833, (0xB8F, 0x1)), + (0x0F94A, (0x92B, 0x1)), + (0x0F96C, (0x94D, 0x1)), + (0x0FA3E, (0xA13, 0x1)), + (0x0FA5E, (0xA33, 0x1)), + (0x01E72, (0x452, 0x2)), + (0x0FA1E, (0x9FA, 0x1)), + (0x0015F, (0x106, 0x2)), + (0x01F64, (0x687, 0x3)), + (0x01F07, (0x5AB, 0x3)), + (0x01E87, (0x480, 0x2)), + (0x0FA86, (0xA59, 0x1)), + (0x0F92F, (0x910, 0x1)), + (0x2F8DD, (0xC39, 0x1)), + (0x2FA17, (0xD73, 0x1)), + (0x00F73, (0x324, 0x2)), + (0x01ED0, (0x526, 0x3)), + (0x0F9CA, (0x9AB, 0x1)), + (0x113C8, (0xB11, 0x2)), + (0x2F83F, (0xB9B, 0x1)), + (0x2F999, (0xCF5, 0x1)), + (0x2F9F6, (0xD52, 0x1)), + (0x01FC2, (0x797, 0x3)), + (0x0FABC, (0xA8F, 0x1)), + (0x01FDA, (0x7C7, 0x2)), + (0x2F9B9, (0xD15, 0x1)), + (0x0F9F5, (0x9D6, 0x1)), + (0x01E73, (0x454, 0x2)), + (0x0FA9D, (0xA70, 0x1)), + (0x01E29, (0x3AC, 0x2)), + (0x0FA5F, (0xA34, 0x1)), + (0x2F849, (0xBA5, 0x1)), + (0x00F43, (0x318, 0x2)), + (0x01EA2, (0x4AC, 0x2)), + (0x0F99C, (0x97D, 0x1)), + (0x00129, (0x0B4, 0x2)), + (0x01F85, (0x6D7, 0x4)), + (0x2F8C0, (0xC1C, 0x1)), + (0x01E93, (0x498, 0x2)), + (0x02280, (0x845, 0x2)), + (0x2F821, (0xB7D, 0x1)), + (0x0FA50, (0xA25, 0x1)), + (0x03077, (0x895, 0x2)), + (0x001FD, (0x1AA, 0x2)), + (0x00230, (0x204, 0x3)), + (0x0016D, (0x11E, 0x2)), + (0x0F9A2, (0x983, 0x1)), + (0x01EA8, (0x4BC, 0x3)), + (0x1D161, (0xB40, 0x3)), + (0x0FA94, (0xA67, 0x1)), + (0x01F1A, (0x5D8, 0x3)), + (0x001A1, (0x144, 0x2)), + (0x2F922, (0xC7E, 0x1)), + (0x01FF9, (0x802, 0x2)), + (0x0F93D, (0x91E, 0x1)), + (0x030AC, (0x8A3, 0x2)), + (0x0F9E9, (0x9CA, 0x1)), + (0x01E89, (0x484, 0x2)), + (0x01F35, (0x61D, 0x3)), + (0x0FA2F, (0xA04, 0x1)), + (0x0F90A, (0x8EB, 0x1)), + (0x0F9FC, (0x9DD, 0x1)), + (0x2F891, (0xBED, 0x1)), + (0x0307D, (0x89D, 0x2)), + (0x01FA5, (0x74F, 0x4)), + (0x00173, (0x12A, 0x2)), + (0x0FB49, (0xAE7, 0x2)), + (0x0FACA, (0xA9D, 0x1)), + (0x0F97B, (0x95C, 0x1)), + (0x2F9FD, (0xD59, 0x1)), + (0x2F90B, (0xC67, 0x1)), + (0x0F9A3, (0x984, 0x1)), + (0x01E2A, (0x3AE, 0x2)), + (0x01FBB, (0x790, 0x2)), + (0x2F9A0, (0xCFC, 0x1)), + (0x0F924, (0x905, 0x1)), + (0x01E7B, (0x467, 0x3)), + (0x2F8CB, (0xC27, 0x1)), + (0x2F8F6, (0xC52, 0x1)), + (0x004F1, (0x2A0, 0x2)), + (0x01FD0, (0x7B4, 0x2)), + (0x01EF5, (0x58E, 0x2)), + (0x00146, (0x0DE, 0x2)), + (0x01E2E, (0x3B6, 0x3)), + (0x0F95E, (0x93F, 0x1)), + (0x0F916, (0x8F7, 0x1)), + (0x0FA44, (0xA19, 0x1)), + (0x0FA16, (0x9F2, 0x1)), + (0x01F1C, (0x5DE, 0x3)), + (0x105E4, (0xAF5, 0x2)), + (0x2F94D, (0xCA9, 0x1)), + (0x0FAB9, (0xA8C, 0x1)), + (0x0F907, (0x8E8, 0x1)), + (0x0305E, (0x87F, 0x2)), + (0x01E0D, (0x36E, 0x2)), + (0x01F4A, (0x650, 0x3)), + (0x0F9F9, (0x9DA, 0x1)), + (0x2F9C7, (0xD23, 0x1)), + (0x0F94B, (0x92C, 0x1)), + (0x2F87E, (0xBDA, 0x1)), + (0x00D4C, (0x30D, 0x2)), + (0x0F9EC, (0x9CD, 0x1)), + (0x001AF, (0x146, 0x2)), + (0x2F91D, (0xC79, 0x1)), + (0x01EE8, (0x56A, 0x3)), + (0x022AD, (0x853, 0x2)), + (0x2F834, (0xB90, 0x1)), + (0x01EC8, (0x516, 0x2)), + (0x01F52, (0x660, 0x3)), + (0x2F84F, (0xBAB, 0x1)), + (0x01E27, (0x3A8, 0x2)), + (0x01F48, (0x64C, 0x2)), + (0x01FEB, (0x7EA, 0x2)), + (0x0F9C4, (0x9A5, 0x1)), + (0x01EE5, (0x564, 0x2)), + (0x01EBB, (0x4F2, 0x2)), + (0x0F9B5, (0x996, 0x1)), + (0x01F8D, (0x6F5, 0x4)), + (0x01EAF, (0x4D1, 0x3)), + (0x0FA78, (0xA4B, 0x1)), + (0x2F975, (0xCD1, 0x1)), + (0x2F9BA, (0xD16, 0x1)), + (0x01E22, (0x39E, 0x2)), + (0x01EEA, (0x570, 0x3)), + (0x0FB2A, (0xAB1, 0x2)), + (0x2F951, (0xCAD, 0x1)), + (0x00A33, (0x2DE, 0x2)), + (0x2F8DC, (0xC38, 0x1)), + (0x000E7, (0x040, 0x2)), + (0x2F8F7, (0xC53, 0x1)), + (0x2F9EB, (0xD47, 0x1)), + (0x00174, (0x12C, 0x2)), + (0x0011D, (0x0A0, 0x2)), + (0x0F966, (0x947, 0x1)), + (0x0FB36, (0xACB, 0x2)), + (0x2F88A, (0xBE6, 0x1)), + (0x00450, (0x258, 0x2)), + (0x0305C, (0x87D, 0x2)), + (0x0F9F6, (0x9D7, 0x1)), + (0x0F9A7, (0x988, 0x1)), + (0x0FA82, (0xA55, 0x1)), + (0x0FAD7, (0xAAA, 0x1)), + (0x01B41, (0x34E, 0x2)), + (0x01E5D, (0x421, 0x3)), + (0x01F12, (0x5C8, 0x3)), + (0x00108, (0x07A, 0x2)), + (0x01EAC, (0x4C8, 0x3)), + (0x2F9F0, (0xD4C, 0x1)), + (0x00100, (0x06A, 0x2)), + (0x0FAA2, (0xA75, 0x1)), + (0x003D3, (0x242, 0x2)), + (0x0F973, (0x954, 0x1)), + (0x00407, (0x24C, 0x2)), + (0x03070, (0x88B, 0x2)), + (0x01E79, (0x461, 0x3)), + (0x0F964, (0x945, 0x1)), + (0x00F52, (0x31C, 0x2)), + (0x0F9EF, (0x9D0, 0x1)), + (0x01E58, (0x416, 0x2)), + (0x2F949, (0xCA5, 0x1)), + (0x00171, (0x126, 0x2)), + (0x01F2A, (0x5FE, 0x3)), + (0x00388, (0x21A, 0x2)), + (0x00157, (0x0F6, 0x2)), + (0x01F3D, (0x633, 0x3)), + (0x0F98B, (0x96C, 0x1)), + (0x030BE, (0x8B5, 0x2)), + (0x2F816, (0xB72, 0x1)), + (0x01E95, (0x49C, 0x2)), + (0x0F991, (0x972, 0x1)), + (0x2F8B5, (0xC11, 0x1)), + (0x2F810, (0xB6C, 0x1)), + (0x0FAB8, (0xA8B, 0x1)), + (0x001EC, (0x18E, 0x3)), + (0x01E09, (0x365, 0x3)), + (0x2F8BB, (0xC17, 0x1)), + (0x2F9E1, (0xD3D, 0x1)), + (0x2F94E, (0xCAA, 0x1)), + (0x01FAE, (0x771, 0x4)), + (0x01FFD, (0x80A, 0x1)), + (0x0FA00, (0x9E1, 0x1)), + (0x00BCC, (0x2FA, 0x2)), + (0x0FA4B, (0xA20, 0x1)), + (0x0FAC3, (0xA96, 0x1)), + (0x021CE, (0x819, 0x2)), + (0x02271, (0x83B, 0x2)), + (0x000CB, (0x014, 0x2)), + (0x01F51, (0x65E, 0x2)), + (0x0FA99, (0xA6C, 0x1)), + (0x030B8, (0x8AF, 0x2)), + (0x01E7E, (0x46E, 0x2)), + (0x0FA75, (0xA48, 0x1)), + (0x16128, (0xB2F, 0x3)), + (0x0F978, (0x959, 0x1)), + (0x001E6, (0x182, 0x2)), + (0x01E8E, (0x48E, 0x2)), + (0x2F9E6, (0xD42, 0x1)), + (0x2F8E3, (0xC3F, 0x1)), + (0x0045D, (0x262, 0x2)), + (0x001DE, (0x172, 0x3)), + (0x01F63, (0x684, 0x3)), + (0x01E48, (0x3EE, 0x2)), + (0x2F8D0, (0xC2C, 0x1)), + (0x0FA22, (0x9FC, 0x1)), + (0x0FACF, (0xAA2, 0x1)), + (0x01EA3, (0x4AE, 0x2)), + (0x022E3, (0x85F, 0x2)), + (0x0FAD4, (0xAA7, 0x1)), + (0x0304C, (0x86D, 0x2)), + (0x0FA8D, (0xA60, 0x1)), + (0x004D6, (0x276, 0x2)), + (0x01F00, (0x598, 0x2)), + (0x0FA36, (0xA0B, 0x1)), + (0x0FA72, (0xA45, 0x1)), + (0x2F9A3, (0xCFF, 0x1)), + (0x01F1B, (0x5DB, 0x3)), + (0x01F5D, (0x677, 0x3)), + (0x2F9AB, (0xD07, 0x1)), + (0x0FA15, (0x9F1, 0x1)), + (0x0F9BE, (0x99F, 0x1)), + (0x1D1BF, (0xB56, 0x3)), + (0x0010D, (0x084, 0x2)), + (0x01FB4, (0x782, 0x3)), + (0x0F942, (0x923, 0x1)), + (0x00934, (0x2C2, 0x2)), + (0x0FAAE, (0xA81, 0x1)), + (0x2F98A, (0xCE6, 0x1)), + (0x01F3C, (0x630, 0x3)), + (0x2F9D1, (0xD2D, 0x1)), + (0x01FD9, (0x7C5, 0x2)), + (0x01F38, (0x626, 0x2)), + (0x030BC, (0x8B3, 0x2)), + (0x000FC, (0x064, 0x2)), + (0x01F05, (0x5A5, 0x3)), + (0x01EE4, (0x562, 0x2)), + (0x0F90C, (0x8ED, 0x1)), + (0x01EB3, (0x4DD, 0x3)), + (0x2F8E0, (0xC3C, 0x1)), + (0x0016B, (0x11A, 0x2)), + (0x01E12, (0x378, 0x2)), + (0x0F99F, (0x980, 0x1)), + (0x01FB3, (0x780, 0x2)), + (0x1D160, (0xB3D, 0x3)), + (0x000CF, (0x01C, 0x2)), + (0x000CD, (0x018, 0x2)), + (0x2F835, (0xB91, 0x1)), + (0x0F902, (0x8E3, 0x1)), + (0x00B4C, (0x2EE, 0x2)), + (0x2F99C, (0xCF8, 0x1)), + (0x0FA41, (0xA16, 0x1)), + (0x0F9C5, (0x9A6, 0x1)), + (0x0F9C7, (0x9A8, 0x1)), + (0x030FE, (0x8DF, 0x2)), + (0x01EE0, (0x556, 0x3)), + (0x2F882, (0xBDE, 0x1)), + (0x2F973, (0xCCF, 0x1)), + (0x0FA0D, (0x9EE, 0x1)), + (0x0FA5C, (0xA31, 0x1)), + (0x2F900, (0xC5C, 0x1)), + (0x0F9FD, (0x9DE, 0x1)), + (0x01F62, (0x681, 0x3)), + (0x2F8B9, (0xC15, 0x1)), + (0x001F5, (0x19C, 0x2)), + (0x01EF3, (0x58A, 0x2)), + (0x2F84C, (0xBA8, 0x1)), + (0x001D5, (0x15A, 0x3)), + (0x0F9BC, (0x99D, 0x1)), + (0x01FE5, (0x7DD, 0x2)), + (0x01F5B, (0x674, 0x3)), + (0x03071, (0x88D, 0x2)), + (0x2F9BB, (0xD17, 0x1)), + (0x01FAA, (0x761, 0x4)), + (0x01F94, (0x70F, 0x4)), + (0x01E4E, (0x3FC, 0x3)), + (0x001EE, (0x194, 0x2)), + (0x0F9ED, (0x9CE, 0x1)), + (0x2F9B4, (0xD10, 0x1)), + (0x2FA0F, (0xD6B, 0x1)), + (0x00DDE, (0x316, 0x2)), + (0x0F915, (0x8F6, 0x1)), + (0x01F87, (0x6DF, 0x4)), + (0x0F9B2, (0x993, 0x1)), + (0x01B06, (0x33C, 0x2)), + (0x2F84B, (0xBA7, 0x1)), + (0x2F93D, (0xC99, 0x1)), + (0x00113, (0x08C, 0x2)), + (0x01F69, (0x695, 0x2)), + (0x2F8C6, (0xC22, 0x1)), + (0x000FF, (0x068, 0x2)), + (0x01E77, (0x45C, 0x2)), + (0x2FA12, (0xD6E, 0x1)), + (0x00341, (0x20F, 0x1)), + (0x2F827, (0xB83, 0x1)), + (0x01B43, (0x350, 0x2)), + (0x2F8BA, (0xC16, 0x1)), + (0x0F987, (0x968, 0x1)), + (0x01B12, (0x346, 0x2)), + (0x022EA, (0x861, 0x2)), + (0x2F97D, (0xCD9, 0x1)), + (0x16D68, (0xB32, 0x2)), + (0x0FB4C, (0xAED, 0x2)), + (0x01E4A, (0x3F2, 0x2)), + (0x01E1E, (0x396, 0x2)), + (0x00B48, (0x2EA, 0x2)), + (0x009DC, (0x2D8, 0x2)), + (0x000DD, (0x032, 0x2)), + (0x2F971, (0xCCD, 0x1)), + (0x0FA9F, (0xA72, 0x1)), + (0x0045E, (0x264, 0x2)), + (0x01FA3, (0x747, 0x4)), + (0x004DF, (0x284, 0x2)), + (0x004DC, (0x27E, 0x2)), + (0x00150, (0x0EC, 0x2)), + (0x000DA, (0x02C, 0x2)), + (0x001E7, (0x184, 0x2)), + (0x2F92E, (0xC8A, 0x1)), + (0x0F918, (0x8F9, 0x1)), + (0x01FCE, (0x7B0, 0x2)), + (0x0232A, (0x86A, 0x1)), + (0x02281, (0x847, 0x2)), + (0x01E0F, (0x372, 0x2)), + (0x000E3, (0x03A, 0x2)), + (0x0FB48, (0xAE5, 0x2)), + (0x2FA0B, (0xD67, 0x1)), + (0x0FB1D, (0xAAD, 0x2)), + (0x01E90, (0x492, 0x2)), + (0x003AA, (0x229, 0x2)), + (0x0F981, (0x962, 0x1)), + (0x01E30, (0x3BC, 0x2)), + (0x01EBD, (0x4F6, 0x2)), + (0x01E0B, (0x36A, 0x2)), + (0x01E62, (0x42C, 0x2)), + (0x2F85D, (0xBB9, 0x1)), + (0x00401, (0x248, 0x2)), + (0x2F87F, (0xBDB, 0x1)), + (0x01F22, (0x5E8, 0x3)), + (0x2F9A4, (0xD00, 0x1)), + (0x2F855, (0xBB1, 0x1)), + (0x2F98F, (0xCEB, 0x1)), + (0x0F9D0, (0x9B1, 0x1)), + (0x021CD, (0x817, 0x2)), + (0x2F87A, (0xBD6, 0x1)), + (0x01FB9, (0x78C, 0x2)), + (0x2F8C8, (0xC24, 0x1)), + (0x0FA65, (0xA3A, 0x1)), + (0x01EA4, (0x4B0, 0x3)), + (0x0014C, (0x0E4, 0x2)), + (0x004F0, (0x29E, 0x2)), + (0x01FB0, (0x779, 0x2)), + (0x01FAD, (0x76D, 0x4)), + (0x2F94F, (0xCAB, 0x1)), + (0x01F75, (0x6B3, 0x2)), + (0x0F905, (0x8E6, 0x1)), + (0x0FA71, (0xA44, 0x1)), + (0x000CE, (0x01A, 0x2)), + (0x2F89E, (0xBFA, 0x1)), + (0x2F903, (0xC5F, 0x1)), + (0x0F939, (0x91A, 0x1)), + (0x00B94, (0x2F4, 0x2)), + (0x2F926, (0xC82, 0x1)), + (0x0FA20, (0x9FB, 0x1)), + (0x01EAB, (0x4C5, 0x3)), + (0x004EF, (0x29C, 0x2)), + (0x01F4D, (0x659, 0x3)), + (0x1134B, (0xB01, 0x2)), + (0x01F28, (0x5FA, 0x2)), + (0x2F955, (0xCB1, 0x1)), + (0x01FBC, (0x792, 0x2)), + (0x01E42, (0x3E2, 0x2)), + (0x0F935, (0x916, 0x1)), + (0x114BB, (0xB13, 0x2)), + (0x2F9E0, (0xD3C, 0x1)), + (0x0015E, (0x104, 0x2)), + (0x0017B, (0x13A, 0x2)), + (0x01E3B, (0x3D4, 0x2)), + (0x01E6A, (0x442, 0x2)), + (0x00214, (0x1D8, 0x2)), + (0x01B0A, (0x340, 0x2)), + (0x2F825, (0xB81, 0x1)), + (0x01E78, (0x45E, 0x3)), + (0x001E8, (0x186, 0x2)), + (0x022ED, (0x867, 0x2)), + (0x00387, (0x219, 0x1)), + (0x2F9CE, (0xD2A, 0x1)), + (0x2F984, (0xCE0, 0x1)), + (0x022EB, (0x863, 0x2)), + (0x01FCB, (0x7AA, 0x2)), + (0x0FAC5, (0xA98, 0x1)), + (0x2F806, (0xB62, 0x1)), + (0x0F960, (0x941, 0x1)), + (0x0F9B3, (0x994, 0x1)), + (0x0FA02, (0x9E3, 0x1)), + (0x01EB9, (0x4EE, 0x2)), + (0x01F3E, (0x636, 0x3)), + (0x01EB1, (0x4D7, 0x3)), + (0x2FA15, (0xD71, 0x1)), + (0x0FB31, (0xAC1, 0x2)), + (0x01F0D, (0x5BB, 0x3)), + (0x0F9AB, (0x98C, 0x1)), + (0x0FB39, (0xACF, 0x2)), + (0x0305A, (0x87B, 0x2)), + (0x0F9B0, (0x991, 0x1)), + (0x0F91A, (0x8FB, 0x1)), + (0x2F9F8, (0xD54, 0x1)), + (0x2F977, (0xCD3, 0x1)), + (0x001CF, (0x14E, 0x2)), + (0x01E20, (0x39A, 0x2)), + (0x0F9A4, (0x985, 0x1)), + (0x00176, (0x130, 0x2)), + (0x2FA1D, (0xD79, 0x1)), + (0x004F4, (0x2A6, 0x2)), + (0x2FA10, (0xD6C, 0x1)), + (0x0F96E, (0x94F, 0x1)), + (0x0F9BF, (0x9A0, 0x1)), + (0x01F9E, (0x735, 0x4)), + (0x2F84D, (0xBA9, 0x1)), + (0x2FA0E, (0xD6A, 0x1)), + (0x0FA07, (0x9E8, 0x1)), + (0x004E7, (0x290, 0x2)), + (0x01FE3, (0x7D8, 0x3)), + (0x003CC, (0x23C, 0x2)), + (0x01FA6, (0x753, 0x4)), + (0x0020F, (0x1CE, 0x2)), + (0x0FA5D, (0xA32, 0x1)), + (0x00107, (0x078, 0x2)), + (0x0FA4F, (0xA24, 0x1)), + (0x0FA64, (0xA39, 0x1)), + (0x1D1BC, (0xB4E, 0x2)), + (0x0F99A, (0x97B, 0x1)), + (0x2F9D5, (0xD31, 0x1)), + (0x01EA7, (0x4B9, 0x3)), + (0x2F8F9, (0xC55, 0x1)), + (0x0F9F0, (0x9D1, 0x1)), + (0x00476, (0x266, 0x2)), + (0x000EA, (0x046, 0x2)), + (0x2F86F, (0xBCB, 0x1)), + (0x2F992, (0xCEE, 0x1)), + (0x01E0E, (0x370, 0x2)), + (0x0F95D, (0x93E, 0x1)), + (0x0FA89, (0xA5C, 0x1)), + (0x0022F, (0x202, 0x2)), + (0x00CCB, (0x306, 0x3)), + (0x2F841, (0xB9D, 0x1)), + (0x004E6, (0x28E, 0x2)), + (0x01E5F, (0x426, 0x2)), + (0x004C2, (0x26C, 0x2)), + (0x004EC, (0x296, 0x2)), + (0x01B0E, (0x344, 0x2)), + (0x00390, (0x226, 0x3)), + (0x00105, (0x074, 0x2)), + (0x00419, (0x254, 0x2)), + (0x0F959, (0x93A, 0x1)), + (0x030F8, (0x8D9, 0x2)), + (0x01F25, (0x5F1, 0x3)), + (0x01EC0, (0x4FE, 0x3)), + (0x00124, (0x0AE, 0x2)), + (0x00101, (0x06C, 0x2)), + (0x000C7, (0x00C, 0x2)), + (0x2F9FC, (0xD58, 0x1)), + (0x0F92E, (0x90F, 0x1)), + (0x2F910, (0xC6C, 0x1)), + (0x02284, (0x849, 0x2)), + (0x01EE3, (0x55F, 0x3)), + (0x01E34, (0x3C4, 0x2)), + (0x003AD, (0x22F, 0x2)), + (0x0FA2C, (0xA01, 0x1)), + (0x2F877, (0xBD3, 0x1)), + (0x0F99B, (0x97C, 0x1)), + (0x000E8, (0x042, 0x2)), + (0x01E28, (0x3AA, 0x2)), + (0x01EA1, (0x4AA, 0x2)), + (0x2F94A, (0xCA6, 0x1)), + (0x1D15E, (0xB39, 0x2)), + (0x2F83B, (0xB97, 0x1)), + (0x1D164, (0xB49, 0x3)), + (0x2F854, (0xBB0, 0x1)), + (0x2F892, (0xBEE, 0x1)), + (0x1D1BB, (0xB4C, 0x2)), + (0x0010F, (0x088, 0x2)), + (0x01E63, (0x42E, 0x2)), + (0x01FD3, (0x7BB, 0x3)), + (0x01FB6, (0x785, 0x2)), + (0x0F944, (0x925, 0x1)), + (0x2F92B, (0xC87, 0x1)), + (0x001FF, (0x1AE, 0x2)), + (0x00386, (0x217, 0x2)), + (0x2F95F, (0xCBB, 0x1)), + (0x0FA32, (0xA07, 0x1)), + (0x0FA17, (0x9F3, 0x1)), + (0x01E17, (0x385, 0x3)), + (0x01F31, (0x612, 0x2)), + (0x2F980, (0xCDC, 0x1)), + (0x0FA2D, (0xA02, 0x1)), + (0x2F88E, (0xBEA, 0x1)), + (0x01FAC, (0x769, 0x4)), + (0x0FA3C, (0xA11, 0x1)), + (0x01F09, (0x5B0, 0x2)), + (0x01FDB, (0x7C9, 0x2)), + (0x2F9CA, (0xD26, 0x1)), + (0x01F2F, (0x60D, 0x3)), + (0x00623, (0x2B0, 0x2)), + (0x2F9F9, (0xD55, 0x1)), + (0x0FAB4, (0xA87, 0x1)), + (0x01EBF, (0x4FB, 0x3)), + (0x0F985, (0x966, 0x1)), + (0x01F6E, (0x6A3, 0x3)), + (0x2F965, (0xCC1, 0x1)), + (0x2F829, (0xB85, 0x1)), + (0x01E24, (0x3A2, 0x2)), + (0x2F8A2, (0xBFE, 0x1)), + (0x2F8CC, (0xC28, 0x1)), + (0x02ADC, (0x86B, 0x2)), + (0x004F3, (0x2A4, 0x2)), + (0x01F9D, (0x731, 0x4)), + (0x01F24, (0x5EE, 0x3)), + (0x2F9AF, (0xD0B, 0x1)), + (0x0FA77, (0xA4A, 0x1)), + (0x0FA93, (0xA66, 0x1)), + (0x01E61, (0x42A, 0x2)), + (0x00121, (0x0A8, 0x2)), + (0x01FCC, (0x7AC, 0x2)), + (0x2F9B6, (0xD12, 0x1)), + (0x2F963, (0xCBF, 0x1)), + (0x01EDB, (0x547, 0x3)), + (0x01FAB, (0x765, 0x4)), + (0x01E5A, (0x41A, 0x2)), + (0x2F80E, (0xB6A, 0x1)), + (0x0FA0A, (0x9EB, 0x1)), + (0x2F994, (0xCF0, 0x1)), + (0x2F91B, (0xC77, 0x1)), + (0x01EEE, (0x57C, 0x3)), + (0x01F67, (0x690, 0x3)), + (0x0F9B9, (0x99A, 0x1)), + (0x0FA63, (0xA38, 0x1)), + (0x2F972, (0xCCE, 0x1)), + (0x03079, (0x897, 0x2)), + (0x0F9EA, (0x9CB, 0x1)), + (0x0FB38, (0xACD, 0x2)), + (0x0FA9E, (0xA71, 0x1)), + (0x01E02, (0x356, 0x2)), + (0x01ECE, (0x522, 0x2)), + (0x01E75, (0x458, 0x2)), + (0x0FA46, (0xA1B, 0x1)), + (0x0FB43, (0xADD, 0x2)), + (0x2F80A, (0xB66, 0x1)), + (0x00115, (0x090, 0x2)), + (0x2F959, (0xCB5, 0x1)), + (0x030D1, (0x8C3, 0x2)), + (0x2F9B2, (0xD0E, 0x1)), + (0x2F98D, (0xCE9, 0x1)), + (0x0FA7E, (0xA51, 0x1)), + (0x00177, (0x132, 0x2)), + (0x2F867, (0xBC3, 0x1)), + (0x0FAA8, (0xA7B, 0x1)), + (0x0F97D, (0x95E, 0x1)), + (0x0F9B8, (0x999, 0x1)), + (0x0F968, (0x949, 0x1)), + (0x00D4B, (0x30B, 0x2)), + (0x0FA5A, (0xA2F, 0x1)), + (0x00104, (0x072, 0x2)), + (0x01F4C, (0x656, 0x3)), + (0x01F8E, (0x6F9, 0x4)), + (0x105C9, (0xAF3, 0x2)), + (0x01F2D, (0x607, 0x3)), + (0x0FA2B, (0xA00, 0x1)), + (0x2F8C5, (0xC21, 0x1)), + (0x01F73, (0x6AF, 0x2)), + (0x0FA73, (0xA46, 0x1)), + (0x0014E, (0x0E8, 0x2)), + (0x0F998, (0x979, 0x1)), + (0x0F94D, (0x92E, 0x1)), + (0x2F966, (0xCC2, 0x1)), + (0x2F91E, (0xC7A, 0x1)), + (0x00439, (0x256, 0x2)), + (0x01E98, (0x4A2, 0x2)), + (0x0FA8A, (0xA5D, 0x1)), + (0x000E9, (0x044, 0x2)), + (0x01FE9, (0x7E6, 0x2)), + (0x00170, (0x124, 0x2)), + (0x1109A, (0xAF7, 0x2)), + (0x11383, (0xB05, 0x2)), + (0x02270, (0x839, 0x2)), + (0x2F982, (0xCDE, 0x1)), + (0x0F9AF, (0x990, 0x1)), + (0x0FAB3, (0xA86, 0x1)), + (0x0F9E2, (0x9C3, 0x1)), + (0x2F9CB, (0xD27, 0x1)), + (0x0F947, (0x928, 0x1)), + (0x00F78, (0x32A, 0x2)), + (0x0021F, (0x1EA, 0x2)), + (0x2F928, (0xC84, 0x1)), + (0x004D2, (0x272, 0x2)), + (0x2F845, (0xBA1, 0x1)), + (0x01F23, (0x5EB, 0x3)), + (0x02285, (0x84B, 0x2)), + (0x0F903, (0x8E4, 0x1)), + (0x2F84A, (0xBA6, 0x1)), + (0x01F3F, (0x639, 0x3)), + (0x01E07, (0x360, 0x2)), + (0x2F823, (0xB7F, 0x1)), + (0x2F8D1, (0xC2D, 0x1)), + (0x01E11, (0x376, 0x2)), + (0x01FD2, (0x7B8, 0x3)), + (0x0017C, (0x13C, 0x2)), + (0x000E4, (0x03C, 0x2)), + (0x0F962, (0x943, 0x1)), + (0x001F4, (0x19A, 0x2)), + (0x0017A, (0x138, 0x2)), + (0x0F948, (0x929, 0x1)), + (0x001FE, (0x1AC, 0x2)), + (0x2F90F, (0xC6B, 0x1)), + (0x2F838, (0xB94, 0x1)), + (0x2F800, (0xB5C, 0x1)), + (0x0212B, (0x80F, 0x2)), + (0x2F83E, (0xB9A, 0x1)), + (0x0FA90, (0xA63, 0x1)), + (0x0095D, (0x2CE, 0x2)), + (0x2F96C, (0xCC8, 0x1)), + (0x0FA4D, (0xA22, 0x1)), + (0x0F906, (0x8E7, 0x1)), + (0x01F37, (0x623, 0x3)), + (0x0F9AC, (0x98D, 0x1)), + (0x01FE1, (0x7D3, 0x2)), + (0x01EC5, (0x50D, 0x3)), + (0x01ECB, (0x51C, 0x2)), + (0x2F947, (0xCA3, 0x1)), + (0x01F6D, (0x6A0, 0x3)), + (0x01E4C, (0x3F6, 0x3)), + (0x01FE6, (0x7DF, 0x2)), + (0x2F93C, (0xC98, 0x1)), + (0x2F9C4, (0xD20, 0x1)), + (0x001ED, (0x191, 0x3)), + (0x030F9, (0x8DB, 0x2)), + (0x2F898, (0xBF4, 0x1)), + (0x0FA0C, (0x9ED, 0x1)), + (0x000E0, (0x034, 0x2)), + (0x2F986, (0xCE2, 0x1)), + (0x01F61, (0x67F, 0x2)), + (0x01F7C, (0x6C1, 0x2)), + (0x01FA1, (0x740, 0x3)), + (0x0307C, (0x89B, 0x2)), + (0x01FEE, (0x7F0, 0x2)), + (0x2F8E6, (0xC42, 0x1)), + (0x00451, (0x25A, 0x2)), + (0x01E16, (0x382, 0x3)), + (0x00179, (0x136, 0x2)), + (0x00114, (0x08E, 0x2)), + (0x01F32, (0x614, 0x3)), + (0x0FB3E, (0xAD7, 0x2)), + (0x0F949, (0x92A, 0x1)), + (0x2F937, (0xC93, 0x1)), + (0x0F932, (0x913, 0x1)), + (0x0219B, (0x813, 0x2)), + (0x01E4F, (0x3FF, 0x3)), + (0x01E51, (0x405, 0x3)), + (0x01E8F, (0x490, 0x2)), + (0x030D4, (0x8C7, 0x2)), + (0x2FA0D, (0xD69, 0x1)), + (0x01EE1, (0x559, 0x3)), + (0x01026, (0x33A, 0x2)), + (0x0F9C2, (0x9A3, 0x1)), + (0x0012D, (0x0BC, 0x2)), + (0x2F864, (0xBC0, 0x1)), + (0x2F88D, (0xBE9, 0x1)), + (0x2F9CC, (0xD28, 0x1)), + (0x16124, (0xB25, 0x2)), + (0x0FA98, (0xA6B, 0x1)), + (0x2F901, (0xC5D, 0x1)), + (0x2F9D3, (0xD2F, 0x1)), + (0x01E96, (0x49E, 0x2)), + (0x0FA60, (0xA35, 0x1)), + (0x0FA62, (0xA37, 0x1)), + (0x000FD, (0x066, 0x2)), + (0x2FA00, (0xD5C, 0x1)), + (0x01F06, (0x5A8, 0x3)), + (0x00128, (0x0B2, 0x2)), + (0x01F0B, (0x5B5, 0x3)), + (0x2F99A, (0xCF6, 0x1)), + (0x2F970, (0xCCC, 0x1)), + (0x2FA13, (0xD6F, 0x1)), + (0x01F0F, (0x5C1, 0x3)), + (0x000F1, (0x052, 0x2)), + (0x2F8D3, (0xC2F, 0x1)), + (0x0F919, (0x8FA, 0x1)), + (0x02329, (0x869, 0x1)), + (0x0FB32, (0xAC3, 0x2)), + (0x0FA48, (0xA1D, 0x1)), + (0x0F953, (0x934, 0x1)), + (0x2F873, (0xBCF, 0x1)), + (0x0012E, (0x0BE, 0x2)), + (0x0F963, (0x944, 0x1)), + (0x01F53, (0x663, 0x3)), + (0x0F94E, (0x92F, 0x1)), + (0x0095A, (0x2C8, 0x2)), + (0x2F929, (0xC85, 0x1)), + (0x0012C, (0x0BA, 0x2)), + (0x00119, (0x098, 0x2)), + (0x2F997, (0xCF3, 0x1)), + (0x0FACD, (0xAA0, 0x1)), + (0x01E1B, (0x38E, 0x2)), + (0x01ED6, (0x538, 0x3)), + (0x0F945, (0x926, 0x1)), + (0x01FA8, (0x75B, 0x3)), + (0x0FA3A, (0xA0F, 0x1)), + (0x2F94C, (0xCA8, 0x1)), + (0x0F9C6, (0x9A7, 0x1)), + (0x0FB4E, (0xAF1, 0x2)), + (0x01F20, (0x5E4, 0x2)), + (0x0FAD3, (0xAA6, 0x1)), + (0x02278, (0x841, 0x2)), + (0x01E86, (0x47E, 0x2)), + (0x0F92D, (0x90E, 0x1)), + (0x0FA5B, (0xA30, 0x1)), + (0x0FA49, (0xA1E, 0x1)), + (0x0FAC7, (0xA9A, 0x1)), + (0x0F91D, (0x8FE, 0x1)), + (0x2F852, (0xBAE, 0x1)), + (0x01E3C, (0x3D6, 0x2)), + (0x01E25, (0x3A4, 0x2)), + (0x0F938, (0x919, 0x1)), + (0x2F919, (0xC75, 0x1)), + (0x00205, (0x1BA, 0x2)), + (0x2F843, (0xB9F, 0x1)), + (0x0FB33, (0xAC5, 0x2)), + (0x01FB8, (0x78A, 0x2)), + (0x0F9D7, (0x9B8, 0x1)), + (0x0FB4A, (0xAE9, 0x2)), + (0x00147, (0x0E0, 0x2)), + (0x0FAAA, (0xA7D, 0x1)), + (0x2F858, (0xBB4, 0x1)), + (0x01E8A, (0x486, 0x2)), + (0x001E1, (0x17B, 0x3)), + (0x2F950, (0xCAC, 0x1)), + (0x2FA19, (0xD75, 0x1)), + (0x0FA6C, (0xA41, 0x1)), + (0x01F93, (0x70B, 0x4)), + (0x0FA74, (0xA47, 0x1)), + (0x00109, (0x07C, 0x2)), + (0x01F59, (0x672, 0x2)), + (0x0F9D5, (0x9B6, 0x1)), + (0x0FA70, (0xA43, 0x1)), + (0x0FAA9, (0xA7C, 0x1)), + (0x2F9F4, (0xD50, 0x1)), + (0x2F948, (0xCA4, 0x1)), + (0x0F9DB, (0x9BC, 0x1)), + (0x01E2B, (0x3B0, 0x2)), + (0x2F9F3, (0xD4F, 0x1)), + (0x0016F, (0x122, 0x2)), + (0x01F97, (0x71B, 0x4)), + (0x01FA2, (0x743, 0x4)), + (0x2F956, (0xCB2, 0x1)), + (0x00F81, (0x32C, 0x2)), + (0x01EDF, (0x553, 0x3)), + (0x01E41, (0x3E0, 0x2)), + (0x1D15F, (0xB3B, 0x2)), + (0x01E66, (0x436, 0x3)), + (0x2F8E7, (0xC43, 0x1)), + (0x0FABD, (0xA90, 0x1)), + (0x0F92A, (0x90B, 0x1)), + (0x0FABA, (0xA8D, 0x1)), + (0x01ED5, (0x535, 0x3)), + (0x01F29, (0x5FC, 0x2)), + (0x01EB0, (0x4D4, 0x3)), + (0x01FF6, (0x7FB, 0x2)), + (0x0FA69, (0xA3E, 0x1)), + (0x00231, (0x207, 0x3)), + (0x0011A, (0x09A, 0x2)), + (0x2F916, (0xC72, 0x1)), + (0x000D2, (0x020, 0x2)), + (0x01E26, (0x3A6, 0x2)), + (0x2F9E8, (0xD44, 0x1)), + (0x00233, (0x20C, 0x2)), + (0x0F936, (0x917, 0x1)), + (0x01FEC, (0x7EC, 0x2)), + (0x00202, (0x1B4, 0x2)), + (0x0F9AD, (0x98E, 0x1)), + (0x2F927, (0xC83, 0x1)), + (0x2F856, (0xBB2, 0x1)), + (0x00931, (0x2C0, 0x2)), + (0x01E70, (0x44E, 0x2)), + (0x00135, (0x0C6, 0x2)), + (0x01E33, (0x3C2, 0x2)), + (0x01F82, (0x6CB, 0x4)), + (0x01F27, (0x5F7, 0x3)), + (0x2F809, (0xB65, 0x1)), + (0x0F920, (0x901, 0x1)), + (0x2F936, (0xC92, 0x1)), + (0x00340, (0x20E, 0x1)), + (0x003AB, (0x22B, 0x2)), + (0x2F86C, (0xBC8, 0x1)), + (0x01ED3, (0x52F, 0x3)), + (0x00103, (0x070, 0x2)), + (0x0F9A8, (0x989, 0x1)), + (0x0011C, (0x09E, 0x2)), + (0x0F92C, (0x90D, 0x1)), + (0x000C9, (0x010, 0x2)), + (0x0F9B4, (0x995, 0x1)), + (0x2F939, (0xC95, 0x1)), + (0x0F913, (0x8F4, 0x1)), + (0x0FA52, (0xA27, 0x1)), + (0x00210, (0x1D0, 0x2)), + (0x000F3, (0x056, 0x2)), + (0x2F804, (0xB60, 0x1)), + (0x2F87D, (0xBD9, 0x1)), + (0x0FAC9, (0xA9C, 0x1)), + (0x01E1C, (0x390, 0x3)), + (0x0011E, (0x0A2, 0x2)), + (0x0016C, (0x11C, 0x2)), + (0x00A59, (0x2E2, 0x2)), + (0x0FA26, (0x9FE, 0x1)), + (0x0FA45, (0xA1A, 0x1)), + (0x00112, (0x08A, 0x2)), + (0x2F82E, (0xB8A, 0x1)), + (0x0FA33, (0xA08, 0x1)), + (0x1112F, (0xAFF, 0x2)), + (0x00206, (0x1BC, 0x2)), + (0x030DC, (0x8D1, 0x2)), + (0x003CB, (0x23A, 0x2)), + (0x0F986, (0x967, 0x1)), + (0x0FB2D, (0xAB8, 0x3)), + (0x01FA9, (0x75E, 0x3)), + (0x0304E, (0x86F, 0x2)), + (0x0F9E6, (0x9C7, 0x1)), + (0x115BB, (0xB1B, 0x2)), + (0x11391, (0xB0B, 0x2)), + (0x01B3D, (0x34A, 0x2)), + (0x00DDA, (0x30F, 0x2)), + (0x0F992, (0x973, 0x1)), + (0x0015D, (0x102, 0x2)), + (0x00477, (0x268, 0x2)), + (0x0F9B1, (0x992, 0x1)), + (0x0040D, (0x250, 0x2)), + (0x030F7, (0x8D7, 0x2)), + (0x0F977, (0x958, 0x1)), + (0x0FAC4, (0xA97, 0x1)), + (0x0FA3B, (0xA10, 0x1)), + (0x2F88B, (0xBE7, 0x1)), + (0x02279, (0x843, 0x2)), + (0x0FA01, (0x9E2, 0x1)), + (0x01F79, (0x6BB, 0x2)), + (0x03062, (0x883, 0x2)), + (0x2F9D6, (0xD32, 0x1)), + (0x004ED, (0x298, 0x2)), + (0x2FA05, (0xD61, 0x1)), + (0x110AB, (0xAFB, 0x2)), + (0x0F9F1, (0x9D2, 0x1)), + (0x01E54, (0x40E, 0x2)), + (0x2F8B6, (0xC12, 0x1)), + (0x0FA25, (0x9FD, 0x1)), + (0x001D3, (0x156, 0x2)), + (0x01E2D, (0x3B4, 0x2)), + (0x00622, (0x2AE, 0x2)), + (0x0F9A9, (0x98A, 0x1)), + (0x00CC7, (0x300, 0x2)), + (0x01F7A, (0x6BD, 0x2)), + (0x0FA57, (0xA2C, 0x1)), + (0x2F9A8, (0xD04, 0x1)), + (0x001E0, (0x178, 0x3)), + (0x2F904, (0xC60, 0x1)), + (0x01FA7, (0x757, 0x4)), + (0x01EC3, (0x507, 0x3)), + (0x2F983, (0xCDF, 0x1)), + (0x009CC, (0x2D6, 0x2)), + (0x000D4, (0x024, 0x2)), + (0x0FAD9, (0xAAC, 0x1)), + (0x01F04, (0x5A2, 0x3)), + (0x2F8B0, (0xC0C, 0x1)), + (0x2F8D7, (0xC33, 0x1)), + (0x0F9FB, (0x9DC, 0x1)), + (0x2F9FB, (0xD57, 0x1)), + (0x00217, (0x1DE, 0x2)), + (0x2F9C1, (0xD1D, 0x1)), + (0x2F98B, (0xCE7, 0x1)), + (0x01F56, (0x66C, 0x3)), + (0x2F9E2, (0xD3E, 0x1)), + (0x00625, (0x2B4, 0x2)), + (0x0307A, (0x899, 0x2)), + (0x2F818, (0xB74, 0x1)), + (0x01E83, (0x478, 0x2)), + (0x01FB7, (0x787, 0x3)), + (0x01ECA, (0x51A, 0x2)), + (0x2F8F2, (0xC4E, 0x1)), + (0x2F990, (0xCEC, 0x1)), + (0x2F9DF, (0xD3B, 0x1)), + (0x2F859, (0xBB5, 0x1)), + (0x2FA09, (0xD65, 0x1)), + (0x2F883, (0xBDF, 0x1)), + (0x01FD7, (0x7C0, 0x3)), + (0x2F872, (0xBCE, 0x1)), + (0x2F85E, (0xBBA, 0x1)), + (0x2F9B5, (0xD11, 0x1)), + (0x0F9F4, (0x9D5, 0x1)), + (0x00213, (0x1D6, 0x2)), + (0x01EF4, (0x58C, 0x2)), + (0x2F9DA, (0xD36, 0x1)), + (0x01E36, (0x3C8, 0x2)), + (0x006D3, (0x2BC, 0x2)), + (0x2F9FF, (0xD5B, 0x1)), + (0x2F97C, (0xCD8, 0x1)), + (0x01FFC, (0x808, 0x2)), + (0x2F8AD, (0xC09, 0x1)), + (0x2F8FC, (0xC58, 0x1)), + (0x01E31, (0x3BE, 0x2)), + (0x003AC, (0x22D, 0x2)), + (0x01E80, (0x472, 0x2)), + (0x001D2, (0x154, 0x2)), + (0x0F901, (0x8E2, 0x1)), + (0x0F9DF, (0x9C0, 0x1)), + (0x0FA83, (0xA56, 0x1)), + (0x2F946, (0xCA2, 0x1)), + (0x2F863, (0xBBF, 0x1)), + (0x01F8B, (0x6ED, 0x4)), + (0x0FA7C, (0xA4F, 0x1)), + (0x00151, (0x0EE, 0x2)), + (0x01FC1, (0x795, 0x2)), + (0x2F8F8, (0xC54, 0x1)), + (0x2F9B3, (0xD0F, 0x1)), + (0x2F8A6, (0xC02, 0x1)), + (0x003AE, (0x231, 0x2)), + (0x2F9C9, (0xD25, 0x1)), + (0x2F9D8, (0xD34, 0x1)), + (0x2F81C, (0xB78, 0x1)), + (0x01EBA, (0x4F0, 0x2)), + (0x2F853, (0xBAF, 0x1)), + (0x00118, (0x096, 0x2)), + (0x2F8B7, (0xC13, 0x1)), + (0x2F9B8, (0xD14, 0x1)), + (0x2F93F, (0xC9B, 0x1)), + (0x0F9E0, (0x9C1, 0x1)), + (0x00385, (0x215, 0x2)), + (0x2F888, (0xBE4, 0x1)), + (0x0F99D, (0x97E, 0x1)), + (0x01E5B, (0x41C, 0x2)), + (0x000C4, (0x008, 0x2)), + (0x16122, (0xB21, 0x2)), + (0x03058, (0x879, 0x2)), + (0x01E68, (0x43C, 0x3)), + (0x0212A, (0x80E, 0x1)), + (0x2F921, (0xC7D, 0x1)), + (0x02260, (0x82F, 0x2)), + (0x0FB1F, (0xAAF, 0x2)), + (0x02001, (0x80C, 0x1)), + (0x01F88, (0x6E3, 0x3)), + (0x01F9C, (0x72D, 0x4)), + (0x00137, (0x0CA, 0x2)), + (0x0FA30, (0xA05, 0x1)), + (0x01E49, (0x3F0, 0x2)), + (0x0F9E1, (0x9C2, 0x1)), + (0x0FA8F, (0xA62, 0x1)), + (0x11938, (0xB1D, 0x2)), + (0x0F9D1, (0x9B2, 0x1)), + (0x0020B, (0x1C6, 0x2)), + (0x0FA9C, (0xA6F, 0x1)), + (0x0F982, (0x963, 0x1)), + (0x2F97B, (0xCD7, 0x1)), + (0x00400, (0x246, 0x2)), + (0x0FA40, (0xA15, 0x1)), + (0x0F96D, (0x94E, 0x1)), + (0x02241, (0x827, 0x2)), + (0x2F924, (0xC80, 0x1)), + (0x00172, (0x128, 0x2)), + (0x01E1F, (0x398, 0x2)), + (0x2F993, (0xCEF, 0x1)), + (0x001FB, (0x1A5, 0x3)), + (0x00F75, (0x326, 0x2)), + (0x00162, (0x10C, 0x2)), + (0x001E2, (0x17E, 0x2)), + (0x00374, (0x213, 0x1)), + (0x0F997, (0x978, 0x1)), + (0x004DE, (0x282, 0x2)), + (0x000D9, (0x02A, 0x2)), + (0x2F9EA, (0xD46, 0x1)), + (0x2F8AB, (0xC07, 0x1)), + (0x0FA7A, (0xA4D, 0x1)), + (0x2F8FA, (0xC56, 0x1)), + (0x0F90E, (0x8EF, 0x1)), + (0x0F983, (0x964, 0x1)), + (0x0016A, (0x118, 0x2)), + (0x0FA68, (0xA3D, 0x1)), + (0x000FB, (0x062, 0x2)), + (0x2FA16, (0xD72, 0x1)), + (0x01FFA, (0x804, 0x2)), + (0x01F02, (0x59C, 0x3)), + (0x2FA02, (0xD5E, 0x1)), + (0x01E3A, (0x3D2, 0x2)), + (0x01E69, (0x43F, 0x3)), + (0x0FAAD, (0xA80, 0x1)), + (0x004F8, (0x2AA, 0x2)), + (0x004D3, (0x274, 0x2)), + (0x01EF1, (0x585, 0x3)), + (0x1138E, (0xB09, 0x2)), + (0x2F8A5, (0xC01, 0x1)), + (0x2F837, (0xB93, 0x1)), + (0x01E0A, (0x368, 0x2)), + (0x0FA96, (0xA69, 0x1)), + (0x0014D, (0x0E6, 0x2)), + (0x1D162, (0xB43, 0x3)), + (0x0F923, (0x904, 0x1)), + (0x0FAB7, (0xA8A, 0x1)), + (0x01F11, (0x5C6, 0x2)), + (0x000EE, (0x04E, 0x2)), + (0x030C2, (0x8B9, 0x2)), + (0x0FA31, (0xA06, 0x1)), + (0x001D6, (0x15D, 0x3)), + (0x0FB4D, (0xAEF, 0x2)), + (0x000EC, (0x04A, 0x2)), + (0x2F969, (0xCC5, 0x1)), + (0x0F921, (0x902, 0x1)), + (0x00F76, (0x328, 0x2)), + (0x01EB5, (0x4E3, 0x3)), + (0x00155, (0x0F2, 0x2)), + (0x0FA61, (0xA36, 0x1)), + (0x0020E, (0x1CC, 0x2)), + (0x01F54, (0x666, 0x3)), + (0x2F8D9, (0xC35, 0x1)), + (0x0FAA1, (0xA74, 0x1)), + (0x2F985, (0xCE1, 0x1)), + (0x0F96F, (0x950, 0x1)), + (0x2F974, (0xCD0, 0x1)), + (0x01EC4, (0x50A, 0x3)), + (0x01E44, (0x3E6, 0x2)), + (0x2F8F0, (0xC4C, 0x1)), + (0x0FA81, (0xA54, 0x1)), + (0x0F9DE, (0x9BF, 0x1)), + (0x2F9A5, (0xD01, 0x1)), + (0x01FEA, (0x7E8, 0x2)), + (0x0FABF, (0xA92, 0x1)), + (0x00457, (0x25E, 0x2)), + (0x01E21, (0x39C, 0x2)), + (0x0FAB0, (0xA83, 0x1)), + (0x01E55, (0x410, 0x2)), + (0x01EF8, (0x594, 0x2)), + (0x0F91B, (0x8FC, 0x1)), + (0x01E50, (0x402, 0x3)), + (0x000EB, (0x048, 0x2)), + (0x2FA0A, (0xD66, 0x1)), + (0x0F94F, (0x930, 0x1)), + (0x004E4, (0x28A, 0x2)), + (0x0013B, (0x0D0, 0x2)), + (0x00169, (0x116, 0x2)), + (0x2FA01, (0xD5D, 0x1)), + (0x0F9E5, (0x9C6, 0x1)), + (0x0FA1A, (0x9F6, 0x1)), + (0x2F8AC, (0xC08, 0x1)), + (0x01F6A, (0x697, 0x3)), + (0x00CC8, (0x302, 0x2)), + (0x0F911, (0x8F2, 0x1)), + (0x0F928, (0x909, 0x1)), + (0x01E6C, (0x446, 0x2)), + (0x02226, (0x825, 0x2)), + (0x2F8E9, (0xC45, 0x1)), + (0x0F9FA, (0x9DB, 0x1)), + (0x01EE9, (0x56D, 0x3)), + (0x01F80, (0x6C5, 0x3)), + (0x01F13, (0x5CB, 0x3)), + (0x2F98C, (0xCE8, 0x1)), + (0x2F96B, (0xCC7, 0x1)), + (0x01FFB, (0x806, 0x2)), + (0x2F920, (0xC7C, 0x1)), + (0x0F951, (0x932, 0x1)), + (0x1112E, (0xAFD, 0x2)), + (0x000DC, (0x030, 0x2)), + (0x2FA1C, (0xD78, 0x1)), + (0x2F940, (0xC9C, 0x1)), + (0x2F84E, (0xBAA, 0x1)), + (0x0FA03, (0x9E4, 0x1)), + (0x0F914, (0x8F5, 0x1)), + (0x0F931, (0x912, 0x1)), + (0x0F98A, (0x96B, 0x1)), + (0x00F69, (0x322, 0x2)), + (0x0F9BD, (0x99E, 0x1)), + (0x030B2, (0x8A9, 0x2)), + (0x01FBE, (0x794, 0x1)), + (0x2F8C2, (0xC1E, 0x1)), + (0x0FAD8, (0xAAB, 0x1)), + (0x01FDE, (0x7CD, 0x2)), + (0x01F8F, (0x6FD, 0x4)), + (0x2FA11, (0xD6D, 0x1)), + (0x01E5E, (0x424, 0x2)), + (0x2F9C6, (0xD22, 0x1)), + (0x0014F, (0x0EA, 0x2)), + (0x030D6, (0x8C9, 0x2)), + (0x2F968, (0xCC4, 0x1)), + (0x0F952, (0x933, 0x1)), + (0x2F8E8, (0xC44, 0x1)), + (0x01F50, (0x65C, 0x2)), + (0x01E56, (0x412, 0x2)), + (0x0F9CC, (0x9AD, 0x1)), + (0x001D4, (0x158, 0x2)), + (0x0FABE, (0xA91, 0x1)), + (0x00123, (0x0AC, 0x2)), + (0x0FB3C, (0xAD5, 0x2)), + (0x0F996, (0x977, 0x1)), + (0x01E8D, (0x48C, 0x2)), + (0x2F8DB, (0xC37, 0x1)), + (0x00215, (0x1DA, 0x2)), + (0x0F909, (0x8EA, 0x1)), + (0x16123, (0xB23, 0x2)), + (0x0FA6B, (0xA40, 0x1)), + (0x02247, (0x82B, 0x2)), + (0x030D0, (0x8C1, 0x2)), + (0x1D1BE, (0xB53, 0x3)), + (0x004D1, (0x270, 0x2)), + (0x0FA79, (0xA4C, 0x1)), + (0x01E7F, (0x470, 0x2)), + (0x0FA12, (0x9F0, 0x1)), + (0x022AC, (0x851, 0x2)), + (0x0F9D4, (0x9B5, 0x1)), + (0x01EDA, (0x544, 0x3)), + (0x0F90D, (0x8EE, 0x1)), + (0x0F922, (0x903, 0x1)), + (0x01F8C, (0x6F1, 0x4)), + (0x01E13, (0x37A, 0x2)), + (0x030F4, (0x8D5, 0x2)), + (0x0FA88, (0xA5B, 0x1)), + (0x000CA, (0x012, 0x2)), + (0x01E0C, (0x36C, 0x2)), + (0x114BE, (0xB17, 0x2)), + (0x2F964, (0xCC0, 0x1)), + (0x030D9, (0x8CD, 0x2)), + (0x2F907, (0xC63, 0x1)), + (0x00161, (0x10A, 0x2)), + (0x0FAD0, (0xAA3, 0x1)), + (0x2FA03, (0xD5F, 0x1)), + (0x01FD6, (0x7BE, 0x2)), + (0x2F8B4, (0xC10, 0x1)), + (0x2F893, (0xBEF, 0x1)), + (0x01E45, (0x3E8, 0x2)), + (0x16127, (0xB2C, 0x3)), + (0x000ED, (0x04C, 0x2)), + (0x0FA35, (0xA0A, 0x1)), + (0x001FC, (0x1A8, 0x2)), + (0x01E60, (0x428, 0x2)), + (0x01E7D, (0x46C, 0x2)), + (0x0FA4C, (0xA21, 0x1)), + (0x00200, (0x1B0, 0x2)), + (0x0F93F, (0x920, 0x1)), + (0x2F911, (0xC6D, 0x1)), + (0x00168, (0x114, 0x2)), + (0x0F993, (0x974, 0x1)), + (0x00136, (0x0C8, 0x2)), + (0x01EAA, (0x4C2, 0x3)), + (0x0F969, (0x94A, 0x1)), + (0x2F8D5, (0xC31, 0x1)), + (0x01E99, (0x4A4, 0x2)), + (0x01E6F, (0x44C, 0x2)), + (0x0FA1B, (0x9F7, 0x1)), + (0x01E9B, (0x4A6, 0x2)), + (0x2F808, (0xB64, 0x1)), + (0x01F43, (0x643, 0x3)), + (0x0F980, (0x961, 0x1)), + (0x0FA58, (0xA2D, 0x1)), + (0x2F8A8, (0xC04, 0x1)), + (0x03052, (0x873, 0x2)), + (0x2F9E9, (0xD45, 0x1)), + (0x00344, (0x211, 0x2)), + (0x0FA38, (0xA0D, 0x1)), + (0x2F935, (0xC91, 0x1)), + (0x01F14, (0x5CE, 0x3)), + (0x01F39, (0x628, 0x2)), + (0x01E71, (0x450, 0x2)), + (0x0F96B, (0x94C, 0x1)), + (0x0F9F3, (0x9D4, 0x1)), + (0x0FAB6, (0xA89, 0x1)), + (0x01FD8, (0x7C3, 0x2)), + (0x0F995, (0x976, 0x1)), + (0x01EF9, (0x596, 0x2)), + (0x2F82F, (0xB8B, 0x1)), + (0x2F9BF, (0xD1B, 0x1)), + (0x0FA2E, (0xA03, 0x1)), + (0x2F814, (0xB70, 0x1)), + (0x0FAD1, (0xAA4, 0x1)), + (0x01E1D, (0x393, 0x3)), + (0x0038F, (0x224, 0x2)), + (0x2F8A1, (0xBFD, 0x1)), + (0x00228, (0x1F0, 0x2)), + (0x2F81E, (0xB7A, 0x1)), + (0x2F811, (0xB6D, 0x1)), + (0x001CD, (0x14A, 0x2)), + (0x01FC7, (0x7A1, 0x3)), + (0x0022A, (0x1F4, 0x3)), + (0x01F6B, (0x69A, 0x3)), + (0x00624, (0x2B2, 0x2)), + (0x01FC8, (0x7A4, 0x2)), + (0x0FAC2, (0xA95, 0x1)), + (0x0F9E7, (0x9C8, 0x1)), + (0x2F8FE, (0xC5A, 0x1)), + (0x030C9, (0x8BF, 0x2)), + (0x2F908, (0xC64, 0x1)), + (0x2F9E7, (0xD43, 0x1)), + (0x0FABB, (0xA8E, 0x1)), + (0x2FA1B, (0xD77, 0x1)), + (0x00139, (0x0CC, 0x2)), + (0x0FA1D, (0x9F9, 0x1)), + (0x01EF2, (0x588, 0x2)), + (0x2F998, (0xCF4, 0x1)), + (0x2F91F, (0xC7B, 0x1)), + (0x0FA9B, (0xA6E, 0x1)), + (0x0FA80, (0xA53, 0x1)), + (0x2F95C, (0xCB8, 0x1)), + (0x2F9F5, (0xD51, 0x1)), + (0x2F91A, (0xC76, 0x1)), + (0x01F70, (0x6A9, 0x2)), + (0x2F86B, (0xBC7, 0x1)), + (0x2F85A, (0xBB6, 0x1)), + (0x0013E, (0x0D6, 0x2)), + (0x2F850, (0xBAC, 0x1)), + (0x004DB, (0x27C, 0x2)), + (0x2F871, (0xBCD, 0x1)), + (0x0F970, (0x951, 0x1)), + (0x004DD, (0x280, 0x2)), + (0x01E1A, (0x38C, 0x2)), + (0x2F90E, (0xC6A, 0x1)), + (0x01F65, (0x68A, 0x3)), + (0x0F929, (0x90A, 0x1)), + (0x01EDD, (0x54D, 0x3)), + (0x01F89, (0x6E6, 0x3)), + (0x004D7, (0x278, 0x2)), + (0x01E2F, (0x3B9, 0x3)), + (0x2F860, (0xBBC, 0x1)), + (0x01F55, (0x669, 0x3)), + (0x0FAA4, (0xA77, 0x1)), + (0x0FA59, (0xA2E, 0x1)), + (0x0FB4B, (0xAEB, 0x2)), + (0x2F8BF, (0xC1B, 0x1)), + (0x01EE7, (0x568, 0x2)), + (0x004F9, (0x2AC, 0x2)), + (0x2F995, (0xCF1, 0x1)), + (0x022AF, (0x857, 0x2)), + (0x0F9B6, (0x997, 0x1)), + (0x01EBC, (0x4F4, 0x2)), + (0x004F5, (0x2A8, 0x2)), + (0x2F826, (0xB82, 0x1)), + (0x00116, (0x092, 0x2)), + (0x00453, (0x25C, 0x2)), + (0x0FB47, (0xAE3, 0x2)), + (0x01E08, (0x362, 0x3)), + (0x2F8E1, (0xC3D, 0x1)), + (0x001DC, (0x16F, 0x3)), + (0x0FA05, (0x9E6, 0x1)), + (0x0F908, (0x8E9, 0x1)), + (0x2F839, (0xB95, 0x1)), + (0x0F95F, (0x940, 0x1)), + (0x0012A, (0x0B6, 0x2)), + (0x0040E, (0x252, 0x2)), + (0x000D3, (0x022, 0x2)), + (0x03069, (0x889, 0x2)), + (0x2F944, (0xCA0, 0x1)), + (0x0F90F, (0x8F0, 0x1)), + (0x0F9A1, (0x982, 0x1)), + (0x001D0, (0x150, 0x2)), + (0x01F9B, (0x729, 0x4)), + (0x2FA04, (0xD60, 0x1)), + (0x01F74, (0x6B1, 0x2)), + (0x01F1D, (0x5E1, 0x3)), + (0x0F9F8, (0x9D9, 0x1)), + (0x2F9E3, (0xD3F, 0x1)), + (0x01FE2, (0x7D5, 0x3)), + (0x02288, (0x84D, 0x2)), + (0x2F9C2, (0xD1E, 0x1)), + (0x030D3, (0x8C5, 0x2)), + (0x030C0, (0x8B7, 0x2)), + (0x0226F, (0x837, 0x2)), + (0x2F9C8, (0xD24, 0x1)), + (0x2F8ED, (0xC49, 0x1)), + (0x2F85C, (0xBB8, 0x1)), + (0x01F0C, (0x5B8, 0x3)), + (0x01FC3, (0x79A, 0x2)), + (0x01FF2, (0x7F3, 0x3)), + (0x2F8EC, (0xC48, 0x1)), + (0x2F885, (0xBE1, 0x1)), + (0x2FA1A, (0xD76, 0x1)), + (0x00216, (0x1DC, 0x2)), + (0x2F8C7, (0xC23, 0x1)), + (0x01F71, (0x6AB, 0x2)), + (0x00209, (0x1C2, 0x2)), + (0x0F999, (0x97A, 0x1)), + (0x01FD1, (0x7B6, 0x2)), + (0x03094, (0x89F, 0x2)), + (0x2F878, (0xBD4, 0x1)), + (0x01E5C, (0x41E, 0x3)), + (0x01FED, (0x7EE, 0x2)), + (0x0F9F7, (0x9D8, 0x1)), + (0x2F9DE, (0xD3A, 0x1)), + (0x0F925, (0x906, 0x1)), + (0x001DA, (0x169, 0x3)), + (0x000D5, (0x026, 0x2)), + (0x0FA08, (0x9E9, 0x1)), + (0x01EC9, (0x518, 0x2)), + (0x00117, (0x094, 0x2)), + (0x01F3A, (0x62A, 0x3)), + (0x2F9FE, (0xD5A, 0x1)), + (0x01F2C, (0x604, 0x3)), + (0x0F94C, (0x92D, 0x1)), + (0x01E52, (0x408, 0x3)), + (0x02249, (0x82D, 0x2)), + (0x0021E, (0x1E8, 0x2)), + (0x01F44, (0x646, 0x3)), + (0x0F988, (0x969, 0x1)), + (0x01E4B, (0x3F4, 0x2)), + (0x01FE0, (0x7D1, 0x2)), + (0x01F6C, (0x69D, 0x3)), + (0x0FA66, (0xA3B, 0x1)), + (0x2F82B, (0xB87, 0x1)), + (0x01E67, (0x439, 0x3)), + (0x2F976, (0xCD2, 0x1)), + (0x0FA43, (0xA18, 0x1)), + (0x01E35, (0x3C6, 0x2)), + (0x2F83D, (0xB99, 0x1)), + (0x2F8DE, (0xC3A, 0x1)), + (0x2F813, (0xB6F, 0x1)), + (0x00175, (0x12E, 0x2)), + (0x0F979, (0x95A, 0x1)), + (0x2F942, (0xC9E, 0x1)), + (0x0F9FE, (0x9DF, 0x1)), + (0x0FAA3, (0xA76, 0x1)), + (0x0F974, (0x955, 0x1)), + (0x0F9AA, (0x98B, 0x1)), + (0x0F9C1, (0x9A2, 0x1)), + (0x02000, (0x80B, 0x1)), + (0x2F905, (0xC61, 0x1)), + (0x1109C, (0xAF9, 0x2)), + (0x0FA7F, (0xA52, 0x1)), + (0x2F890, (0xBEC, 0x1)), + (0x03073, (0x88F, 0x2)), + (0x0F9E8, (0x9C9, 0x1)), + (0x2F887, (0xBE3, 0x1)), + (0x000FA, (0x060, 0x2)), + (0x2F803, (0xB5F, 0x1)), + (0x2F9CF, (0xD2B, 0x1)), + (0x2F8A7, (0xC03, 0x1)), + (0x2F820, (0xB7C, 0x1)), + (0x0FB30, (0xABF, 0x2)), + (0x000EF, (0x050, 0x2)), + (0x1D1C0, (0xB59, 0x3)), + (0x01E37, (0x3CA, 0x2)), + (0x2F932, (0xC8E, 0x1)), + (0x021AE, (0x815, 0x2)), + (0x0FAC6, (0xA99, 0x1)), + (0x01F2B, (0x601, 0x3)), + (0x0FA3F, (0xA14, 0x1)), + (0x0FA54, (0xA29, 0x1)), + (0x001DB, (0x16C, 0x3)), + (0x01F26, (0x5F4, 0x3)), + (0x2F80F, (0xB6B, 0x1)), + (0x001F0, (0x198, 0x2)), + (0x0FA0B, (0x9EC, 0x1)), + (0x2F857, (0xBB3, 0x1)), + (0x0FA10, (0x9EF, 0x1)), + (0x2FA14, (0xD70, 0x1)), + (0x2F8F4, (0xC50, 0x1)), + (0x003B0, (0x235, 0x3)), + (0x0F9D2, (0x9B3, 0x1)), + (0x2F842, (0xB9E, 0x1)), + (0x01F9A, (0x725, 0x4)), + (0x01EED, (0x579, 0x3)), + (0x01ED8, (0x53E, 0x3)), + (0x00144, (0x0DA, 0x2)), + (0x003D4, (0x244, 0x2)), + (0x2F870, (0xBCC, 0x1)), + (0x0F95C, (0x93D, 0x1)), + (0x0FA92, (0xA65, 0x1)), + (0x2F962, (0xCBE, 0x1)), + (0x2F8E4, (0xC40, 0x1)), + (0x01E15, (0x37F, 0x3)), + (0x022E0, (0x859, 0x2)), + (0x001D1, (0x152, 0x2)), + (0x00165, (0x112, 0x2)), + (0x0FAD2, (0xAA5, 0x1)), + (0x0FB2C, (0xAB5, 0x3)), + (0x01E39, (0x3CF, 0x3)), + (0x2F9AE, (0xD0A, 0x1)), + (0x000C8, (0x00E, 0x2)), + (0x2F8BC, (0xC18, 0x1)), + (0x01EEB, (0x573, 0x3)), + (0x2F96A, (0xCC6, 0x1)), + (0x001FA, (0x1A2, 0x3)), + (0x2F8CD, (0xC29, 0x1)), + (0x2F8A4, (0xC00, 0x1)), + (0x0F91E, (0x8FF, 0x1)), + (0x113C7, (0xB0F, 0x2)), + (0x01FEF, (0x7F2, 0x1)), + (0x2F899, (0xBF5, 0x1)), + (0x2F8D8, (0xC34, 0x1)), + (0x01E47, (0x3EC, 0x2)), + (0x022AE, (0x855, 0x2)), + (0x00389, (0x21C, 0x2)), + (0x0FA8E, (0xA61, 0x1)), + (0x000CC, (0x016, 0x2)), + (0x2F81D, (0xB79, 0x1)), + (0x0F941, (0x922, 0x1)), + (0x0F975, (0x956, 0x1)), + (0x00A5A, (0x2E4, 0x2)), + (0x00FA2, (0x332, 0x2)), + (0x01FB1, (0x77B, 0x2)), + (0x00106, (0x076, 0x2)), + (0x2F954, (0xCB0, 0x1)), + (0x004EB, (0x294, 0x2)), + (0x01F72, (0x6AD, 0x2)), + (0x2F8AE, (0xC0A, 0x1)), + (0x01ED4, (0x532, 0x3)), + (0x01E81, (0x474, 0x2)), + (0x0FA42, (0xA17, 0x1)), + (0x00626, (0x2B6, 0x2)), + (0x01E43, (0x3E4, 0x2)), + (0x01F77, (0x6B7, 0x2)), + (0x001EA, (0x18A, 0x2)), + (0x0F9D3, (0x9B4, 0x1)), + (0x2F819, (0xB75, 0x1)), + (0x2F8BE, (0xC1A, 0x1)), + (0x01ED9, (0x541, 0x3)), + (0x0F930, (0x911, 0x1)), + (0x0FA91, (0xA64, 0x1)), + (0x0095F, (0x2D2, 0x2)), + (0x2F930, (0xC8C, 0x1)), + (0x2F86D, (0xBC9, 0x1)), + (0x004EA, (0x292, 0x2)), + (0x01EE6, (0x566, 0x2)), + (0x01F01, (0x59A, 0x2)), + (0x022E2, (0x85D, 0x2)), + (0x01FDD, (0x7CB, 0x2)), + (0x2FA18, (0xD74, 0x1)), + (0x03076, (0x893, 0x2)), + (0x2F906, (0xC62, 0x1)), + (0x2F9C3, (0xD1F, 0x1)), + (0x01F08, (0x5AE, 0x2)), + (0x01B3B, (0x348, 0x2)), + (0x0022B, (0x1F7, 0x3)), + (0x01F86, (0x6DB, 0x4)), + (0x000C3, (0x006, 0x2)), + (0x0038E, (0x222, 0x2)), + (0x004D0, (0x26E, 0x2)), + (0x030C7, (0x8BD, 0x2)), + (0x00A5B, (0x2E6, 0x2)), + (0x000F9, (0x05E, 0x2)), + (0x0017D, (0x13E, 0x2)), + (0x01E94, (0x49A, 0x2)), + (0x01E3D, (0x3D8, 0x2)), + (0x0FAB1, (0xA84, 0x1)), + (0x2F8DA, (0xC36, 0x1)), + (0x01F6F, (0x6A6, 0x3)), + (0x0F937, (0x918, 0x1)), + (0x2F8EE, (0xC4A, 0x1)), + (0x2F8C1, (0xC1D, 0x1)), + (0x2F913, (0xC6F, 0x1)), + (0x0F912, (0x8F3, 0x1)), + (0x2F978, (0xCD4, 0x1)), + (0x2F97F, (0xCDB, 0x1)), + (0x001EF, (0x196, 0x2)), + (0x01E65, (0x433, 0x3)), + (0x0012F, (0x0C0, 0x2)), + (0x01FC6, (0x79F, 0x2)), + (0x0FAC0, (0xA93, 0x1)), + (0x0020A, (0x1C4, 0x2)), + (0x000C0, (0x000, 0x2)), + (0x02209, (0x81F, 0x2)), + (0x003CE, (0x240, 0x2)), + (0x0020D, (0x1CA, 0x2)), + (0x2F99E, (0xCFA, 0x1)), + (0x00FA7, (0x334, 0x2)), + (0x0F98E, (0x96F, 0x1)), + (0x2F805, (0xB61, 0x1)), + (0x01EC1, (0x501, 0x3)), + (0x00159, (0x0FA, 0x2)), + (0x01FCD, (0x7AE, 0x2)), + (0x01F40, (0x63C, 0x2)), + (0x2F933, (0xC8F, 0x1)), + (0x030B0, (0x8A7, 0x2)), + (0x01F30, (0x610, 0x2)), + (0x00F93, (0x32E, 0x2)), + (0x1134C, (0xB03, 0x2)), + (0x2FA06, (0xD62, 0x1)), + (0x2F9A2, (0xCFE, 0x1)), + (0x2F80C, (0xB68, 0x1)), + (0x2F9D9, (0xD35, 0x1)), + (0x01E19, (0x38A, 0x2)), + (0x000C5, (0x00A, 0x2)), + (0x01F9F, (0x739, 0x4)), + (0x2F95D, (0xCB9, 0x1)), + (0x00DDC, (0x311, 0x2)), + (0x01F81, (0x6C8, 0x3)), + (0x01E76, (0x45A, 0x2)), + (0x0F957, (0x938, 0x1)), + (0x00134, (0x0C4, 0x2)), + (0x01E97, (0x4A0, 0x2)), + (0x01EB2, (0x4DA, 0x3)), + (0x2F89A, (0xBF6, 0x1)), + (0x2F828, (0xB84, 0x1)), + (0x0015C, (0x100, 0x2)), + (0x0F967, (0x948, 0x1)), + (0x00122, (0x0AA, 0x2)), + (0x2F967, (0xCC3, 0x1)), + (0x00163, (0x10E, 0x2)), + (0x0FA2A, (0x9FF, 0x1)), + (0x00207, (0x1BE, 0x2)), + (0x001D8, (0x163, 0x3)), + (0x01F78, (0x6B9, 0x2)), + (0x0FA51, (0xA26, 0x1)), + (0x2F988, (0xCE4, 0x1)), + (0x2F918, (0xC74, 0x1)), + (0x030D7, (0x8CB, 0x2)), + (0x2F92D, (0xC89, 0x1)), + (0x2F9A1, (0xCFD, 0x1)), + (0x01F42, (0x640, 0x3)), + (0x00160, (0x108, 0x2)), + (0x00CC0, (0x2FE, 0x2)), + (0x030BA, (0x8B1, 0x2)), + (0x01EBE, (0x4F8, 0x3)), + (0x01E10, (0x374, 0x2)), + (0x01EDE, (0x550, 0x3)), + (0x01F57, (0x66F, 0x3)), + (0x0F940, (0x921, 0x1)), + (0x01E06, (0x35E, 0x2)), + (0x0010A, (0x07E, 0x2)), + (0x01E46, (0x3EA, 0x2)), + (0x0F900, (0x8E1, 0x1)), + (0x004EE, (0x29A, 0x2)), + (0x2F88C, (0xBE8, 0x1)), + (0x2F889, (0xBE5, 0x1)), + (0x00FB9, (0x338, 0x2)), + (0x2F90C, (0xC68, 0x1)), + (0x2F8F1, (0xC4D, 0x1)), + (0x00C48, (0x2FC, 0x2)), + (0x03067, (0x887, 0x2)), + (0x2F917, (0xC73, 0x1)), + (0x2F8F3, (0xC4F, 0x1)), + (0x2F97A, (0xCD6, 0x1)), + (0x0F961, (0x942, 0x1)), + (0x0F97C, (0x95D, 0x1)), + (0x0037E, (0x214, 0x1)), + (0x2F824, (0xB80, 0x1)), + (0x004DA, (0x27A, 0x2)), + (0x2F89D, (0xBF9, 0x1)), + (0x2F960, (0xCBC, 0x1)), + (0x0022C, (0x1FA, 0x3)), + (0x2F96F, (0xCCB, 0x1)), + (0x01F33, (0x617, 0x3)), + (0x0FAD5, (0xAA8, 0x1)), + (0x2F9F7, (0xD53, 0x1)), + (0x16125, (0xB27, 0x2)), + (0x2F9AA, (0xD06, 0x1)), + (0x022EC, (0x865, 0x2)), + (0x00204, (0x1B8, 0x2)), + (0x01F3B, (0x62D, 0x3)), + (0x2F925, (0xC81, 0x1)), + (0x2F8B8, (0xC14, 0x1)), + (0x01E8B, (0x488, 0x2)), + (0x2F840, (0xB9C, 0x1)), + (0x2F931, (0xC8D, 0x1)), + (0x00218, (0x1E0, 0x2)), + (0x001EB, (0x18C, 0x2)), + (0x0F9A6, (0x987, 0x1)), + (0x0F976, (0x957, 0x1)), + (0x01EA0, (0x4A8, 0x2)), + (0x2F86E, (0xBCA, 0x1)), + (0x0FA97, (0xA6A, 0x1)), + (0x02204, (0x81D, 0x2)), + (0x0F9A5, (0x986, 0x1)), + (0x01F99, (0x722, 0x3)), + (0x01E82, (0x476, 0x2)), + (0x01F7D, (0x6C3, 0x2)), + (0x001E9, (0x188, 0x2)), + (0x2F884, (0xBE0, 0x1)), + (0x0020C, (0x1C8, 0x2)), + (0x16D69, (0xB34, 0x2)), + (0x2F9BC, (0xD18, 0x1)), + (0x2F847, (0xBA3, 0x1)), + (0x2F8C4, (0xC20, 0x1)), + (0x00BCB, (0x2F8, 0x2)), + (0x2F830, (0xB8C, 0x1)), + (0x01E03, (0x358, 0x2)), + (0x01E18, (0x388, 0x2)), + (0x030B6, (0x8AD, 0x2)), + (0x2F9D4, (0xD30, 0x1)), + (0x0F9B7, (0x998, 0x1)), + (0x001CE, (0x14C, 0x2)), + (0x0F934, (0x915, 0x1)), + (0x001B0, (0x148, 0x2)), + (0x0011F, (0x0A4, 0x2)), + (0x03074, (0x891, 0x2)), + (0x2F89C, (0xBF8, 0x1)), + (0x00227, (0x1EE, 0x2)), + (0x2F979, (0xCD5, 0x1)), + (0x2F9F2, (0xD4E, 0x1)), + (0x01FA4, (0x74B, 0x4)), + (0x2F862, (0xBBE, 0x1)), + (0x2F8E5, (0xC41, 0x1)), + (0x0016E, (0x120, 0x2)), + (0x0F98C, (0x96D, 0x1)), + (0x2F95E, (0xCBA, 0x1)), + (0x2F996, (0xCF2, 0x1)), + (0x01F84, (0x6D3, 0x4)), + (0x2F945, (0xCA1, 0x1)), + (0x00929, (0x2BE, 0x2)), + (0x2F89B, (0xBF7, 0x1)), + (0x02224, (0x823, 0x2)), + (0x01B08, (0x33E, 0x2)), + (0x0F9D6, (0x9B7, 0x1)), + (0x01F60, (0x67D, 0x2)), + (0x2F953, (0xCAF, 0x1)), + (0x01E6E, (0x44A, 0x2)), + (0x2F861, (0xBBD, 0x1)), + (0x00B5D, (0x2F2, 0x2)), + (0x2F938, (0xC94, 0x1)), + (0x2F9BD, (0xD19, 0x1)), + (0x2F9E4, (0xD40, 0x1)), + (0x2F943, (0xC9F, 0x1)), + (0x01E3F, (0x3DC, 0x2)), + (0x03060, (0x881, 0x2)), + (0x2F92F, (0xC8B, 0x1)), + (0x2F880, (0xBDC, 0x1)), + (0x02262, (0x831, 0x2)), + (0x0F9EB, (0x9CC, 0x1)), + (0x0F9DC, (0x9BD, 0x1)), + (0x01F45, (0x649, 0x3)), + (0x0FA6D, (0xA42, 0x1)), + (0x01E53, (0x40B, 0x3)), + (0x2F88F, (0xBEB, 0x1)), + (0x0F956, (0x937, 0x1)), + (0x0FA84, (0xA57, 0x1)), + (0x001D7, (0x160, 0x3)), + (0x113C5, (0xB0D, 0x2)), + (0x000E5, (0x03E, 0x2)), + (0x01F90, (0x701, 0x3)), + (0x2F9A6, (0xD02, 0x1)), + (0x01F0E, (0x5BE, 0x3)), + (0x0095E, (0x2D0, 0x2)), + (0x01E4D, (0x3F9, 0x3)), + (0x000D6, (0x028, 0x2)), + (0x01F96, (0x717, 0x4)), + (0x01EA6, (0x4B6, 0x3)), + (0x2F874, (0xBD0, 0x1)), + (0x2F9C5, (0xD21, 0x1)), + (0x2F981, (0xCDD, 0x1)), + (0x0F92B, (0x90C, 0x1)), + (0x0FA04, (0x9E5, 0x1)), + (0x2F987, (0xCE3, 0x1)), + (0x01E64, (0x430, 0x3)), + (0x0FB2B, (0xAB3, 0x2)), + (0x0FAAB, (0xA7E, 0x1)), + (0x2F915, (0xC71, 0x1)), + (0x2F81B, (0xB77, 0x1)), + (0x00958, (0x2C4, 0x2)), + (0x2FA07, (0xD63, 0x1)), + (0x0022E, (0x200, 0x2)), + (0x0FACC, (0xA9F, 0x1)), + (0x2F895, (0xBF1, 0x1)), + (0x001E3, (0x180, 0x2)), + (0x11385, (0xB07, 0x2)), + (0x0FA34, (0xA09, 0x1)), + (0x0FAA7, (0xA7A, 0x1)), + (0x01F92, (0x707, 0x4)), + (0x2F8C9, (0xC25, 0x1)), + (0x0FA18, (0x9F4, 0x1)), + (0x0F9DA, (0x9BB, 0x1)), + (0x2F94B, (0xCA7, 0x1)), + (0x0220C, (0x821, 0x2)), + (0x0F99E, (0x97F, 0x1)), + (0x00F57, (0x31E, 0x2)), + (0x00226, (0x1EC, 0x2)), + (0x01EB8, (0x4EC, 0x2)), + (0x00CCA, (0x304, 0x2)), + (0x2F8DF, (0xC3B, 0x1)), + (0x0040C, (0x24E, 0x2)), + (0x0F926, (0x907, 0x1)), + (0x01E85, (0x47C, 0x2)), + (0x0015B, (0x0FE, 0x2)), + (0x0FA7B, (0xA4E, 0x1)), + (0x0FA67, (0xA3C, 0x1)), + (0x0F946, (0x927, 0x1)), + (0x2F9CD, (0xD29, 0x1)), + (0x03054, (0x875, 0x2)), + (0x2F868, (0xBC4, 0x1)), + (0x0FA7D, (0xA50, 0x1)), + (0x01EA5, (0x4B3, 0x3)), + (0x2F832, (0xB8E, 0x1)), + (0x0FAA0, (0xA73, 0x1)), + (0x01FE8, (0x7E4, 0x2)), + (0x2F8B1, (0xC0D, 0x1)), + (0x00219, (0x1E2, 0x2)), + (0x0F9DD, (0x9BE, 0x1)), + (0x001DF, (0x175, 0x3)), + (0x0FA56, (0xA2B, 0x1)), + (0x2F9EC, (0xD48, 0x1)), + (0x2F8F5, (0xC51, 0x1)), + (0x03050, (0x871, 0x2)), + (0x1D163, (0xB46, 0x3)), + (0x01EB4, (0x4E0, 0x3)), + (0x0F95A, (0x93B, 0x1)), + (0x00DDD, (0x313, 0x3)), + (0x0FA76, (0xA49, 0x1)), + (0x00203, (0x1B6, 0x2)), + (0x01B40, (0x34C, 0x2)), + (0x004E2, (0x286, 0x2)), + (0x01E91, (0x494, 0x2)), + (0x2F95A, (0xCB6, 0x1)), + (0x0F9E4, (0x9C5, 0x1)), + (0x16D6A, (0xB36, 0x3)), + (0x0F989, (0x96A, 0x1)), + (0x01F03, (0x59F, 0x3)), + (0x00154, (0x0F0, 0x2)), + (0x000DB, (0x02E, 0x2)), + (0x2F923, (0xC7F, 0x1)), + (0x00232, (0x20A, 0x2)), + (0x00148, (0x0E2, 0x2)), + (0x2F87C, (0xBD8, 0x1)), + (0x0F9A0, (0x981, 0x1)), + (0x0F9CE, (0x9AF, 0x1)), + (0x006C2, (0x2BA, 0x2)), + (0x0FB41, (0xADB, 0x2)), + (0x2F8AA, (0xC06, 0x1)), + (0x2F91C, (0xC78, 0x1)), + (0x0F990, (0x971, 0x1)), + (0x01EE2, (0x55C, 0x3)), + (0x01F68, (0x693, 0x2)), + (0x01F21, (0x5E6, 0x2)), + (0x2F9B7, (0xD13, 0x1)), + (0x01FF8, (0x800, 0x2)), + (0x0FA09, (0x9EA, 0x1)), + (0x030B4, (0x8AB, 0x2)), + (0x0FB34, (0xAC7, 0x2)), + (0x000C2, (0x004, 0x2)), + (0x004E3, (0x288, 0x2)), + (0x01E59, (0x418, 0x2)), + (0x01B0C, (0x342, 0x2)), + (0x2F894, (0xBF0, 0x1)), + (0x01E57, (0x414, 0x2)), + (0x0021A, (0x1E4, 0x2)), + (0x0F9CB, (0x9AC, 0x1)), + (0x0226E, (0x835, 0x2)), + (0x114BC, (0xB15, 0x2)), + (0x2F896, (0xBF2, 0x1)), + (0x02274, (0x83D, 0x2)), + (0x0FAD6, (0xAA9, 0x1)), + (0x02275, (0x83F, 0x2)), + (0x0010C, (0x082, 0x2)), + (0x2F9B1, (0xD0D, 0x1)), + (0x0FB3B, (0xAD3, 0x2)), + (0x2F9F1, (0xD4D, 0x1)), + (0x00A36, (0x2E0, 0x2)), + (0x00BCA, (0x2F6, 0x2)), + (0x01ECC, (0x51E, 0x2)), + (0x2F958, (0xCB4, 0x1)), + (0x0FB35, (0xAC9, 0x2)), + (0x001A0, (0x142, 0x2)), + (0x0FA19, (0x9F5, 0x1)), + (0x0013D, (0x0D4, 0x2)), + (0x01EF6, (0x590, 0x2)), + (0x0038C, (0x220, 0x2)), + (0x2F881, (0xBDD, 0x1)), + (0x0F9D9, (0x9BA, 0x1)), + (0x01ECD, (0x520, 0x2)), + (0x01E7C, (0x46A, 0x2)), + (0x2F9DD, (0xD39, 0x1)), + (0x16126, (0xB29, 0x3)), + (0x2F9ED, (0xD49, 0x1)), + (0x2F952, (0xCAE, 0x1)), + (0x0F91F, (0x900, 0x1)), + (0x2F902, (0xC5E, 0x1)), + (0x0F97A, (0x95B, 0x1)), + (0x2F8FF, (0xC5B, 0x1)), + (0x0FA37, (0xA0C, 0x1)), + (0x0FB44, (0xADF, 0x2)), + (0x2F9EE, (0xD4A, 0x1)), + (0x00A5E, (0x2E8, 0x2)), + (0x01F4B, (0x653, 0x3)), + (0x0F9F2, (0x9D3, 0x1)), + (0x01E6D, (0x448, 0x2)), + (0x00164, (0x110, 0x2)), + (0x003CD, (0x23E, 0x2)), + (0x030FA, (0x8DD, 0x2)), + (0x0FAB2, (0xA85, 0x1)), + (0x01E40, (0x3DE, 0x2)), + (0x00156, (0x0F4, 0x2)), + (0x0FA53, (0xA28, 0x1)), + (0x2F99F, (0xCFB, 0x1)), + (0x2F96D, (0xCC9, 0x1)), + (0x2F9A7, (0xD03, 0x1)), + (0x01F19, (0x5D6, 0x2)), + (0x0F9BA, (0x99B, 0x1)), + (0x01EF0, (0x582, 0x3)), + (0x2F8D2, (0xC2E, 0x1)), + (0x00F5C, (0x320, 0x2)), + (0x1D1BD, (0xB50, 0x3)), + (0x01FB2, (0x77D, 0x3)), + (0x03065, (0x885, 0x2)), + (0x2F9DB, (0xD37, 0x1)), + (0x0038A, (0x21E, 0x2)), + (0x01F91, (0x704, 0x3)), + (0x0FB3A, (0xAD1, 0x2)), + (0x2F9BE, (0xD1A, 0x1)), + (0x01FBA, (0x78E, 0x2)), + (0x000F4, (0x058, 0x2)), + (0x00B4B, (0x2EC, 0x2)), + (0x0F910, (0x8F1, 0x1)), + (0x0F95B, (0x93C, 0x1)), + (0x2F876, (0xBD2, 0x1)), + (0x2F81F, (0xB7B, 0x1)), + (0x2F8BD, (0xC19, 0x1)), + (0x0F954, (0x935, 0x1)), + (0x2F822, (0xB7E, 0x1)), + (0x00201, (0x1B2, 0x2)), + (0x01E84, (0x47A, 0x2)), + (0x2FA08, (0xD64, 0x1)), + (0x0F9CF, (0x9B0, 0x1)), + (0x2F9A9, (0xD05, 0x1)), + (0x01F76, (0x6B5, 0x2)), + (0x0F96A, (0x94B, 0x1)), + (0x0F9E3, (0x9C4, 0x1)), + (0x2F844, (0xBA0, 0x1)), + (0x0FB2E, (0xABB, 0x2)), + (0x0FAB5, (0xA88, 0x1)), + (0x000C1, (0x002, 0x2)), + (0x00178, (0x134, 0x2)), + (0x2F8D6, (0xC32, 0x1)), + (0x00343, (0x210, 0x1)), + (0x2F815, (0xB71, 0x1)), + (0x2F85F, (0xBBB, 0x1)), + (0x0F93B, (0x91C, 0x1)), + (0x001F8, (0x19E, 0x2)), + (0x01EB6, (0x4E6, 0x3)), + (0x01FE7, (0x7E1, 0x3)), + (0x0FA47, (0xA1C, 0x1)), + (0x2F99B, (0xCF7, 0x1)), + (0x004C1, (0x26A, 0x2)), + (0x01F49, (0x64E, 0x2)), + (0x2F8A9, (0xC05, 0x1)), + (0x01E32, (0x3C0, 0x2)), + (0x000F2, (0x054, 0x2)), + (0x0FA9A, (0xA6D, 0x1)), + (0x2F85B, (0xBB7, 0x1)), + (0x0F9CD, (0x9AE, 0x1)), + (0x030AE, (0x8A5, 0x2)), + (0x01F7B, (0x6BF, 0x2)), + (0x01E92, (0x496, 0x2)), + (0x2F8B2, (0xC0E, 0x1)), + (0x0F97E, (0x95F, 0x1)), + (0x01EB7, (0x4E9, 0x3)), + (0x0FA06, (0x9E7, 0x1)), + (0x01FCF, (0x7B2, 0x2)), + (0x2F8EA, (0xC46, 0x1)), + (0x2F97E, (0xCDA, 0x1)), + (0x2F8E2, (0xC3E, 0x1)), + (0x01F18, (0x5D4, 0x2)), + (0x0F98D, (0x96E, 0x1)), + (0x03056, (0x877, 0x2)), + (0x2F93A, (0xC96, 0x1)), + (0x0FACE, (0xAA1, 0x1)), + (0x01E8C, (0x48A, 0x2)), + (0x00158, (0x0F8, 0x2)), + (0x0FA55, (0xA2A, 0x1)), + (0x01FC4, (0x79C, 0x3)), + (0x115BA, (0xB19, 0x2)), + (0x0017E, (0x140, 0x2)), + (0x0010E, (0x086, 0x2)), + (0x0F950, (0x931, 0x1)), + (0x2F886, (0xBE2, 0x1)), + (0x01EF7, (0x592, 0x2)), + (0x2F9DC, (0xD38, 0x1)), + (0x009DF, (0x2DC, 0x2)), + (0x01F8A, (0x6E9, 0x4)), + (0x0FAC1, (0xA94, 0x1)), + (0x2F934, (0xC90, 0x1)), + (0x01EEC, (0x576, 0x3)), + (0x01EEF, (0x57F, 0x3)), + (0x01F41, (0x63E, 0x2)), + (0x0F943, (0x924, 0x1)), + (0x01EC7, (0x513, 0x3)), + (0x01F66, (0x68D, 0x3)), + (0x01F10, (0x5C4, 0x2)), + (0x2F8CF, (0xC2B, 0x1)), + (0x01FA0, (0x73D, 0x3)), + (0x2F909, (0xC65, 0x1)), + (0x00FAC, (0x336, 0x2)), + (0x004E5, (0x28C, 0x2)), + (0x2F991, (0xCED, 0x1)), + (0x0F958, (0x939, 0x1)), + (0x01FCA, (0x7A8, 0x2)), + (0x003CA, (0x238, 0x2)), + (0x2F817, (0xB73, 0x1)), + (0x00F4D, (0x31A, 0x2)), + (0x00143, (0x0D8, 0x2)), + (0x0013C, (0x0D2, 0x2)), + (0x001F9, (0x1A0, 0x2)), + (0x2F9D2, (0xD2E, 0x1)), + (0x2F866, (0xBC2, 0x1)), + (0x2F9D0, (0xD2C, 0x1)), + (0x01E01, (0x354, 0x2)), + (0x2F90D, (0xC69, 0x1)), + (0x0015A, (0x0FC, 0x2)), + (0x00125, (0x0B0, 0x2)), + (0x0F984, (0x965, 0x1)), + (0x0F91C, (0x8FD, 0x1)), + (0x0FA8C, (0xA5F, 0x1)), + (0x01E14, (0x37C, 0x3)), + (0x0226D, (0x833, 0x2)), + (0x0045C, (0x260, 0x2)), + (0x00102, (0x06E, 0x2)), + (0x0FAAF, (0xA82, 0x1)), + (0x2F836, (0xB92, 0x1)), + (0x006C0, (0x2B8, 0x2)), + (0x0F9FF, (0x9E0, 0x1)), + (0x0F97F, (0x960, 0x1)), + (0x2F8CA, (0xC26, 0x1)), + (0x2F92A, (0xC86, 0x1)), + (0x0012B, (0x0B8, 0x2)), + (0x0309E, (0x8A1, 0x2)), + (0x0FA4E, (0xA23, 0x1)), + (0x0FAC8, (0xA9B, 0x1)), + (0x01FDF, (0x7CF, 0x2)), + (0x2F96E, (0xCCA, 0x1)), + (0x00F9D, (0x330, 0x2)), + (0x2F802, (0xB5E, 0x1)), + (0x01E05, (0x35C, 0x2)), + (0x2F80D, (0xB69, 0x1)), + (0x2F941, (0xC9D, 0x1)), + (0x0021B, (0x1E6, 0x2)), + (0x2F82C, (0xB88, 0x1)), + (0x0FB46, (0xAE1, 0x2)), + (0x0F971, (0x952, 0x1)), + (0x0F9C3, (0x9A4, 0x1)), + (0x2F83C, (0xB98, 0x1)), + (0x2F81A, (0xB76, 0x1)), + (0x0F9BB, (0x99C, 0x1)), + (0x0FAAC, (0xA7F, 0x1)), + (0x01F5F, (0x67A, 0x3)), + (0x0FA6A, (0xA3F, 0x1)), + (0x2F8B3, (0xC0F, 0x1)), + (0x0F9C9, (0x9AA, 0x1)), + (0x0F9EE, (0x9CF, 0x1)), + (0x01E6B, (0x444, 0x2)), + (0x01E2C, (0x3B2, 0x2)), + (0x2F851, (0xBAD, 0x1)), + (0x2F812, (0xB6E, 0x1)), + (0x01F15, (0x5D1, 0x3)), + (0x0FA4A, (0xA1F, 0x1)), + (0x030DA, (0x8CF, 0x2)), + (0x01EC6, (0x510, 0x3)), + (0x00208, (0x1C0, 0x2)), + (0x0F90B, (0x8EC, 0x1)), + (0x01E00, (0x352, 0x2)), + (0x0FB40, (0xAD9, 0x2)), + (0x2F82D, (0xB89, 0x1)), + (0x001D9, (0x166, 0x3)), + (0x0FAA5, (0xA78, 0x1)), + (0x000F6, (0x05C, 0x2)), + (0x022E1, (0x85B, 0x2)), + (0x2F961, (0xCBD, 0x1)), + (0x021CF, (0x81B, 0x2)), + (0x0F9D8, (0x9B9, 0x1)), + (0x0FA3D, (0xA12, 0x1)), + (0x0FB2F, (0xABD, 0x2)), + (0x0FA85, (0xA58, 0x1)), + (0x0095C, (0x2CC, 0x2)), + (0x01FF7, (0x7FD, 0x3)), + (0x01EAE, (0x4CE, 0x3)), + (0x2F98E, (0xCEA, 0x1)), + (0x01F83, (0x6CF, 0x4)), + (0x030C5, (0x8BB, 0x2)), + (0x00403, (0x24A, 0x2)), + (0x00120, (0x0A6, 0x2)), + (0x004F2, (0x2A2, 0x2)), + (0x0F98F, (0x970, 0x1)), + (0x2F9B0, (0xD0C, 0x1)), + (0x01FF3, (0x7F6, 0x2)), + (0x00D4A, (0x309, 0x2)), + (0x0013A, (0x0CE, 0x2)), + (0x01E74, (0x456, 0x2)), + (0x2F831, (0xB8D, 0x1)), + (0x2F80B, (0xB67, 0x1)), + (0x2F8A3, (0xBFF, 0x1)), + (0x0F955, (0x936, 0x1)), + (0x2F89F, (0xBFB, 0x1)), + (0x0011B, (0x09C, 0x2)), + (0x0F93C, (0x91D, 0x1)), + (0x009DD, (0x2DA, 0x2)), + (0x2F9AC, (0xD08, 0x1)), + (0x0F933, (0x914, 0x1)), + (0x2F8C3, (0xC1F, 0x1)), + (0x16121, (0xB1F, 0x2)), + (0x2F82A, (0xB86, 0x1)), + (0x2F93E, (0xC9A, 0x1)), + (0x0022D, (0x1FD, 0x3)), + (0x01ED2, (0x52C, 0x3)), + (0x2F99D, (0xCF9, 0x1)), + (0x01F36, (0x620, 0x3)), + (0x2F9D7, (0xD33, 0x1)), + (0x01EAD, (0x4CB, 0x3)), + (0x2F914, (0xC70, 0x1)), + (0x01FE4, (0x7DB, 0x2)), + (0x00B5C, (0x2F0, 0x2)), + (0x01F95, (0x713, 0x4)), + (0x00959, (0x2C6, 0x2)), + (0x0F9C0, (0x9A1, 0x1)), + (0x01ED7, (0x53B, 0x3)), + (0x2F865, (0xBC1, 0x1)), + (0x2F801, (0xB5D, 0x1)), + (0x01E3E, (0x3DA, 0x2)), + (0x2F848, (0xBA4, 0x1)), + (0x2F8EF, (0xC4B, 0x1)), + (0x2F875, (0xBD1, 0x1)), + (0x01E04, (0x35A, 0x2)), + (0x0FA1C, (0x9F8, 0x1)), + (0x2F807, (0xB63, 0x1)), + (0x01ECF, (0x524, 0x2)), + (0x01ED1, (0x529, 0x3)), + (0x0F927, (0x908, 0x1)), + (0x2F8D4, (0xC30, 0x1)), + (0x0FA39, (0xA0E, 0x1)), + (0x2F989, (0xCE5, 0x1)), + (0x2FA0C, (0xD68, 0x1)), + (0x2F86A, (0xBC6, 0x1)), + (0x01EDC, (0x54A, 0x3)), + (0x0F917, (0x8F8, 0x1)), + (0x2F8A0, (0xBFC, 0x1)), + (0x2F897, (0xBF3, 0x1)), + (0x01E38, (0x3CC, 0x3)), + (0x000E2, (0x038, 0x2)), + (0x01FC9, (0x7A6, 0x2)), + (0x01F34, (0x61A, 0x3)), + (0x02289, (0x84F, 0x2)), + (0x2F9FA, (0xD56, 0x1)), + (0x02244, (0x829, 0x2)), + (0x0FAA6, (0xA79, 0x1)), + (0x2F846, (0xBA2, 0x1)), + (0x02126, (0x80D, 0x1)), + (0x0010B, (0x080, 0x2)), + (0x00145, (0x0DC, 0x2)), + (0x00130, (0x0C2, 0x2)), + (0x2F9E5, (0xD41, 0x1)), + (0x2F912, (0xC6E, 0x1)), + (0x0F9AE, (0x98F, 0x1)), + (0x2F957, (0xCB3, 0x1)), + (0x0F904, (0x8E5, 0x1)), + (0x01F98, (0x71F, 0x3)), + (0x0F93A, (0x91B, 0x1)), + (0x2F8AF, (0xC0B, 0x1)), + (0x2F879, (0xBD5, 0x1)), + (0x01FF4, (0x7F8, 0x3)), + (0x01E23, (0x3A0, 0x2)), + (0x00212, (0x1D4, 0x2)), + (0x030DD, (0x8D3, 0x2)), + (0x2F87B, (0xBD7, 0x1)), + (0x2F8EB, (0xC47, 0x1)), + (0x01EC2, (0x504, 0x3)), + (0x0219A, (0x811, 0x2)), + (0x000E1, (0x036, 0x2)), + (0x000D1, (0x01E, 0x2)), + (0x0F972, (0x953, 0x1)), +]; +pub(crate) const COMPATIBILITY_DECOMPOSED_CHARS: &[char] = &[ + '\u{0020}', + '\u{0020}', + '\u{0308}', + '\u{0061}', + '\u{0020}', + '\u{0304}', + '\u{0032}', + '\u{0033}', + '\u{0020}', + '\u{0301}', + '\u{03BC}', + '\u{0020}', + '\u{0327}', + '\u{0031}', + '\u{006F}', + '\u{0031}', + '\u{2044}', + '\u{0034}', + '\u{0031}', + '\u{2044}', + '\u{0032}', + '\u{0033}', + '\u{2044}', + '\u{0034}', + '\u{0049}', + '\u{004A}', + '\u{0069}', + '\u{006A}', + '\u{004C}', + '\u{00B7}', + '\u{006C}', + '\u{00B7}', + '\u{02BC}', + '\u{006E}', + '\u{0073}', + '\u{0044}', + '\u{005A}', + '\u{030C}', + '\u{0044}', + '\u{007A}', + '\u{030C}', + '\u{0064}', + '\u{007A}', + '\u{030C}', + '\u{004C}', + '\u{004A}', + '\u{004C}', + '\u{006A}', + '\u{006C}', + '\u{006A}', + '\u{004E}', + '\u{004A}', + '\u{004E}', + '\u{006A}', + '\u{006E}', + '\u{006A}', + '\u{0044}', + '\u{005A}', + '\u{0044}', + '\u{007A}', + '\u{0064}', + '\u{007A}', + '\u{0068}', + '\u{0266}', + '\u{006A}', + '\u{0072}', + '\u{0279}', + '\u{027B}', + '\u{0281}', + '\u{0077}', + '\u{0079}', + '\u{0020}', + '\u{0306}', + '\u{0020}', + '\u{0307}', + '\u{0020}', + '\u{030A}', + '\u{0020}', + '\u{0328}', + '\u{0020}', + '\u{0303}', + '\u{0020}', + '\u{030B}', + '\u{0263}', + '\u{006C}', + '\u{0073}', + '\u{0078}', + '\u{0295}', + '\u{0020}', + '\u{0345}', + '\u{0020}', + '\u{0301}', + '\u{0020}', + '\u{0308}', + '\u{0301}', + '\u{03B2}', + '\u{03B8}', + '\u{03A5}', + '\u{03A5}', + '\u{0301}', + '\u{03A5}', + '\u{0308}', + '\u{03C6}', + '\u{03C0}', + '\u{03BA}', + '\u{03C1}', + '\u{03C2}', + '\u{0398}', + '\u{03B5}', + '\u{03A3}', + '\u{0565}', + '\u{0582}', + '\u{0627}', + '\u{0674}', + '\u{0648}', + '\u{0674}', + '\u{06C7}', + '\u{0674}', + '\u{064A}', + '\u{0674}', + '\u{0E4D}', + '\u{0E32}', + '\u{0ECD}', + '\u{0EB2}', + '\u{0EAB}', + '\u{0E99}', + '\u{0EAB}', + '\u{0EA1}', + '\u{0F0B}', + '\u{0FB2}', + '\u{0F71}', + '\u{0F80}', + '\u{0FB3}', + '\u{0F71}', + '\u{0F80}', + '\u{10DC}', + '\u{0041}', + '\u{00C6}', + '\u{0042}', + '\u{0044}', + '\u{0045}', + '\u{018E}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0222}', + '\u{0050}', + '\u{0052}', + '\u{0054}', + '\u{0055}', + '\u{0057}', + '\u{0061}', + '\u{0250}', + '\u{0251}', + '\u{1D02}', + '\u{0062}', + '\u{0064}', + '\u{0065}', + '\u{0259}', + '\u{025B}', + '\u{025C}', + '\u{0067}', + '\u{006B}', + '\u{006D}', + '\u{014B}', + '\u{006F}', + '\u{0254}', + '\u{1D16}', + '\u{1D17}', + '\u{0070}', + '\u{0074}', + '\u{0075}', + '\u{1D1D}', + '\u{026F}', + '\u{0076}', + '\u{1D25}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03C6}', + '\u{03C7}', + '\u{0069}', + '\u{0072}', + '\u{0075}', + '\u{0076}', + '\u{03B2}', + '\u{03B3}', + '\u{03C1}', + '\u{03C6}', + '\u{03C7}', + '\u{043D}', + '\u{0252}', + '\u{0063}', + '\u{0255}', + '\u{00F0}', + '\u{025C}', + '\u{0066}', + '\u{025F}', + '\u{0261}', + '\u{0265}', + '\u{0268}', + '\u{0269}', + '\u{026A}', + '\u{1D7B}', + '\u{029D}', + '\u{026D}', + '\u{1D85}', + '\u{029F}', + '\u{0271}', + '\u{0270}', + '\u{0272}', + '\u{0273}', + '\u{0274}', + '\u{0275}', + '\u{0278}', + '\u{0282}', + '\u{0283}', + '\u{01AB}', + '\u{0289}', + '\u{028A}', + '\u{1D1C}', + '\u{028B}', + '\u{028C}', + '\u{007A}', + '\u{0290}', + '\u{0291}', + '\u{0292}', + '\u{03B8}', + '\u{0061}', + '\u{02BE}', + '\u{0073}', + '\u{0307}', + '\u{0020}', + '\u{0313}', + '\u{0020}', + '\u{0313}', + '\u{0020}', + '\u{0342}', + '\u{0020}', + '\u{0308}', + '\u{0342}', + '\u{0020}', + '\u{0313}', + '\u{0300}', + '\u{0020}', + '\u{0313}', + '\u{0301}', + '\u{0020}', + '\u{0313}', + '\u{0342}', + '\u{0020}', + '\u{0314}', + '\u{0300}', + '\u{0020}', + '\u{0314}', + '\u{0301}', + '\u{0020}', + '\u{0314}', + '\u{0342}', + '\u{0020}', + '\u{0308}', + '\u{0300}', + '\u{0020}', + '\u{0308}', + '\u{0301}', + '\u{0020}', + '\u{0301}', + '\u{0020}', + '\u{0314}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{0020}', + '\u{2010}', + '\u{0020}', + '\u{0333}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{0020}', + '\u{2032}', + '\u{2032}', + '\u{2032}', + '\u{2032}', + '\u{2032}', + '\u{2035}', + '\u{2035}', + '\u{2035}', + '\u{2035}', + '\u{2035}', + '\u{0021}', + '\u{0021}', + '\u{0020}', + '\u{0305}', + '\u{003F}', + '\u{003F}', + '\u{003F}', + '\u{0021}', + '\u{0021}', + '\u{003F}', + '\u{2032}', + '\u{2032}', + '\u{2032}', + '\u{2032}', + '\u{0020}', + '\u{0030}', + '\u{0069}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{002B}', + '\u{2212}', + '\u{003D}', + '\u{0028}', + '\u{0029}', + '\u{006E}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{002B}', + '\u{2212}', + '\u{003D}', + '\u{0028}', + '\u{0029}', + '\u{0061}', + '\u{0065}', + '\u{006F}', + '\u{0078}', + '\u{0259}', + '\u{0068}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{0070}', + '\u{0073}', + '\u{0074}', + '\u{0052}', + '\u{0073}', + '\u{0061}', + '\u{002F}', + '\u{0063}', + '\u{0061}', + '\u{002F}', + '\u{0073}', + '\u{0043}', + '\u{00B0}', + '\u{0043}', + '\u{0063}', + '\u{002F}', + '\u{006F}', + '\u{0063}', + '\u{002F}', + '\u{0075}', + '\u{0190}', + '\u{00B0}', + '\u{0046}', + '\u{0067}', + '\u{0048}', + '\u{0048}', + '\u{0048}', + '\u{0068}', + '\u{0127}', + '\u{0049}', + '\u{0049}', + '\u{004C}', + '\u{006C}', + '\u{004E}', + '\u{004E}', + '\u{006F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0052}', + '\u{0052}', + '\u{0053}', + '\u{004D}', + '\u{0054}', + '\u{0045}', + '\u{004C}', + '\u{0054}', + '\u{004D}', + '\u{005A}', + '\u{005A}', + '\u{0042}', + '\u{0043}', + '\u{0065}', + '\u{0045}', + '\u{0046}', + '\u{004D}', + '\u{006F}', + '\u{05D0}', + '\u{05D1}', + '\u{05D2}', + '\u{05D3}', + '\u{0069}', + '\u{0046}', + '\u{0041}', + '\u{0058}', + '\u{03C0}', + '\u{03B3}', + '\u{0393}', + '\u{03A0}', + '\u{2211}', + '\u{0044}', + '\u{0064}', + '\u{0065}', + '\u{0069}', + '\u{006A}', + '\u{0031}', + '\u{2044}', + '\u{0037}', + '\u{0031}', + '\u{2044}', + '\u{0039}', + '\u{0031}', + '\u{2044}', + '\u{0031}', + '\u{0030}', + '\u{0031}', + '\u{2044}', + '\u{0033}', + '\u{0032}', + '\u{2044}', + '\u{0033}', + '\u{0031}', + '\u{2044}', + '\u{0035}', + '\u{0032}', + '\u{2044}', + '\u{0035}', + '\u{0033}', + '\u{2044}', + '\u{0035}', + '\u{0034}', + '\u{2044}', + '\u{0035}', + '\u{0031}', + '\u{2044}', + '\u{0036}', + '\u{0035}', + '\u{2044}', + '\u{0036}', + '\u{0031}', + '\u{2044}', + '\u{0038}', + '\u{0033}', + '\u{2044}', + '\u{0038}', + '\u{0035}', + '\u{2044}', + '\u{0038}', + '\u{0037}', + '\u{2044}', + '\u{0038}', + '\u{0031}', + '\u{2044}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0056}', + '\u{0056}', + '\u{0056}', + '\u{0049}', + '\u{0056}', + '\u{0049}', + '\u{0049}', + '\u{0056}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0049}', + '\u{0058}', + '\u{0058}', + '\u{0058}', + '\u{0049}', + '\u{0058}', + '\u{0049}', + '\u{0049}', + '\u{004C}', + '\u{0043}', + '\u{0044}', + '\u{004D}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0076}', + '\u{0076}', + '\u{0076}', + '\u{0069}', + '\u{0076}', + '\u{0069}', + '\u{0069}', + '\u{0076}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0069}', + '\u{0078}', + '\u{0078}', + '\u{0078}', + '\u{0069}', + '\u{0078}', + '\u{0069}', + '\u{0069}', + '\u{006C}', + '\u{0063}', + '\u{0064}', + '\u{006D}', + '\u{0030}', + '\u{2044}', + '\u{0033}', + '\u{222B}', + '\u{222B}', + '\u{222B}', + '\u{222B}', + '\u{222B}', + '\u{222E}', + '\u{222E}', + '\u{222E}', + '\u{222E}', + '\u{222E}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0031}', + '\u{0030}', + '\u{0031}', + '\u{0031}', + '\u{0031}', + '\u{0032}', + '\u{0031}', + '\u{0033}', + '\u{0031}', + '\u{0034}', + '\u{0031}', + '\u{0035}', + '\u{0031}', + '\u{0036}', + '\u{0031}', + '\u{0037}', + '\u{0031}', + '\u{0038}', + '\u{0031}', + '\u{0039}', + '\u{0032}', + '\u{0030}', + '\u{0028}', + '\u{0031}', + '\u{0029}', + '\u{0028}', + '\u{0032}', + '\u{0029}', + '\u{0028}', + '\u{0033}', + '\u{0029}', + '\u{0028}', + '\u{0034}', + '\u{0029}', + '\u{0028}', + '\u{0035}', + '\u{0029}', + '\u{0028}', + '\u{0036}', + '\u{0029}', + '\u{0028}', + '\u{0037}', + '\u{0029}', + '\u{0028}', + '\u{0038}', + '\u{0029}', + '\u{0028}', + '\u{0039}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0030}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0031}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0032}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0033}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0034}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0035}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0036}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0037}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0038}', + '\u{0029}', + '\u{0028}', + '\u{0031}', + '\u{0039}', + '\u{0029}', + '\u{0028}', + '\u{0032}', + '\u{0030}', + '\u{0029}', + '\u{0031}', + '\u{002E}', + '\u{0032}', + '\u{002E}', + '\u{0033}', + '\u{002E}', + '\u{0034}', + '\u{002E}', + '\u{0035}', + '\u{002E}', + '\u{0036}', + '\u{002E}', + '\u{0037}', + '\u{002E}', + '\u{0038}', + '\u{002E}', + '\u{0039}', + '\u{002E}', + '\u{0031}', + '\u{0030}', + '\u{002E}', + '\u{0031}', + '\u{0031}', + '\u{002E}', + '\u{0031}', + '\u{0032}', + '\u{002E}', + '\u{0031}', + '\u{0033}', + '\u{002E}', + '\u{0031}', + '\u{0034}', + '\u{002E}', + '\u{0031}', + '\u{0035}', + '\u{002E}', + '\u{0031}', + '\u{0036}', + '\u{002E}', + '\u{0031}', + '\u{0037}', + '\u{002E}', + '\u{0031}', + '\u{0038}', + '\u{002E}', + '\u{0031}', + '\u{0039}', + '\u{002E}', + '\u{0032}', + '\u{0030}', + '\u{002E}', + '\u{0028}', + '\u{0061}', + '\u{0029}', + '\u{0028}', + '\u{0062}', + '\u{0029}', + '\u{0028}', + '\u{0063}', + '\u{0029}', + '\u{0028}', + '\u{0064}', + '\u{0029}', + '\u{0028}', + '\u{0065}', + '\u{0029}', + '\u{0028}', + '\u{0066}', + '\u{0029}', + '\u{0028}', + '\u{0067}', + '\u{0029}', + '\u{0028}', + '\u{0068}', + '\u{0029}', + '\u{0028}', + '\u{0069}', + '\u{0029}', + '\u{0028}', + '\u{006A}', + '\u{0029}', + '\u{0028}', + '\u{006B}', + '\u{0029}', + '\u{0028}', + '\u{006C}', + '\u{0029}', + '\u{0028}', + '\u{006D}', + '\u{0029}', + '\u{0028}', + '\u{006E}', + '\u{0029}', + '\u{0028}', + '\u{006F}', + '\u{0029}', + '\u{0028}', + '\u{0070}', + '\u{0029}', + '\u{0028}', + '\u{0071}', + '\u{0029}', + '\u{0028}', + '\u{0072}', + '\u{0029}', + '\u{0028}', + '\u{0073}', + '\u{0029}', + '\u{0028}', + '\u{0074}', + '\u{0029}', + '\u{0028}', + '\u{0075}', + '\u{0029}', + '\u{0028}', + '\u{0076}', + '\u{0029}', + '\u{0028}', + '\u{0077}', + '\u{0029}', + '\u{0028}', + '\u{0078}', + '\u{0029}', + '\u{0028}', + '\u{0079}', + '\u{0029}', + '\u{0028}', + '\u{007A}', + '\u{0029}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0030}', + '\u{222B}', + '\u{222B}', + '\u{222B}', + '\u{222B}', + '\u{003A}', + '\u{003A}', + '\u{003D}', + '\u{003D}', + '\u{003D}', + '\u{003D}', + '\u{003D}', + '\u{003D}', + '\u{006A}', + '\u{0056}', + '\u{2D61}', + '\u{6BCD}', + '\u{9F9F}', + '\u{4E00}', + '\u{4E28}', + '\u{4E36}', + '\u{4E3F}', + '\u{4E59}', + '\u{4E85}', + '\u{4E8C}', + '\u{4EA0}', + '\u{4EBA}', + '\u{513F}', + '\u{5165}', + '\u{516B}', + '\u{5182}', + '\u{5196}', + '\u{51AB}', + '\u{51E0}', + '\u{51F5}', + '\u{5200}', + '\u{529B}', + '\u{52F9}', + '\u{5315}', + '\u{531A}', + '\u{5338}', + '\u{5341}', + '\u{535C}', + '\u{5369}', + '\u{5382}', + '\u{53B6}', + '\u{53C8}', + '\u{53E3}', + '\u{56D7}', + '\u{571F}', + '\u{58EB}', + '\u{5902}', + '\u{590A}', + '\u{5915}', + '\u{5927}', + '\u{5973}', + '\u{5B50}', + '\u{5B80}', + '\u{5BF8}', + '\u{5C0F}', + '\u{5C22}', + '\u{5C38}', + '\u{5C6E}', + '\u{5C71}', + '\u{5DDB}', + '\u{5DE5}', + '\u{5DF1}', + '\u{5DFE}', + '\u{5E72}', + '\u{5E7A}', + '\u{5E7F}', + '\u{5EF4}', + '\u{5EFE}', + '\u{5F0B}', + '\u{5F13}', + '\u{5F50}', + '\u{5F61}', + '\u{5F73}', + '\u{5FC3}', + '\u{6208}', + '\u{6236}', + '\u{624B}', + '\u{652F}', + '\u{6534}', + '\u{6587}', + '\u{6597}', + '\u{65A4}', + '\u{65B9}', + '\u{65E0}', + '\u{65E5}', + '\u{66F0}', + '\u{6708}', + '\u{6728}', + '\u{6B20}', + '\u{6B62}', + '\u{6B79}', + '\u{6BB3}', + '\u{6BCB}', + '\u{6BD4}', + '\u{6BDB}', + '\u{6C0F}', + '\u{6C14}', + '\u{6C34}', + '\u{706B}', + '\u{722A}', + '\u{7236}', + '\u{723B}', + '\u{723F}', + '\u{7247}', + '\u{7259}', + '\u{725B}', + '\u{72AC}', + '\u{7384}', + '\u{7389}', + '\u{74DC}', + '\u{74E6}', + '\u{7518}', + '\u{751F}', + '\u{7528}', + '\u{7530}', + '\u{758B}', + '\u{7592}', + '\u{7676}', + '\u{767D}', + '\u{76AE}', + '\u{76BF}', + '\u{76EE}', + '\u{77DB}', + '\u{77E2}', + '\u{77F3}', + '\u{793A}', + '\u{79B8}', + '\u{79BE}', + '\u{7A74}', + '\u{7ACB}', + '\u{7AF9}', + '\u{7C73}', + '\u{7CF8}', + '\u{7F36}', + '\u{7F51}', + '\u{7F8A}', + '\u{7FBD}', + '\u{8001}', + '\u{800C}', + '\u{8012}', + '\u{8033}', + '\u{807F}', + '\u{8089}', + '\u{81E3}', + '\u{81EA}', + '\u{81F3}', + '\u{81FC}', + '\u{820C}', + '\u{821B}', + '\u{821F}', + '\u{826E}', + '\u{8272}', + '\u{8278}', + '\u{864D}', + '\u{866B}', + '\u{8840}', + '\u{884C}', + '\u{8863}', + '\u{897E}', + '\u{898B}', + '\u{89D2}', + '\u{8A00}', + '\u{8C37}', + '\u{8C46}', + '\u{8C55}', + '\u{8C78}', + '\u{8C9D}', + '\u{8D64}', + '\u{8D70}', + '\u{8DB3}', + '\u{8EAB}', + '\u{8ECA}', + '\u{8F9B}', + '\u{8FB0}', + '\u{8FB5}', + '\u{9091}', + '\u{9149}', + '\u{91C6}', + '\u{91CC}', + '\u{91D1}', + '\u{9577}', + '\u{9580}', + '\u{961C}', + '\u{96B6}', + '\u{96B9}', + '\u{96E8}', + '\u{9751}', + '\u{975E}', + '\u{9762}', + '\u{9769}', + '\u{97CB}', + '\u{97ED}', + '\u{97F3}', + '\u{9801}', + '\u{98A8}', + '\u{98DB}', + '\u{98DF}', + '\u{9996}', + '\u{9999}', + '\u{99AC}', + '\u{9AA8}', + '\u{9AD8}', + '\u{9ADF}', + '\u{9B25}', + '\u{9B2F}', + '\u{9B32}', + '\u{9B3C}', + '\u{9B5A}', + '\u{9CE5}', + '\u{9E75}', + '\u{9E7F}', + '\u{9EA5}', + '\u{9EBB}', + '\u{9EC3}', + '\u{9ECD}', + '\u{9ED1}', + '\u{9EF9}', + '\u{9EFD}', + '\u{9F0E}', + '\u{9F13}', + '\u{9F20}', + '\u{9F3B}', + '\u{9F4A}', + '\u{9F52}', + '\u{9F8D}', + '\u{9F9C}', + '\u{9FA0}', + '\u{0020}', + '\u{3012}', + '\u{5341}', + '\u{5344}', + '\u{5345}', + '\u{0020}', + '\u{3099}', + '\u{0020}', + '\u{309A}', + '\u{3088}', + '\u{308A}', + '\u{30B3}', + '\u{30C8}', + '\u{1100}', + '\u{1101}', + '\u{11AA}', + '\u{1102}', + '\u{11AC}', + '\u{11AD}', + '\u{1103}', + '\u{1104}', + '\u{1105}', + '\u{11B0}', + '\u{11B1}', + '\u{11B2}', + '\u{11B3}', + '\u{11B4}', + '\u{11B5}', + '\u{111A}', + '\u{1106}', + '\u{1107}', + '\u{1108}', + '\u{1121}', + '\u{1109}', + '\u{110A}', + '\u{110B}', + '\u{110C}', + '\u{110D}', + '\u{110E}', + '\u{110F}', + '\u{1110}', + '\u{1111}', + '\u{1112}', + '\u{1161}', + '\u{1162}', + '\u{1163}', + '\u{1164}', + '\u{1165}', + '\u{1166}', + '\u{1167}', + '\u{1168}', + '\u{1169}', + '\u{116A}', + '\u{116B}', + '\u{116C}', + '\u{116D}', + '\u{116E}', + '\u{116F}', + '\u{1170}', + '\u{1171}', + '\u{1172}', + '\u{1173}', + '\u{1174}', + '\u{1175}', + '\u{1160}', + '\u{1114}', + '\u{1115}', + '\u{11C7}', + '\u{11C8}', + '\u{11CC}', + '\u{11CE}', + '\u{11D3}', + '\u{11D7}', + '\u{11D9}', + '\u{111C}', + '\u{11DD}', + '\u{11DF}', + '\u{111D}', + '\u{111E}', + '\u{1120}', + '\u{1122}', + '\u{1123}', + '\u{1127}', + '\u{1129}', + '\u{112B}', + '\u{112C}', + '\u{112D}', + '\u{112E}', + '\u{112F}', + '\u{1132}', + '\u{1136}', + '\u{1140}', + '\u{1147}', + '\u{114C}', + '\u{11F1}', + '\u{11F2}', + '\u{1157}', + '\u{1158}', + '\u{1159}', + '\u{1184}', + '\u{1185}', + '\u{1188}', + '\u{1191}', + '\u{1192}', + '\u{1194}', + '\u{119E}', + '\u{11A1}', + '\u{4E00}', + '\u{4E8C}', + '\u{4E09}', + '\u{56DB}', + '\u{4E0A}', + '\u{4E2D}', + '\u{4E0B}', + '\u{7532}', + '\u{4E59}', + '\u{4E19}', + '\u{4E01}', + '\u{5929}', + '\u{5730}', + '\u{4EBA}', + '\u{0028}', + '\u{1100}', + '\u{0029}', + '\u{0028}', + '\u{1102}', + '\u{0029}', + '\u{0028}', + '\u{1103}', + '\u{0029}', + '\u{0028}', + '\u{1105}', + '\u{0029}', + '\u{0028}', + '\u{1106}', + '\u{0029}', + '\u{0028}', + '\u{1107}', + '\u{0029}', + '\u{0028}', + '\u{1109}', + '\u{0029}', + '\u{0028}', + '\u{110B}', + '\u{0029}', + '\u{0028}', + '\u{110C}', + '\u{0029}', + '\u{0028}', + '\u{110E}', + '\u{0029}', + '\u{0028}', + '\u{110F}', + '\u{0029}', + '\u{0028}', + '\u{1110}', + '\u{0029}', + '\u{0028}', + '\u{1111}', + '\u{0029}', + '\u{0028}', + '\u{1112}', + '\u{0029}', + '\u{0028}', + '\u{1100}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1102}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1103}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1105}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1106}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1107}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1109}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{110B}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{110C}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{110E}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{110F}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1110}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1111}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{1112}', + '\u{1161}', + '\u{0029}', + '\u{0028}', + '\u{110C}', + '\u{116E}', + '\u{0029}', + '\u{0028}', + '\u{110B}', + '\u{1169}', + '\u{110C}', + '\u{1165}', + '\u{11AB}', + '\u{0029}', + '\u{0028}', + '\u{110B}', + '\u{1169}', + '\u{1112}', + '\u{116E}', + '\u{0029}', + '\u{0028}', + '\u{4E00}', + '\u{0029}', + '\u{0028}', + '\u{4E8C}', + '\u{0029}', + '\u{0028}', + '\u{4E09}', + '\u{0029}', + '\u{0028}', + '\u{56DB}', + '\u{0029}', + '\u{0028}', + '\u{4E94}', + '\u{0029}', + '\u{0028}', + '\u{516D}', + '\u{0029}', + '\u{0028}', + '\u{4E03}', + '\u{0029}', + '\u{0028}', + '\u{516B}', + '\u{0029}', + '\u{0028}', + '\u{4E5D}', + '\u{0029}', + '\u{0028}', + '\u{5341}', + '\u{0029}', + '\u{0028}', + '\u{6708}', + '\u{0029}', + '\u{0028}', + '\u{706B}', + '\u{0029}', + '\u{0028}', + '\u{6C34}', + '\u{0029}', + '\u{0028}', + '\u{6728}', + '\u{0029}', + '\u{0028}', + '\u{91D1}', + '\u{0029}', + '\u{0028}', + '\u{571F}', + '\u{0029}', + '\u{0028}', + '\u{65E5}', + '\u{0029}', + '\u{0028}', + '\u{682A}', + '\u{0029}', + '\u{0028}', + '\u{6709}', + '\u{0029}', + '\u{0028}', + '\u{793E}', + '\u{0029}', + '\u{0028}', + '\u{540D}', + '\u{0029}', + '\u{0028}', + '\u{7279}', + '\u{0029}', + '\u{0028}', + '\u{8CA1}', + '\u{0029}', + '\u{0028}', + '\u{795D}', + '\u{0029}', + '\u{0028}', + '\u{52B4}', + '\u{0029}', + '\u{0028}', + '\u{4EE3}', + '\u{0029}', + '\u{0028}', + '\u{547C}', + '\u{0029}', + '\u{0028}', + '\u{5B66}', + '\u{0029}', + '\u{0028}', + '\u{76E3}', + '\u{0029}', + '\u{0028}', + '\u{4F01}', + '\u{0029}', + '\u{0028}', + '\u{8CC7}', + '\u{0029}', + '\u{0028}', + '\u{5354}', + '\u{0029}', + '\u{0028}', + '\u{796D}', + '\u{0029}', + '\u{0028}', + '\u{4F11}', + '\u{0029}', + '\u{0028}', + '\u{81EA}', + '\u{0029}', + '\u{0028}', + '\u{81F3}', + '\u{0029}', + '\u{554F}', + '\u{5E7C}', + '\u{6587}', + '\u{7B8F}', + '\u{0050}', + '\u{0054}', + '\u{0045}', + '\u{0032}', + '\u{0031}', + '\u{0032}', + '\u{0032}', + '\u{0032}', + '\u{0033}', + '\u{0032}', + '\u{0034}', + '\u{0032}', + '\u{0035}', + '\u{0032}', + '\u{0036}', + '\u{0032}', + '\u{0037}', + '\u{0032}', + '\u{0038}', + '\u{0032}', + '\u{0039}', + '\u{0033}', + '\u{0030}', + '\u{0033}', + '\u{0031}', + '\u{0033}', + '\u{0032}', + '\u{0033}', + '\u{0033}', + '\u{0033}', + '\u{0034}', + '\u{0033}', + '\u{0035}', + '\u{1100}', + '\u{1102}', + '\u{1103}', + '\u{1105}', + '\u{1106}', + '\u{1107}', + '\u{1109}', + '\u{110B}', + '\u{110C}', + '\u{110E}', + '\u{110F}', + '\u{1110}', + '\u{1111}', + '\u{1112}', + '\u{1100}', + '\u{1161}', + '\u{1102}', + '\u{1161}', + '\u{1103}', + '\u{1161}', + '\u{1105}', + '\u{1161}', + '\u{1106}', + '\u{1161}', + '\u{1107}', + '\u{1161}', + '\u{1109}', + '\u{1161}', + '\u{110B}', + '\u{1161}', + '\u{110C}', + '\u{1161}', + '\u{110E}', + '\u{1161}', + '\u{110F}', + '\u{1161}', + '\u{1110}', + '\u{1161}', + '\u{1111}', + '\u{1161}', + '\u{1112}', + '\u{1161}', + '\u{110E}', + '\u{1161}', + '\u{11B7}', + '\u{1100}', + '\u{1169}', + '\u{110C}', + '\u{116E}', + '\u{110B}', + '\u{1174}', + '\u{110B}', + '\u{116E}', + '\u{4E00}', + '\u{4E8C}', + '\u{4E09}', + '\u{56DB}', + '\u{4E94}', + '\u{516D}', + '\u{4E03}', + '\u{516B}', + '\u{4E5D}', + '\u{5341}', + '\u{6708}', + '\u{706B}', + '\u{6C34}', + '\u{6728}', + '\u{91D1}', + '\u{571F}', + '\u{65E5}', + '\u{682A}', + '\u{6709}', + '\u{793E}', + '\u{540D}', + '\u{7279}', + '\u{8CA1}', + '\u{795D}', + '\u{52B4}', + '\u{79D8}', + '\u{7537}', + '\u{5973}', + '\u{9069}', + '\u{512A}', + '\u{5370}', + '\u{6CE8}', + '\u{9805}', + '\u{4F11}', + '\u{5199}', + '\u{6B63}', + '\u{4E0A}', + '\u{4E2D}', + '\u{4E0B}', + '\u{5DE6}', + '\u{53F3}', + '\u{533B}', + '\u{5B97}', + '\u{5B66}', + '\u{76E3}', + '\u{4F01}', + '\u{8CC7}', + '\u{5354}', + '\u{591C}', + '\u{0033}', + '\u{0036}', + '\u{0033}', + '\u{0037}', + '\u{0033}', + '\u{0038}', + '\u{0033}', + '\u{0039}', + '\u{0034}', + '\u{0030}', + '\u{0034}', + '\u{0031}', + '\u{0034}', + '\u{0032}', + '\u{0034}', + '\u{0033}', + '\u{0034}', + '\u{0034}', + '\u{0034}', + '\u{0035}', + '\u{0034}', + '\u{0036}', + '\u{0034}', + '\u{0037}', + '\u{0034}', + '\u{0038}', + '\u{0034}', + '\u{0039}', + '\u{0035}', + '\u{0030}', + '\u{0031}', + '\u{6708}', + '\u{0032}', + '\u{6708}', + '\u{0033}', + '\u{6708}', + '\u{0034}', + '\u{6708}', + '\u{0035}', + '\u{6708}', + '\u{0036}', + '\u{6708}', + '\u{0037}', + '\u{6708}', + '\u{0038}', + '\u{6708}', + '\u{0039}', + '\u{6708}', + '\u{0031}', + '\u{0030}', + '\u{6708}', + '\u{0031}', + '\u{0031}', + '\u{6708}', + '\u{0031}', + '\u{0032}', + '\u{6708}', + '\u{0048}', + '\u{0067}', + '\u{0065}', + '\u{0072}', + '\u{0067}', + '\u{0065}', + '\u{0056}', + '\u{004C}', + '\u{0054}', + '\u{0044}', + '\u{30A2}', + '\u{30A4}', + '\u{30A6}', + '\u{30A8}', + '\u{30AA}', + '\u{30AB}', + '\u{30AD}', + '\u{30AF}', + '\u{30B1}', + '\u{30B3}', + '\u{30B5}', + '\u{30B7}', + '\u{30B9}', + '\u{30BB}', + '\u{30BD}', + '\u{30BF}', + '\u{30C1}', + '\u{30C4}', + '\u{30C6}', + '\u{30C8}', + '\u{30CA}', + '\u{30CB}', + '\u{30CC}', + '\u{30CD}', + '\u{30CE}', + '\u{30CF}', + '\u{30D2}', + '\u{30D5}', + '\u{30D8}', + '\u{30DB}', + '\u{30DE}', + '\u{30DF}', + '\u{30E0}', + '\u{30E1}', + '\u{30E2}', + '\u{30E4}', + '\u{30E6}', + '\u{30E8}', + '\u{30E9}', + '\u{30EA}', + '\u{30EB}', + '\u{30EC}', + '\u{30ED}', + '\u{30EF}', + '\u{30F0}', + '\u{30F1}', + '\u{30F2}', + '\u{4EE4}', + '\u{548C}', + '\u{30A2}', + '\u{30CF}', + '\u{309A}', + '\u{30FC}', + '\u{30C8}', + '\u{30A2}', + '\u{30EB}', + '\u{30D5}', + '\u{30A1}', + '\u{30A2}', + '\u{30F3}', + '\u{30D8}', + '\u{309A}', + '\u{30A2}', + '\u{30A2}', + '\u{30FC}', + '\u{30EB}', + '\u{30A4}', + '\u{30CB}', + '\u{30F3}', + '\u{30AF}', + '\u{3099}', + '\u{30A4}', + '\u{30F3}', + '\u{30C1}', + '\u{30A6}', + '\u{30A9}', + '\u{30F3}', + '\u{30A8}', + '\u{30B9}', + '\u{30AF}', + '\u{30FC}', + '\u{30C8}', + '\u{3099}', + '\u{30A8}', + '\u{30FC}', + '\u{30AB}', + '\u{30FC}', + '\u{30AA}', + '\u{30F3}', + '\u{30B9}', + '\u{30AA}', + '\u{30FC}', + '\u{30E0}', + '\u{30AB}', + '\u{30A4}', + '\u{30EA}', + '\u{30AB}', + '\u{30E9}', + '\u{30C3}', + '\u{30C8}', + '\u{30AB}', + '\u{30ED}', + '\u{30EA}', + '\u{30FC}', + '\u{30AB}', + '\u{3099}', + '\u{30ED}', + '\u{30F3}', + '\u{30AB}', + '\u{3099}', + '\u{30F3}', + '\u{30DE}', + '\u{30AD}', + '\u{3099}', + '\u{30AB}', + '\u{3099}', + '\u{30AD}', + '\u{3099}', + '\u{30CB}', + '\u{30FC}', + '\u{30AD}', + '\u{30E5}', + '\u{30EA}', + '\u{30FC}', + '\u{30AD}', + '\u{3099}', + '\u{30EB}', + '\u{30BF}', + '\u{3099}', + '\u{30FC}', + '\u{30AD}', + '\u{30ED}', + '\u{30AD}', + '\u{30ED}', + '\u{30AF}', + '\u{3099}', + '\u{30E9}', + '\u{30E0}', + '\u{30AD}', + '\u{30ED}', + '\u{30E1}', + '\u{30FC}', + '\u{30C8}', + '\u{30EB}', + '\u{30AD}', + '\u{30ED}', + '\u{30EF}', + '\u{30C3}', + '\u{30C8}', + '\u{30AF}', + '\u{3099}', + '\u{30E9}', + '\u{30E0}', + '\u{30AF}', + '\u{3099}', + '\u{30E9}', + '\u{30E0}', + '\u{30C8}', + '\u{30F3}', + '\u{30AF}', + '\u{30EB}', + '\u{30BB}', + '\u{3099}', + '\u{30A4}', + '\u{30ED}', + '\u{30AF}', + '\u{30ED}', + '\u{30FC}', + '\u{30CD}', + '\u{30B1}', + '\u{30FC}', + '\u{30B9}', + '\u{30B3}', + '\u{30EB}', + '\u{30CA}', + '\u{30B3}', + '\u{30FC}', + '\u{30DB}', + '\u{309A}', + '\u{30B5}', + '\u{30A4}', + '\u{30AF}', + '\u{30EB}', + '\u{30B5}', + '\u{30F3}', + '\u{30C1}', + '\u{30FC}', + '\u{30E0}', + '\u{30B7}', + '\u{30EA}', + '\u{30F3}', + '\u{30AF}', + '\u{3099}', + '\u{30BB}', + '\u{30F3}', + '\u{30C1}', + '\u{30BB}', + '\u{30F3}', + '\u{30C8}', + '\u{30BF}', + '\u{3099}', + '\u{30FC}', + '\u{30B9}', + '\u{30C6}', + '\u{3099}', + '\u{30B7}', + '\u{30C8}', + '\u{3099}', + '\u{30EB}', + '\u{30C8}', + '\u{30F3}', + '\u{30CA}', + '\u{30CE}', + '\u{30CE}', + '\u{30C3}', + '\u{30C8}', + '\u{30CF}', + '\u{30A4}', + '\u{30C4}', + '\u{30CF}', + '\u{309A}', + '\u{30FC}', + '\u{30BB}', + '\u{30F3}', + '\u{30C8}', + '\u{30CF}', + '\u{309A}', + '\u{30FC}', + '\u{30C4}', + '\u{30CF}', + '\u{3099}', + '\u{30FC}', + '\u{30EC}', + '\u{30EB}', + '\u{30D2}', + '\u{309A}', + '\u{30A2}', + '\u{30B9}', + '\u{30C8}', + '\u{30EB}', + '\u{30D2}', + '\u{309A}', + '\u{30AF}', + '\u{30EB}', + '\u{30D2}', + '\u{309A}', + '\u{30B3}', + '\u{30D2}', + '\u{3099}', + '\u{30EB}', + '\u{30D5}', + '\u{30A1}', + '\u{30E9}', + '\u{30C3}', + '\u{30C8}', + '\u{3099}', + '\u{30D5}', + '\u{30A3}', + '\u{30FC}', + '\u{30C8}', + '\u{30D5}', + '\u{3099}', + '\u{30C3}', + '\u{30B7}', + '\u{30A7}', + '\u{30EB}', + '\u{30D5}', + '\u{30E9}', + '\u{30F3}', + '\u{30D8}', + '\u{30AF}', + '\u{30BF}', + '\u{30FC}', + '\u{30EB}', + '\u{30D8}', + '\u{309A}', + '\u{30BD}', + '\u{30D8}', + '\u{309A}', + '\u{30CB}', + '\u{30D2}', + '\u{30D8}', + '\u{30EB}', + '\u{30C4}', + '\u{30D8}', + '\u{309A}', + '\u{30F3}', + '\u{30B9}', + '\u{30D8}', + '\u{309A}', + '\u{30FC}', + '\u{30B7}', + '\u{3099}', + '\u{30D8}', + '\u{3099}', + '\u{30FC}', + '\u{30BF}', + '\u{30DB}', + '\u{309A}', + '\u{30A4}', + '\u{30F3}', + '\u{30C8}', + '\u{30DB}', + '\u{3099}', + '\u{30EB}', + '\u{30C8}', + '\u{30DB}', + '\u{30F3}', + '\u{30DB}', + '\u{309A}', + '\u{30F3}', + '\u{30C8}', + '\u{3099}', + '\u{30DB}', + '\u{30FC}', + '\u{30EB}', + '\u{30DB}', + '\u{30FC}', + '\u{30F3}', + '\u{30DE}', + '\u{30A4}', + '\u{30AF}', + '\u{30ED}', + '\u{30DE}', + '\u{30A4}', + '\u{30EB}', + '\u{30DE}', + '\u{30C3}', + '\u{30CF}', + '\u{30DE}', + '\u{30EB}', + '\u{30AF}', + '\u{30DE}', + '\u{30F3}', + '\u{30B7}', + '\u{30E7}', + '\u{30F3}', + '\u{30DF}', + '\u{30AF}', + '\u{30ED}', + '\u{30F3}', + '\u{30DF}', + '\u{30EA}', + '\u{30DF}', + '\u{30EA}', + '\u{30CF}', + '\u{3099}', + '\u{30FC}', + '\u{30EB}', + '\u{30E1}', + '\u{30AB}', + '\u{3099}', + '\u{30E1}', + '\u{30AB}', + '\u{3099}', + '\u{30C8}', + '\u{30F3}', + '\u{30E1}', + '\u{30FC}', + '\u{30C8}', + '\u{30EB}', + '\u{30E4}', + '\u{30FC}', + '\u{30C8}', + '\u{3099}', + '\u{30E4}', + '\u{30FC}', + '\u{30EB}', + '\u{30E6}', + '\u{30A2}', + '\u{30F3}', + '\u{30EA}', + '\u{30C3}', + '\u{30C8}', + '\u{30EB}', + '\u{30EA}', + '\u{30E9}', + '\u{30EB}', + '\u{30D2}', + '\u{309A}', + '\u{30FC}', + '\u{30EB}', + '\u{30FC}', + '\u{30D5}', + '\u{3099}', + '\u{30EB}', + '\u{30EC}', + '\u{30E0}', + '\u{30EC}', + '\u{30F3}', + '\u{30C8}', + '\u{30B1}', + '\u{3099}', + '\u{30F3}', + '\u{30EF}', + '\u{30C3}', + '\u{30C8}', + '\u{0030}', + '\u{70B9}', + '\u{0031}', + '\u{70B9}', + '\u{0032}', + '\u{70B9}', + '\u{0033}', + '\u{70B9}', + '\u{0034}', + '\u{70B9}', + '\u{0035}', + '\u{70B9}', + '\u{0036}', + '\u{70B9}', + '\u{0037}', + '\u{70B9}', + '\u{0038}', + '\u{70B9}', + '\u{0039}', + '\u{70B9}', + '\u{0031}', + '\u{0030}', + '\u{70B9}', + '\u{0031}', + '\u{0031}', + '\u{70B9}', + '\u{0031}', + '\u{0032}', + '\u{70B9}', + '\u{0031}', + '\u{0033}', + '\u{70B9}', + '\u{0031}', + '\u{0034}', + '\u{70B9}', + '\u{0031}', + '\u{0035}', + '\u{70B9}', + '\u{0031}', + '\u{0036}', + '\u{70B9}', + '\u{0031}', + '\u{0037}', + '\u{70B9}', + '\u{0031}', + '\u{0038}', + '\u{70B9}', + '\u{0031}', + '\u{0039}', + '\u{70B9}', + '\u{0032}', + '\u{0030}', + '\u{70B9}', + '\u{0032}', + '\u{0031}', + '\u{70B9}', + '\u{0032}', + '\u{0032}', + '\u{70B9}', + '\u{0032}', + '\u{0033}', + '\u{70B9}', + '\u{0032}', + '\u{0034}', + '\u{70B9}', + '\u{0068}', + '\u{0050}', + '\u{0061}', + '\u{0064}', + '\u{0061}', + '\u{0041}', + '\u{0055}', + '\u{0062}', + '\u{0061}', + '\u{0072}', + '\u{006F}', + '\u{0056}', + '\u{0070}', + '\u{0063}', + '\u{0064}', + '\u{006D}', + '\u{0064}', + '\u{006D}', + '\u{0032}', + '\u{0064}', + '\u{006D}', + '\u{0033}', + '\u{0049}', + '\u{0055}', + '\u{5E73}', + '\u{6210}', + '\u{662D}', + '\u{548C}', + '\u{5927}', + '\u{6B63}', + '\u{660E}', + '\u{6CBB}', + '\u{682A}', + '\u{5F0F}', + '\u{4F1A}', + '\u{793E}', + '\u{0070}', + '\u{0041}', + '\u{006E}', + '\u{0041}', + '\u{03BC}', + '\u{0041}', + '\u{006D}', + '\u{0041}', + '\u{006B}', + '\u{0041}', + '\u{004B}', + '\u{0042}', + '\u{004D}', + '\u{0042}', + '\u{0047}', + '\u{0042}', + '\u{0063}', + '\u{0061}', + '\u{006C}', + '\u{006B}', + '\u{0063}', + '\u{0061}', + '\u{006C}', + '\u{0070}', + '\u{0046}', + '\u{006E}', + '\u{0046}', + '\u{03BC}', + '\u{0046}', + '\u{03BC}', + '\u{0067}', + '\u{006D}', + '\u{0067}', + '\u{006B}', + '\u{0067}', + '\u{0048}', + '\u{007A}', + '\u{006B}', + '\u{0048}', + '\u{007A}', + '\u{004D}', + '\u{0048}', + '\u{007A}', + '\u{0047}', + '\u{0048}', + '\u{007A}', + '\u{0054}', + '\u{0048}', + '\u{007A}', + '\u{03BC}', + '\u{006C}', + '\u{006D}', + '\u{006C}', + '\u{0064}', + '\u{006C}', + '\u{006B}', + '\u{006C}', + '\u{0066}', + '\u{006D}', + '\u{006E}', + '\u{006D}', + '\u{03BC}', + '\u{006D}', + '\u{006D}', + '\u{006D}', + '\u{0063}', + '\u{006D}', + '\u{006B}', + '\u{006D}', + '\u{006D}', + '\u{006D}', + '\u{0032}', + '\u{0063}', + '\u{006D}', + '\u{0032}', + '\u{006D}', + '\u{0032}', + '\u{006B}', + '\u{006D}', + '\u{0032}', + '\u{006D}', + '\u{006D}', + '\u{0033}', + '\u{0063}', + '\u{006D}', + '\u{0033}', + '\u{006D}', + '\u{0033}', + '\u{006B}', + '\u{006D}', + '\u{0033}', + '\u{006D}', + '\u{2215}', + '\u{0073}', + '\u{006D}', + '\u{2215}', + '\u{0073}', + '\u{0032}', + '\u{0050}', + '\u{0061}', + '\u{006B}', + '\u{0050}', + '\u{0061}', + '\u{004D}', + '\u{0050}', + '\u{0061}', + '\u{0047}', + '\u{0050}', + '\u{0061}', + '\u{0072}', + '\u{0061}', + '\u{0064}', + '\u{0072}', + '\u{0061}', + '\u{0064}', + '\u{2215}', + '\u{0073}', + '\u{0072}', + '\u{0061}', + '\u{0064}', + '\u{2215}', + '\u{0073}', + '\u{0032}', + '\u{0070}', + '\u{0073}', + '\u{006E}', + '\u{0073}', + '\u{03BC}', + '\u{0073}', + '\u{006D}', + '\u{0073}', + '\u{0070}', + '\u{0056}', + '\u{006E}', + '\u{0056}', + '\u{03BC}', + '\u{0056}', + '\u{006D}', + '\u{0056}', + '\u{006B}', + '\u{0056}', + '\u{004D}', + '\u{0056}', + '\u{0070}', + '\u{0057}', + '\u{006E}', + '\u{0057}', + '\u{03BC}', + '\u{0057}', + '\u{006D}', + '\u{0057}', + '\u{006B}', + '\u{0057}', + '\u{004D}', + '\u{0057}', + '\u{006B}', + '\u{03A9}', + '\u{004D}', + '\u{03A9}', + '\u{0061}', + '\u{002E}', + '\u{006D}', + '\u{002E}', + '\u{0042}', + '\u{0071}', + '\u{0063}', + '\u{0063}', + '\u{0063}', + '\u{0064}', + '\u{0043}', + '\u{2215}', + '\u{006B}', + '\u{0067}', + '\u{0043}', + '\u{006F}', + '\u{002E}', + '\u{0064}', + '\u{0042}', + '\u{0047}', + '\u{0079}', + '\u{0068}', + '\u{0061}', + '\u{0048}', + '\u{0050}', + '\u{0069}', + '\u{006E}', + '\u{004B}', + '\u{004B}', + '\u{004B}', + '\u{004D}', + '\u{006B}', + '\u{0074}', + '\u{006C}', + '\u{006D}', + '\u{006C}', + '\u{006E}', + '\u{006C}', + '\u{006F}', + '\u{0067}', + '\u{006C}', + '\u{0078}', + '\u{006D}', + '\u{0062}', + '\u{006D}', + '\u{0069}', + '\u{006C}', + '\u{006D}', + '\u{006F}', + '\u{006C}', + '\u{0050}', + '\u{0048}', + '\u{0070}', + '\u{002E}', + '\u{006D}', + '\u{002E}', + '\u{0050}', + '\u{0050}', + '\u{004D}', + '\u{0050}', + '\u{0052}', + '\u{0073}', + '\u{0072}', + '\u{0053}', + '\u{0076}', + '\u{0057}', + '\u{0062}', + '\u{0056}', + '\u{2215}', + '\u{006D}', + '\u{0041}', + '\u{2215}', + '\u{006D}', + '\u{0031}', + '\u{65E5}', + '\u{0032}', + '\u{65E5}', + '\u{0033}', + '\u{65E5}', + '\u{0034}', + '\u{65E5}', + '\u{0035}', + '\u{65E5}', + '\u{0036}', + '\u{65E5}', + '\u{0037}', + '\u{65E5}', + '\u{0038}', + '\u{65E5}', + '\u{0039}', + '\u{65E5}', + '\u{0031}', + '\u{0030}', + '\u{65E5}', + '\u{0031}', + '\u{0031}', + '\u{65E5}', + '\u{0031}', + '\u{0032}', + '\u{65E5}', + '\u{0031}', + '\u{0033}', + '\u{65E5}', + '\u{0031}', + '\u{0034}', + '\u{65E5}', + '\u{0031}', + '\u{0035}', + '\u{65E5}', + '\u{0031}', + '\u{0036}', + '\u{65E5}', + '\u{0031}', + '\u{0037}', + '\u{65E5}', + '\u{0031}', + '\u{0038}', + '\u{65E5}', + '\u{0031}', + '\u{0039}', + '\u{65E5}', + '\u{0032}', + '\u{0030}', + '\u{65E5}', + '\u{0032}', + '\u{0031}', + '\u{65E5}', + '\u{0032}', + '\u{0032}', + '\u{65E5}', + '\u{0032}', + '\u{0033}', + '\u{65E5}', + '\u{0032}', + '\u{0034}', + '\u{65E5}', + '\u{0032}', + '\u{0035}', + '\u{65E5}', + '\u{0032}', + '\u{0036}', + '\u{65E5}', + '\u{0032}', + '\u{0037}', + '\u{65E5}', + '\u{0032}', + '\u{0038}', + '\u{65E5}', + '\u{0032}', + '\u{0039}', + '\u{65E5}', + '\u{0033}', + '\u{0030}', + '\u{65E5}', + '\u{0033}', + '\u{0031}', + '\u{65E5}', + '\u{0067}', + '\u{0061}', + '\u{006C}', + '\u{044A}', + '\u{044C}', + '\u{A76F}', + '\u{0043}', + '\u{0046}', + '\u{0051}', + '\u{0126}', + '\u{0153}', + '\u{A727}', + '\u{AB37}', + '\u{026B}', + '\u{AB52}', + '\u{028D}', + '\u{0066}', + '\u{0066}', + '\u{0066}', + '\u{0069}', + '\u{0066}', + '\u{006C}', + '\u{0066}', + '\u{0066}', + '\u{0069}', + '\u{0066}', + '\u{0066}', + '\u{006C}', + '\u{0073}', + '\u{0074}', + '\u{0073}', + '\u{0074}', + '\u{0574}', + '\u{0576}', + '\u{0574}', + '\u{0565}', + '\u{0574}', + '\u{056B}', + '\u{057E}', + '\u{0576}', + '\u{0574}', + '\u{056D}', + '\u{05E2}', + '\u{05D0}', + '\u{05D3}', + '\u{05D4}', + '\u{05DB}', + '\u{05DC}', + '\u{05DD}', + '\u{05E8}', + '\u{05EA}', + '\u{002B}', + '\u{05D0}', + '\u{05DC}', + '\u{0671}', + '\u{0671}', + '\u{067B}', + '\u{067B}', + '\u{067B}', + '\u{067B}', + '\u{067E}', + '\u{067E}', + '\u{067E}', + '\u{067E}', + '\u{0680}', + '\u{0680}', + '\u{0680}', + '\u{0680}', + '\u{067A}', + '\u{067A}', + '\u{067A}', + '\u{067A}', + '\u{067F}', + '\u{067F}', + '\u{067F}', + '\u{067F}', + '\u{0679}', + '\u{0679}', + '\u{0679}', + '\u{0679}', + '\u{06A4}', + '\u{06A4}', + '\u{06A4}', + '\u{06A4}', + '\u{06A6}', + '\u{06A6}', + '\u{06A6}', + '\u{06A6}', + '\u{0684}', + '\u{0684}', + '\u{0684}', + '\u{0684}', + '\u{0683}', + '\u{0683}', + '\u{0683}', + '\u{0683}', + '\u{0686}', + '\u{0686}', + '\u{0686}', + '\u{0686}', + '\u{0687}', + '\u{0687}', + '\u{0687}', + '\u{0687}', + '\u{068D}', + '\u{068D}', + '\u{068C}', + '\u{068C}', + '\u{068E}', + '\u{068E}', + '\u{0688}', + '\u{0688}', + '\u{0698}', + '\u{0698}', + '\u{0691}', + '\u{0691}', + '\u{06A9}', + '\u{06A9}', + '\u{06A9}', + '\u{06A9}', + '\u{06AF}', + '\u{06AF}', + '\u{06AF}', + '\u{06AF}', + '\u{06B3}', + '\u{06B3}', + '\u{06B3}', + '\u{06B3}', + '\u{06B1}', + '\u{06B1}', + '\u{06B1}', + '\u{06B1}', + '\u{06BA}', + '\u{06BA}', + '\u{06BB}', + '\u{06BB}', + '\u{06BB}', + '\u{06BB}', + '\u{06D5}', + '\u{0654}', + '\u{06D5}', + '\u{0654}', + '\u{06C1}', + '\u{06C1}', + '\u{06C1}', + '\u{06C1}', + '\u{06BE}', + '\u{06BE}', + '\u{06BE}', + '\u{06BE}', + '\u{06D2}', + '\u{06D2}', + '\u{06D2}', + '\u{0654}', + '\u{06D2}', + '\u{0654}', + '\u{06AD}', + '\u{06AD}', + '\u{06AD}', + '\u{06AD}', + '\u{06C7}', + '\u{06C7}', + '\u{06C6}', + '\u{06C6}', + '\u{06C8}', + '\u{06C8}', + '\u{06C7}', + '\u{0674}', + '\u{06CB}', + '\u{06CB}', + '\u{06C5}', + '\u{06C5}', + '\u{06C9}', + '\u{06C9}', + '\u{06D0}', + '\u{06D0}', + '\u{06D0}', + '\u{06D0}', + '\u{0649}', + '\u{0649}', + '\u{064A}', + '\u{0654}', + '\u{0627}', + '\u{064A}', + '\u{0654}', + '\u{0627}', + '\u{064A}', + '\u{0654}', + '\u{06D5}', + '\u{064A}', + '\u{0654}', + '\u{06D5}', + '\u{064A}', + '\u{0654}', + '\u{0648}', + '\u{064A}', + '\u{0654}', + '\u{0648}', + '\u{064A}', + '\u{0654}', + '\u{06C7}', + '\u{064A}', + '\u{0654}', + '\u{06C7}', + '\u{064A}', + '\u{0654}', + '\u{06C6}', + '\u{064A}', + '\u{0654}', + '\u{06C6}', + '\u{064A}', + '\u{0654}', + '\u{06C8}', + '\u{064A}', + '\u{0654}', + '\u{06C8}', + '\u{064A}', + '\u{0654}', + '\u{06D0}', + '\u{064A}', + '\u{0654}', + '\u{06D0}', + '\u{064A}', + '\u{0654}', + '\u{06D0}', + '\u{064A}', + '\u{0654}', + '\u{0649}', + '\u{064A}', + '\u{0654}', + '\u{0649}', + '\u{064A}', + '\u{0654}', + '\u{0649}', + '\u{06CC}', + '\u{06CC}', + '\u{06CC}', + '\u{06CC}', + '\u{064A}', + '\u{0654}', + '\u{062C}', + '\u{064A}', + '\u{0654}', + '\u{062D}', + '\u{064A}', + '\u{0654}', + '\u{0645}', + '\u{064A}', + '\u{0654}', + '\u{0649}', + '\u{064A}', + '\u{0654}', + '\u{064A}', + '\u{0628}', + '\u{062C}', + '\u{0628}', + '\u{062D}', + '\u{0628}', + '\u{062E}', + '\u{0628}', + '\u{0645}', + '\u{0628}', + '\u{0649}', + '\u{0628}', + '\u{064A}', + '\u{062A}', + '\u{062C}', + '\u{062A}', + '\u{062D}', + '\u{062A}', + '\u{062E}', + '\u{062A}', + '\u{0645}', + '\u{062A}', + '\u{0649}', + '\u{062A}', + '\u{064A}', + '\u{062B}', + '\u{062C}', + '\u{062B}', + '\u{0645}', + '\u{062B}', + '\u{0649}', + '\u{062B}', + '\u{064A}', + '\u{062C}', + '\u{062D}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{062C}', + '\u{062D}', + '\u{0645}', + '\u{062E}', + '\u{062C}', + '\u{062E}', + '\u{062D}', + '\u{062E}', + '\u{0645}', + '\u{0633}', + '\u{062C}', + '\u{0633}', + '\u{062D}', + '\u{0633}', + '\u{062E}', + '\u{0633}', + '\u{0645}', + '\u{0635}', + '\u{062D}', + '\u{0635}', + '\u{0645}', + '\u{0636}', + '\u{062C}', + '\u{0636}', + '\u{062D}', + '\u{0636}', + '\u{062E}', + '\u{0636}', + '\u{0645}', + '\u{0637}', + '\u{062D}', + '\u{0637}', + '\u{0645}', + '\u{0638}', + '\u{0645}', + '\u{0639}', + '\u{062C}', + '\u{0639}', + '\u{0645}', + '\u{063A}', + '\u{062C}', + '\u{063A}', + '\u{0645}', + '\u{0641}', + '\u{062C}', + '\u{0641}', + '\u{062D}', + '\u{0641}', + '\u{062E}', + '\u{0641}', + '\u{0645}', + '\u{0641}', + '\u{0649}', + '\u{0641}', + '\u{064A}', + '\u{0642}', + '\u{062D}', + '\u{0642}', + '\u{0645}', + '\u{0642}', + '\u{0649}', + '\u{0642}', + '\u{064A}', + '\u{0643}', + '\u{0627}', + '\u{0643}', + '\u{062C}', + '\u{0643}', + '\u{062D}', + '\u{0643}', + '\u{062E}', + '\u{0643}', + '\u{0644}', + '\u{0643}', + '\u{0645}', + '\u{0643}', + '\u{0649}', + '\u{0643}', + '\u{064A}', + '\u{0644}', + '\u{062C}', + '\u{0644}', + '\u{062D}', + '\u{0644}', + '\u{062E}', + '\u{0644}', + '\u{0645}', + '\u{0644}', + '\u{0649}', + '\u{0644}', + '\u{064A}', + '\u{0645}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{0645}', + '\u{062E}', + '\u{0645}', + '\u{0645}', + '\u{0645}', + '\u{0649}', + '\u{0645}', + '\u{064A}', + '\u{0646}', + '\u{062C}', + '\u{0646}', + '\u{062D}', + '\u{0646}', + '\u{062E}', + '\u{0646}', + '\u{0645}', + '\u{0646}', + '\u{0649}', + '\u{0646}', + '\u{064A}', + '\u{0647}', + '\u{062C}', + '\u{0647}', + '\u{0645}', + '\u{0647}', + '\u{0649}', + '\u{0647}', + '\u{064A}', + '\u{064A}', + '\u{062C}', + '\u{064A}', + '\u{062D}', + '\u{064A}', + '\u{062E}', + '\u{064A}', + '\u{0645}', + '\u{064A}', + '\u{0649}', + '\u{064A}', + '\u{064A}', + '\u{0630}', + '\u{0670}', + '\u{0631}', + '\u{0670}', + '\u{0649}', + '\u{0670}', + '\u{0020}', + '\u{064C}', + '\u{0651}', + '\u{0020}', + '\u{064D}', + '\u{0651}', + '\u{0020}', + '\u{064E}', + '\u{0651}', + '\u{0020}', + '\u{064F}', + '\u{0651}', + '\u{0020}', + '\u{0650}', + '\u{0651}', + '\u{0020}', + '\u{0651}', + '\u{0670}', + '\u{064A}', + '\u{0654}', + '\u{0631}', + '\u{064A}', + '\u{0654}', + '\u{0632}', + '\u{064A}', + '\u{0654}', + '\u{0645}', + '\u{064A}', + '\u{0654}', + '\u{0646}', + '\u{064A}', + '\u{0654}', + '\u{0649}', + '\u{064A}', + '\u{0654}', + '\u{064A}', + '\u{0628}', + '\u{0631}', + '\u{0628}', + '\u{0632}', + '\u{0628}', + '\u{0645}', + '\u{0628}', + '\u{0646}', + '\u{0628}', + '\u{0649}', + '\u{0628}', + '\u{064A}', + '\u{062A}', + '\u{0631}', + '\u{062A}', + '\u{0632}', + '\u{062A}', + '\u{0645}', + '\u{062A}', + '\u{0646}', + '\u{062A}', + '\u{0649}', + '\u{062A}', + '\u{064A}', + '\u{062B}', + '\u{0631}', + '\u{062B}', + '\u{0632}', + '\u{062B}', + '\u{0645}', + '\u{062B}', + '\u{0646}', + '\u{062B}', + '\u{0649}', + '\u{062B}', + '\u{064A}', + '\u{0641}', + '\u{0649}', + '\u{0641}', + '\u{064A}', + '\u{0642}', + '\u{0649}', + '\u{0642}', + '\u{064A}', + '\u{0643}', + '\u{0627}', + '\u{0643}', + '\u{0644}', + '\u{0643}', + '\u{0645}', + '\u{0643}', + '\u{0649}', + '\u{0643}', + '\u{064A}', + '\u{0644}', + '\u{0645}', + '\u{0644}', + '\u{0649}', + '\u{0644}', + '\u{064A}', + '\u{0645}', + '\u{0627}', + '\u{0645}', + '\u{0645}', + '\u{0646}', + '\u{0631}', + '\u{0646}', + '\u{0632}', + '\u{0646}', + '\u{0645}', + '\u{0646}', + '\u{0646}', + '\u{0646}', + '\u{0649}', + '\u{0646}', + '\u{064A}', + '\u{0649}', + '\u{0670}', + '\u{064A}', + '\u{0631}', + '\u{064A}', + '\u{0632}', + '\u{064A}', + '\u{0645}', + '\u{064A}', + '\u{0646}', + '\u{064A}', + '\u{0649}', + '\u{064A}', + '\u{064A}', + '\u{064A}', + '\u{0654}', + '\u{062C}', + '\u{064A}', + '\u{0654}', + '\u{062D}', + '\u{064A}', + '\u{0654}', + '\u{062E}', + '\u{064A}', + '\u{0654}', + '\u{0645}', + '\u{064A}', + '\u{0654}', + '\u{0647}', + '\u{0628}', + '\u{062C}', + '\u{0628}', + '\u{062D}', + '\u{0628}', + '\u{062E}', + '\u{0628}', + '\u{0645}', + '\u{0628}', + '\u{0647}', + '\u{062A}', + '\u{062C}', + '\u{062A}', + '\u{062D}', + '\u{062A}', + '\u{062E}', + '\u{062A}', + '\u{0645}', + '\u{062A}', + '\u{0647}', + '\u{062B}', + '\u{0645}', + '\u{062C}', + '\u{062D}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{062C}', + '\u{062D}', + '\u{0645}', + '\u{062E}', + '\u{062C}', + '\u{062E}', + '\u{0645}', + '\u{0633}', + '\u{062C}', + '\u{0633}', + '\u{062D}', + '\u{0633}', + '\u{062E}', + '\u{0633}', + '\u{0645}', + '\u{0635}', + '\u{062D}', + '\u{0635}', + '\u{062E}', + '\u{0635}', + '\u{0645}', + '\u{0636}', + '\u{062C}', + '\u{0636}', + '\u{062D}', + '\u{0636}', + '\u{062E}', + '\u{0636}', + '\u{0645}', + '\u{0637}', + '\u{062D}', + '\u{0638}', + '\u{0645}', + '\u{0639}', + '\u{062C}', + '\u{0639}', + '\u{0645}', + '\u{063A}', + '\u{062C}', + '\u{063A}', + '\u{0645}', + '\u{0641}', + '\u{062C}', + '\u{0641}', + '\u{062D}', + '\u{0641}', + '\u{062E}', + '\u{0641}', + '\u{0645}', + '\u{0642}', + '\u{062D}', + '\u{0642}', + '\u{0645}', + '\u{0643}', + '\u{062C}', + '\u{0643}', + '\u{062D}', + '\u{0643}', + '\u{062E}', + '\u{0643}', + '\u{0644}', + '\u{0643}', + '\u{0645}', + '\u{0644}', + '\u{062C}', + '\u{0644}', + '\u{062D}', + '\u{0644}', + '\u{062E}', + '\u{0644}', + '\u{0645}', + '\u{0644}', + '\u{0647}', + '\u{0645}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{0645}', + '\u{062E}', + '\u{0645}', + '\u{0645}', + '\u{0646}', + '\u{062C}', + '\u{0646}', + '\u{062D}', + '\u{0646}', + '\u{062E}', + '\u{0646}', + '\u{0645}', + '\u{0646}', + '\u{0647}', + '\u{0647}', + '\u{062C}', + '\u{0647}', + '\u{0645}', + '\u{0647}', + '\u{0670}', + '\u{064A}', + '\u{062C}', + '\u{064A}', + '\u{062D}', + '\u{064A}', + '\u{062E}', + '\u{064A}', + '\u{0645}', + '\u{064A}', + '\u{0647}', + '\u{064A}', + '\u{0654}', + '\u{0645}', + '\u{064A}', + '\u{0654}', + '\u{0647}', + '\u{0628}', + '\u{0645}', + '\u{0628}', + '\u{0647}', + '\u{062A}', + '\u{0645}', + '\u{062A}', + '\u{0647}', + '\u{062B}', + '\u{0645}', + '\u{062B}', + '\u{0647}', + '\u{0633}', + '\u{0645}', + '\u{0633}', + '\u{0647}', + '\u{0634}', + '\u{0645}', + '\u{0634}', + '\u{0647}', + '\u{0643}', + '\u{0644}', + '\u{0643}', + '\u{0645}', + '\u{0644}', + '\u{0645}', + '\u{0646}', + '\u{0645}', + '\u{0646}', + '\u{0647}', + '\u{064A}', + '\u{0645}', + '\u{064A}', + '\u{0647}', + '\u{0640}', + '\u{064E}', + '\u{0651}', + '\u{0640}', + '\u{064F}', + '\u{0651}', + '\u{0640}', + '\u{0650}', + '\u{0651}', + '\u{0637}', + '\u{0649}', + '\u{0637}', + '\u{064A}', + '\u{0639}', + '\u{0649}', + '\u{0639}', + '\u{064A}', + '\u{063A}', + '\u{0649}', + '\u{063A}', + '\u{064A}', + '\u{0633}', + '\u{0649}', + '\u{0633}', + '\u{064A}', + '\u{0634}', + '\u{0649}', + '\u{0634}', + '\u{064A}', + '\u{062D}', + '\u{0649}', + '\u{062D}', + '\u{064A}', + '\u{062C}', + '\u{0649}', + '\u{062C}', + '\u{064A}', + '\u{062E}', + '\u{0649}', + '\u{062E}', + '\u{064A}', + '\u{0635}', + '\u{0649}', + '\u{0635}', + '\u{064A}', + '\u{0636}', + '\u{0649}', + '\u{0636}', + '\u{064A}', + '\u{0634}', + '\u{062C}', + '\u{0634}', + '\u{062D}', + '\u{0634}', + '\u{062E}', + '\u{0634}', + '\u{0645}', + '\u{0634}', + '\u{0631}', + '\u{0633}', + '\u{0631}', + '\u{0635}', + '\u{0631}', + '\u{0636}', + '\u{0631}', + '\u{0637}', + '\u{0649}', + '\u{0637}', + '\u{064A}', + '\u{0639}', + '\u{0649}', + '\u{0639}', + '\u{064A}', + '\u{063A}', + '\u{0649}', + '\u{063A}', + '\u{064A}', + '\u{0633}', + '\u{0649}', + '\u{0633}', + '\u{064A}', + '\u{0634}', + '\u{0649}', + '\u{0634}', + '\u{064A}', + '\u{062D}', + '\u{0649}', + '\u{062D}', + '\u{064A}', + '\u{062C}', + '\u{0649}', + '\u{062C}', + '\u{064A}', + '\u{062E}', + '\u{0649}', + '\u{062E}', + '\u{064A}', + '\u{0635}', + '\u{0649}', + '\u{0635}', + '\u{064A}', + '\u{0636}', + '\u{0649}', + '\u{0636}', + '\u{064A}', + '\u{0634}', + '\u{062C}', + '\u{0634}', + '\u{062D}', + '\u{0634}', + '\u{062E}', + '\u{0634}', + '\u{0645}', + '\u{0634}', + '\u{0631}', + '\u{0633}', + '\u{0631}', + '\u{0635}', + '\u{0631}', + '\u{0636}', + '\u{0631}', + '\u{0634}', + '\u{062C}', + '\u{0634}', + '\u{062D}', + '\u{0634}', + '\u{062E}', + '\u{0634}', + '\u{0645}', + '\u{0633}', + '\u{0647}', + '\u{0634}', + '\u{0647}', + '\u{0637}', + '\u{0645}', + '\u{0633}', + '\u{062C}', + '\u{0633}', + '\u{062D}', + '\u{0633}', + '\u{062E}', + '\u{0634}', + '\u{062C}', + '\u{0634}', + '\u{062D}', + '\u{0634}', + '\u{062E}', + '\u{0637}', + '\u{0645}', + '\u{0638}', + '\u{0645}', + '\u{0627}', + '\u{064B}', + '\u{0627}', + '\u{064B}', + '\u{062A}', + '\u{062C}', + '\u{0645}', + '\u{062A}', + '\u{062D}', + '\u{062C}', + '\u{062A}', + '\u{062D}', + '\u{062C}', + '\u{062A}', + '\u{062D}', + '\u{0645}', + '\u{062A}', + '\u{062E}', + '\u{0645}', + '\u{062A}', + '\u{0645}', + '\u{062C}', + '\u{062A}', + '\u{0645}', + '\u{062D}', + '\u{062A}', + '\u{0645}', + '\u{062E}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{062D}', + '\u{0645}', + '\u{064A}', + '\u{062D}', + '\u{0645}', + '\u{0649}', + '\u{0633}', + '\u{062D}', + '\u{062C}', + '\u{0633}', + '\u{062C}', + '\u{062D}', + '\u{0633}', + '\u{062C}', + '\u{0649}', + '\u{0633}', + '\u{0645}', + '\u{062D}', + '\u{0633}', + '\u{0645}', + '\u{062D}', + '\u{0633}', + '\u{0645}', + '\u{062C}', + '\u{0633}', + '\u{0645}', + '\u{0645}', + '\u{0633}', + '\u{0645}', + '\u{0645}', + '\u{0635}', + '\u{062D}', + '\u{062D}', + '\u{0635}', + '\u{062D}', + '\u{062D}', + '\u{0635}', + '\u{0645}', + '\u{0645}', + '\u{0634}', + '\u{062D}', + '\u{0645}', + '\u{0634}', + '\u{062D}', + '\u{0645}', + '\u{0634}', + '\u{062C}', + '\u{064A}', + '\u{0634}', + '\u{0645}', + '\u{062E}', + '\u{0634}', + '\u{0645}', + '\u{062E}', + '\u{0634}', + '\u{0645}', + '\u{0645}', + '\u{0634}', + '\u{0645}', + '\u{0645}', + '\u{0636}', + '\u{062D}', + '\u{0649}', + '\u{0636}', + '\u{062E}', + '\u{0645}', + '\u{0636}', + '\u{062E}', + '\u{0645}', + '\u{0637}', + '\u{0645}', + '\u{062D}', + '\u{0637}', + '\u{0645}', + '\u{062D}', + '\u{0637}', + '\u{0645}', + '\u{0645}', + '\u{0637}', + '\u{0645}', + '\u{064A}', + '\u{0639}', + '\u{062C}', + '\u{0645}', + '\u{0639}', + '\u{0645}', + '\u{0645}', + '\u{0639}', + '\u{0645}', + '\u{0645}', + '\u{0639}', + '\u{0645}', + '\u{0649}', + '\u{063A}', + '\u{0645}', + '\u{0645}', + '\u{063A}', + '\u{0645}', + '\u{064A}', + '\u{063A}', + '\u{0645}', + '\u{0649}', + '\u{0641}', + '\u{062E}', + '\u{0645}', + '\u{0641}', + '\u{062E}', + '\u{0645}', + '\u{0642}', + '\u{0645}', + '\u{062D}', + '\u{0642}', + '\u{0645}', + '\u{0645}', + '\u{0644}', + '\u{062D}', + '\u{0645}', + '\u{0644}', + '\u{062D}', + '\u{064A}', + '\u{0644}', + '\u{062D}', + '\u{0649}', + '\u{0644}', + '\u{062C}', + '\u{062C}', + '\u{0644}', + '\u{062C}', + '\u{062C}', + '\u{0644}', + '\u{062E}', + '\u{0645}', + '\u{0644}', + '\u{062E}', + '\u{0645}', + '\u{0644}', + '\u{0645}', + '\u{062D}', + '\u{0644}', + '\u{0645}', + '\u{062D}', + '\u{0645}', + '\u{062D}', + '\u{062C}', + '\u{0645}', + '\u{062D}', + '\u{0645}', + '\u{0645}', + '\u{062D}', + '\u{064A}', + '\u{0645}', + '\u{062C}', + '\u{062D}', + '\u{0645}', + '\u{062C}', + '\u{0645}', + '\u{0645}', + '\u{062E}', + '\u{062C}', + '\u{0645}', + '\u{062E}', + '\u{0645}', + '\u{0645}', + '\u{062C}', + '\u{062E}', + '\u{0647}', + '\u{0645}', + '\u{062C}', + '\u{0647}', + '\u{0645}', + '\u{0645}', + '\u{0646}', + '\u{062D}', + '\u{0645}', + '\u{0646}', + '\u{062D}', + '\u{0649}', + '\u{0646}', + '\u{062C}', + '\u{0645}', + '\u{0646}', + '\u{062C}', + '\u{0645}', + '\u{0646}', + '\u{062C}', + '\u{0649}', + '\u{0646}', + '\u{0645}', + '\u{064A}', + '\u{0646}', + '\u{0645}', + '\u{0649}', + '\u{064A}', + '\u{0645}', + '\u{0645}', + '\u{064A}', + '\u{0645}', + '\u{0645}', + '\u{0628}', + '\u{062E}', + '\u{064A}', + '\u{062A}', + '\u{062C}', + '\u{064A}', + '\u{062A}', + '\u{062C}', + '\u{0649}', + '\u{062A}', + '\u{062E}', + '\u{064A}', + '\u{062A}', + '\u{062E}', + '\u{0649}', + '\u{062A}', + '\u{0645}', + '\u{064A}', + '\u{062A}', + '\u{0645}', + '\u{0649}', + '\u{062C}', + '\u{0645}', + '\u{064A}', + '\u{062C}', + '\u{062D}', + '\u{0649}', + '\u{062C}', + '\u{0645}', + '\u{0649}', + '\u{0633}', + '\u{062E}', + '\u{0649}', + '\u{0635}', + '\u{062D}', + '\u{064A}', + '\u{0634}', + '\u{062D}', + '\u{064A}', + '\u{0636}', + '\u{062D}', + '\u{064A}', + '\u{0644}', + '\u{062C}', + '\u{064A}', + '\u{0644}', + '\u{0645}', + '\u{064A}', + '\u{064A}', + '\u{062D}', + '\u{064A}', + '\u{064A}', + '\u{062C}', + '\u{064A}', + '\u{064A}', + '\u{0645}', + '\u{064A}', + '\u{0645}', + '\u{0645}', + '\u{064A}', + '\u{0642}', + '\u{0645}', + '\u{064A}', + '\u{0646}', + '\u{062D}', + '\u{064A}', + '\u{0642}', + '\u{0645}', + '\u{062D}', + '\u{0644}', + '\u{062D}', + '\u{0645}', + '\u{0639}', + '\u{0645}', + '\u{064A}', + '\u{0643}', + '\u{0645}', + '\u{064A}', + '\u{0646}', + '\u{062C}', + '\u{062D}', + '\u{0645}', + '\u{062E}', + '\u{064A}', + '\u{0644}', + '\u{062C}', + '\u{0645}', + '\u{0643}', + '\u{0645}', + '\u{0645}', + '\u{0644}', + '\u{062C}', + '\u{0645}', + '\u{0646}', + '\u{062C}', + '\u{062D}', + '\u{062C}', + '\u{062D}', + '\u{064A}', + '\u{062D}', + '\u{062C}', + '\u{064A}', + '\u{0645}', + '\u{062C}', + '\u{064A}', + '\u{0641}', + '\u{0645}', + '\u{064A}', + '\u{0628}', + '\u{062D}', + '\u{064A}', + '\u{0643}', + '\u{0645}', + '\u{0645}', + '\u{0639}', + '\u{062C}', + '\u{0645}', + '\u{0635}', + '\u{0645}', + '\u{0645}', + '\u{0633}', + '\u{062E}', + '\u{064A}', + '\u{0646}', + '\u{062C}', + '\u{064A}', + '\u{0635}', + '\u{0644}', + '\u{06D2}', + '\u{0642}', + '\u{0644}', + '\u{06D2}', + '\u{0627}', + '\u{0644}', + '\u{0644}', + '\u{0647}', + '\u{0627}', + '\u{0643}', + '\u{0628}', + '\u{0631}', + '\u{0645}', + '\u{062D}', + '\u{0645}', + '\u{062F}', + '\u{0635}', + '\u{0644}', + '\u{0639}', + '\u{0645}', + '\u{0631}', + '\u{0633}', + '\u{0648}', + '\u{0644}', + '\u{0639}', + '\u{0644}', + '\u{064A}', + '\u{0647}', + '\u{0648}', + '\u{0633}', + '\u{0644}', + '\u{0645}', + '\u{0635}', + '\u{0644}', + '\u{0649}', + '\u{0635}', + '\u{0644}', + '\u{0649}', + '\u{0020}', + '\u{0627}', + '\u{0644}', + '\u{0644}', + '\u{0647}', + '\u{0020}', + '\u{0639}', + '\u{0644}', + '\u{064A}', + '\u{0647}', + '\u{0020}', + '\u{0648}', + '\u{0633}', + '\u{0644}', + '\u{0645}', + '\u{062C}', + '\u{0644}', + '\u{0020}', + '\u{062C}', + '\u{0644}', + '\u{0627}', + '\u{0644}', + '\u{0647}', + '\u{0631}', + '\u{06CC}', + '\u{0627}', + '\u{0644}', + '\u{002C}', + '\u{3001}', + '\u{3002}', + '\u{003A}', + '\u{003B}', + '\u{0021}', + '\u{003F}', + '\u{3016}', + '\u{3017}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{002E}', + '\u{2014}', + '\u{2013}', + '\u{005F}', + '\u{005F}', + '\u{0028}', + '\u{0029}', + '\u{007B}', + '\u{007D}', + '\u{3014}', + '\u{3015}', + '\u{3010}', + '\u{3011}', + '\u{300A}', + '\u{300B}', + '\u{3008}', + '\u{3009}', + '\u{300C}', + '\u{300D}', + '\u{300E}', + '\u{300F}', + '\u{005B}', + '\u{005D}', + '\u{0020}', + '\u{0305}', + '\u{0020}', + '\u{0305}', + '\u{0020}', + '\u{0305}', + '\u{0020}', + '\u{0305}', + '\u{005F}', + '\u{005F}', + '\u{005F}', + '\u{002C}', + '\u{3001}', + '\u{002E}', + '\u{003B}', + '\u{003A}', + '\u{003F}', + '\u{0021}', + '\u{2014}', + '\u{0028}', + '\u{0029}', + '\u{007B}', + '\u{007D}', + '\u{3014}', + '\u{3015}', + '\u{0023}', + '\u{0026}', + '\u{002A}', + '\u{002B}', + '\u{002D}', + '\u{003C}', + '\u{003E}', + '\u{003D}', + '\u{005C}', + '\u{0024}', + '\u{0025}', + '\u{0040}', + '\u{0020}', + '\u{064B}', + '\u{0640}', + '\u{064B}', + '\u{0020}', + '\u{064C}', + '\u{0020}', + '\u{064D}', + '\u{0020}', + '\u{064E}', + '\u{0640}', + '\u{064E}', + '\u{0020}', + '\u{064F}', + '\u{0640}', + '\u{064F}', + '\u{0020}', + '\u{0650}', + '\u{0640}', + '\u{0650}', + '\u{0020}', + '\u{0651}', + '\u{0640}', + '\u{0651}', + '\u{0020}', + '\u{0652}', + '\u{0640}', + '\u{0652}', + '\u{0621}', + '\u{0627}', + '\u{0653}', + '\u{0627}', + '\u{0653}', + '\u{0627}', + '\u{0654}', + '\u{0627}', + '\u{0654}', + '\u{0648}', + '\u{0654}', + '\u{0648}', + '\u{0654}', + '\u{0627}', + '\u{0655}', + '\u{0627}', + '\u{0655}', + '\u{064A}', + '\u{0654}', + '\u{064A}', + '\u{0654}', + '\u{064A}', + '\u{0654}', + '\u{064A}', + '\u{0654}', + '\u{0627}', + '\u{0627}', + '\u{0628}', + '\u{0628}', + '\u{0628}', + '\u{0628}', + '\u{0629}', + '\u{0629}', + '\u{062A}', + '\u{062A}', + '\u{062A}', + '\u{062A}', + '\u{062B}', + '\u{062B}', + '\u{062B}', + '\u{062B}', + '\u{062C}', + '\u{062C}', + '\u{062C}', + '\u{062C}', + '\u{062D}', + '\u{062D}', + '\u{062D}', + '\u{062D}', + '\u{062E}', + '\u{062E}', + '\u{062E}', + '\u{062E}', + '\u{062F}', + '\u{062F}', + '\u{0630}', + '\u{0630}', + '\u{0631}', + '\u{0631}', + '\u{0632}', + '\u{0632}', + '\u{0633}', + '\u{0633}', + '\u{0633}', + '\u{0633}', + '\u{0634}', + '\u{0634}', + '\u{0634}', + '\u{0634}', + '\u{0635}', + '\u{0635}', + '\u{0635}', + '\u{0635}', + '\u{0636}', + '\u{0636}', + '\u{0636}', + '\u{0636}', + '\u{0637}', + '\u{0637}', + '\u{0637}', + '\u{0637}', + '\u{0638}', + '\u{0638}', + '\u{0638}', + '\u{0638}', + '\u{0639}', + '\u{0639}', + '\u{0639}', + '\u{0639}', + '\u{063A}', + '\u{063A}', + '\u{063A}', + '\u{063A}', + '\u{0641}', + '\u{0641}', + '\u{0641}', + '\u{0641}', + '\u{0642}', + '\u{0642}', + '\u{0642}', + '\u{0642}', + '\u{0643}', + '\u{0643}', + '\u{0643}', + '\u{0643}', + '\u{0644}', + '\u{0644}', + '\u{0644}', + '\u{0644}', + '\u{0645}', + '\u{0645}', + '\u{0645}', + '\u{0645}', + '\u{0646}', + '\u{0646}', + '\u{0646}', + '\u{0646}', + '\u{0647}', + '\u{0647}', + '\u{0647}', + '\u{0647}', + '\u{0648}', + '\u{0648}', + '\u{0649}', + '\u{0649}', + '\u{064A}', + '\u{064A}', + '\u{064A}', + '\u{064A}', + '\u{0644}', + '\u{0627}', + '\u{0653}', + '\u{0644}', + '\u{0627}', + '\u{0653}', + '\u{0644}', + '\u{0627}', + '\u{0654}', + '\u{0644}', + '\u{0627}', + '\u{0654}', + '\u{0644}', + '\u{0627}', + '\u{0655}', + '\u{0644}', + '\u{0627}', + '\u{0655}', + '\u{0644}', + '\u{0627}', + '\u{0644}', + '\u{0627}', + '\u{0021}', + '\u{0022}', + '\u{0023}', + '\u{0024}', + '\u{0025}', + '\u{0026}', + '\u{0027}', + '\u{0028}', + '\u{0029}', + '\u{002A}', + '\u{002B}', + '\u{002C}', + '\u{002D}', + '\u{002E}', + '\u{002F}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{003A}', + '\u{003B}', + '\u{003C}', + '\u{003D}', + '\u{003E}', + '\u{003F}', + '\u{0040}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{005B}', + '\u{005C}', + '\u{005D}', + '\u{005E}', + '\u{005F}', + '\u{0060}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{007B}', + '\u{007C}', + '\u{007D}', + '\u{007E}', + '\u{2985}', + '\u{2986}', + '\u{3002}', + '\u{300C}', + '\u{300D}', + '\u{3001}', + '\u{30FB}', + '\u{30F2}', + '\u{30A1}', + '\u{30A3}', + '\u{30A5}', + '\u{30A7}', + '\u{30A9}', + '\u{30E3}', + '\u{30E5}', + '\u{30E7}', + '\u{30C3}', + '\u{30FC}', + '\u{30A2}', + '\u{30A4}', + '\u{30A6}', + '\u{30A8}', + '\u{30AA}', + '\u{30AB}', + '\u{30AD}', + '\u{30AF}', + '\u{30B1}', + '\u{30B3}', + '\u{30B5}', + '\u{30B7}', + '\u{30B9}', + '\u{30BB}', + '\u{30BD}', + '\u{30BF}', + '\u{30C1}', + '\u{30C4}', + '\u{30C6}', + '\u{30C8}', + '\u{30CA}', + '\u{30CB}', + '\u{30CC}', + '\u{30CD}', + '\u{30CE}', + '\u{30CF}', + '\u{30D2}', + '\u{30D5}', + '\u{30D8}', + '\u{30DB}', + '\u{30DE}', + '\u{30DF}', + '\u{30E0}', + '\u{30E1}', + '\u{30E2}', + '\u{30E4}', + '\u{30E6}', + '\u{30E8}', + '\u{30E9}', + '\u{30EA}', + '\u{30EB}', + '\u{30EC}', + '\u{30ED}', + '\u{30EF}', + '\u{30F3}', + '\u{3099}', + '\u{309A}', + '\u{1160}', + '\u{1100}', + '\u{1101}', + '\u{11AA}', + '\u{1102}', + '\u{11AC}', + '\u{11AD}', + '\u{1103}', + '\u{1104}', + '\u{1105}', + '\u{11B0}', + '\u{11B1}', + '\u{11B2}', + '\u{11B3}', + '\u{11B4}', + '\u{11B5}', + '\u{111A}', + '\u{1106}', + '\u{1107}', + '\u{1108}', + '\u{1121}', + '\u{1109}', + '\u{110A}', + '\u{110B}', + '\u{110C}', + '\u{110D}', + '\u{110E}', + '\u{110F}', + '\u{1110}', + '\u{1111}', + '\u{1112}', + '\u{1161}', + '\u{1162}', + '\u{1163}', + '\u{1164}', + '\u{1165}', + '\u{1166}', + '\u{1167}', + '\u{1168}', + '\u{1169}', + '\u{116A}', + '\u{116B}', + '\u{116C}', + '\u{116D}', + '\u{116E}', + '\u{116F}', + '\u{1170}', + '\u{1171}', + '\u{1172}', + '\u{1173}', + '\u{1174}', + '\u{1175}', + '\u{00A2}', + '\u{00A3}', + '\u{00AC}', + '\u{0020}', + '\u{0304}', + '\u{00A6}', + '\u{00A5}', + '\u{20A9}', + '\u{2502}', + '\u{2190}', + '\u{2191}', + '\u{2192}', + '\u{2193}', + '\u{25A0}', + '\u{25CB}', + '\u{02D0}', + '\u{02D1}', + '\u{00E6}', + '\u{0299}', + '\u{0253}', + '\u{02A3}', + '\u{AB66}', + '\u{02A5}', + '\u{02A4}', + '\u{0256}', + '\u{0257}', + '\u{1D91}', + '\u{0258}', + '\u{025E}', + '\u{02A9}', + '\u{0264}', + '\u{0262}', + '\u{0260}', + '\u{029B}', + '\u{0127}', + '\u{029C}', + '\u{0267}', + '\u{0284}', + '\u{02AA}', + '\u{02AB}', + '\u{026C}', + '\u{1DF04}', + '\u{A78E}', + '\u{026E}', + '\u{1DF05}', + '\u{028E}', + '\u{1DF06}', + '\u{00F8}', + '\u{0276}', + '\u{0277}', + '\u{0071}', + '\u{027A}', + '\u{1DF08}', + '\u{027D}', + '\u{027E}', + '\u{0280}', + '\u{02A8}', + '\u{02A6}', + '\u{AB67}', + '\u{02A7}', + '\u{0288}', + '\u{2C71}', + '\u{028F}', + '\u{02A1}', + '\u{02A2}', + '\u{0298}', + '\u{01C0}', + '\u{01C1}', + '\u{01C2}', + '\u{1DF0A}', + '\u{1DF1E}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0043}', + '\u{0044}', + '\u{0047}', + '\u{004A}', + '\u{004B}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0066}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004F}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0061}', + '\u{0062}', + '\u{0063}', + '\u{0064}', + '\u{0065}', + '\u{0066}', + '\u{0067}', + '\u{0068}', + '\u{0069}', + '\u{006A}', + '\u{006B}', + '\u{006C}', + '\u{006D}', + '\u{006E}', + '\u{006F}', + '\u{0070}', + '\u{0071}', + '\u{0072}', + '\u{0073}', + '\u{0074}', + '\u{0075}', + '\u{0076}', + '\u{0077}', + '\u{0078}', + '\u{0079}', + '\u{007A}', + '\u{0131}', + '\u{0237}', + '\u{0391}', + '\u{0392}', + '\u{0393}', + '\u{0394}', + '\u{0395}', + '\u{0396}', + '\u{0397}', + '\u{0398}', + '\u{0399}', + '\u{039A}', + '\u{039B}', + '\u{039C}', + '\u{039D}', + '\u{039E}', + '\u{039F}', + '\u{03A0}', + '\u{03A1}', + '\u{0398}', + '\u{03A3}', + '\u{03A4}', + '\u{03A5}', + '\u{03A6}', + '\u{03A7}', + '\u{03A8}', + '\u{03A9}', + '\u{2207}', + '\u{03B1}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03B5}', + '\u{03B6}', + '\u{03B7}', + '\u{03B8}', + '\u{03B9}', + '\u{03BA}', + '\u{03BB}', + '\u{03BC}', + '\u{03BD}', + '\u{03BE}', + '\u{03BF}', + '\u{03C0}', + '\u{03C1}', + '\u{03C2}', + '\u{03C3}', + '\u{03C4}', + '\u{03C5}', + '\u{03C6}', + '\u{03C7}', + '\u{03C8}', + '\u{03C9}', + '\u{2202}', + '\u{03B5}', + '\u{03B8}', + '\u{03BA}', + '\u{03C6}', + '\u{03C1}', + '\u{03C0}', + '\u{0391}', + '\u{0392}', + '\u{0393}', + '\u{0394}', + '\u{0395}', + '\u{0396}', + '\u{0397}', + '\u{0398}', + '\u{0399}', + '\u{039A}', + '\u{039B}', + '\u{039C}', + '\u{039D}', + '\u{039E}', + '\u{039F}', + '\u{03A0}', + '\u{03A1}', + '\u{0398}', + '\u{03A3}', + '\u{03A4}', + '\u{03A5}', + '\u{03A6}', + '\u{03A7}', + '\u{03A8}', + '\u{03A9}', + '\u{2207}', + '\u{03B1}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03B5}', + '\u{03B6}', + '\u{03B7}', + '\u{03B8}', + '\u{03B9}', + '\u{03BA}', + '\u{03BB}', + '\u{03BC}', + '\u{03BD}', + '\u{03BE}', + '\u{03BF}', + '\u{03C0}', + '\u{03C1}', + '\u{03C2}', + '\u{03C3}', + '\u{03C4}', + '\u{03C5}', + '\u{03C6}', + '\u{03C7}', + '\u{03C8}', + '\u{03C9}', + '\u{2202}', + '\u{03B5}', + '\u{03B8}', + '\u{03BA}', + '\u{03C6}', + '\u{03C1}', + '\u{03C0}', + '\u{0391}', + '\u{0392}', + '\u{0393}', + '\u{0394}', + '\u{0395}', + '\u{0396}', + '\u{0397}', + '\u{0398}', + '\u{0399}', + '\u{039A}', + '\u{039B}', + '\u{039C}', + '\u{039D}', + '\u{039E}', + '\u{039F}', + '\u{03A0}', + '\u{03A1}', + '\u{0398}', + '\u{03A3}', + '\u{03A4}', + '\u{03A5}', + '\u{03A6}', + '\u{03A7}', + '\u{03A8}', + '\u{03A9}', + '\u{2207}', + '\u{03B1}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03B5}', + '\u{03B6}', + '\u{03B7}', + '\u{03B8}', + '\u{03B9}', + '\u{03BA}', + '\u{03BB}', + '\u{03BC}', + '\u{03BD}', + '\u{03BE}', + '\u{03BF}', + '\u{03C0}', + '\u{03C1}', + '\u{03C2}', + '\u{03C3}', + '\u{03C4}', + '\u{03C5}', + '\u{03C6}', + '\u{03C7}', + '\u{03C8}', + '\u{03C9}', + '\u{2202}', + '\u{03B5}', + '\u{03B8}', + '\u{03BA}', + '\u{03C6}', + '\u{03C1}', + '\u{03C0}', + '\u{0391}', + '\u{0392}', + '\u{0393}', + '\u{0394}', + '\u{0395}', + '\u{0396}', + '\u{0397}', + '\u{0398}', + '\u{0399}', + '\u{039A}', + '\u{039B}', + '\u{039C}', + '\u{039D}', + '\u{039E}', + '\u{039F}', + '\u{03A0}', + '\u{03A1}', + '\u{0398}', + '\u{03A3}', + '\u{03A4}', + '\u{03A5}', + '\u{03A6}', + '\u{03A7}', + '\u{03A8}', + '\u{03A9}', + '\u{2207}', + '\u{03B1}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03B5}', + '\u{03B6}', + '\u{03B7}', + '\u{03B8}', + '\u{03B9}', + '\u{03BA}', + '\u{03BB}', + '\u{03BC}', + '\u{03BD}', + '\u{03BE}', + '\u{03BF}', + '\u{03C0}', + '\u{03C1}', + '\u{03C2}', + '\u{03C3}', + '\u{03C4}', + '\u{03C5}', + '\u{03C6}', + '\u{03C7}', + '\u{03C8}', + '\u{03C9}', + '\u{2202}', + '\u{03B5}', + '\u{03B8}', + '\u{03BA}', + '\u{03C6}', + '\u{03C1}', + '\u{03C0}', + '\u{0391}', + '\u{0392}', + '\u{0393}', + '\u{0394}', + '\u{0395}', + '\u{0396}', + '\u{0397}', + '\u{0398}', + '\u{0399}', + '\u{039A}', + '\u{039B}', + '\u{039C}', + '\u{039D}', + '\u{039E}', + '\u{039F}', + '\u{03A0}', + '\u{03A1}', + '\u{0398}', + '\u{03A3}', + '\u{03A4}', + '\u{03A5}', + '\u{03A6}', + '\u{03A7}', + '\u{03A8}', + '\u{03A9}', + '\u{2207}', + '\u{03B1}', + '\u{03B2}', + '\u{03B3}', + '\u{03B4}', + '\u{03B5}', + '\u{03B6}', + '\u{03B7}', + '\u{03B8}', + '\u{03B9}', + '\u{03BA}', + '\u{03BB}', + '\u{03BC}', + '\u{03BD}', + '\u{03BE}', + '\u{03BF}', + '\u{03C0}', + '\u{03C1}', + '\u{03C2}', + '\u{03C3}', + '\u{03C4}', + '\u{03C5}', + '\u{03C6}', + '\u{03C7}', + '\u{03C8}', + '\u{03C9}', + '\u{2202}', + '\u{03B5}', + '\u{03B8}', + '\u{03BA}', + '\u{03C6}', + '\u{03C1}', + '\u{03C0}', + '\u{03DC}', + '\u{03DD}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', + '\u{0430}', + '\u{0431}', + '\u{0432}', + '\u{0433}', + '\u{0434}', + '\u{0435}', + '\u{0436}', + '\u{0437}', + '\u{0438}', + '\u{043A}', + '\u{043B}', + '\u{043C}', + '\u{043E}', + '\u{043F}', + '\u{0440}', + '\u{0441}', + '\u{0442}', + '\u{0443}', + '\u{0444}', + '\u{0445}', + '\u{0446}', + '\u{0447}', + '\u{0448}', + '\u{044B}', + '\u{044D}', + '\u{044E}', + '\u{A689}', + '\u{04D9}', + '\u{0456}', + '\u{0458}', + '\u{04E9}', + '\u{04AF}', + '\u{04CF}', + '\u{0430}', + '\u{0431}', + '\u{0432}', + '\u{0433}', + '\u{0434}', + '\u{0435}', + '\u{0436}', + '\u{0437}', + '\u{0438}', + '\u{043A}', + '\u{043B}', + '\u{043E}', + '\u{043F}', + '\u{0441}', + '\u{0443}', + '\u{0444}', + '\u{0445}', + '\u{0446}', + '\u{0447}', + '\u{0448}', + '\u{044A}', + '\u{044B}', + '\u{0491}', + '\u{0456}', + '\u{0455}', + '\u{045F}', + '\u{04AB}', + '\u{A651}', + '\u{04B1}', + '\u{0627}', + '\u{0628}', + '\u{062C}', + '\u{062F}', + '\u{0648}', + '\u{0632}', + '\u{062D}', + '\u{0637}', + '\u{064A}', + '\u{0643}', + '\u{0644}', + '\u{0645}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0641}', + '\u{0635}', + '\u{0642}', + '\u{0631}', + '\u{0634}', + '\u{062A}', + '\u{062B}', + '\u{062E}', + '\u{0630}', + '\u{0636}', + '\u{0638}', + '\u{063A}', + '\u{066E}', + '\u{06BA}', + '\u{06A1}', + '\u{066F}', + '\u{0628}', + '\u{062C}', + '\u{0647}', + '\u{062D}', + '\u{064A}', + '\u{0643}', + '\u{0644}', + '\u{0645}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0641}', + '\u{0635}', + '\u{0642}', + '\u{0634}', + '\u{062A}', + '\u{062B}', + '\u{062E}', + '\u{0636}', + '\u{063A}', + '\u{062C}', + '\u{062D}', + '\u{064A}', + '\u{0644}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0635}', + '\u{0642}', + '\u{0634}', + '\u{062E}', + '\u{0636}', + '\u{063A}', + '\u{06BA}', + '\u{066F}', + '\u{0628}', + '\u{062C}', + '\u{0647}', + '\u{062D}', + '\u{0637}', + '\u{064A}', + '\u{0643}', + '\u{0645}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0641}', + '\u{0635}', + '\u{0642}', + '\u{0634}', + '\u{062A}', + '\u{062B}', + '\u{062E}', + '\u{0636}', + '\u{0638}', + '\u{063A}', + '\u{066E}', + '\u{06A1}', + '\u{0627}', + '\u{0628}', + '\u{062C}', + '\u{062F}', + '\u{0647}', + '\u{0648}', + '\u{0632}', + '\u{062D}', + '\u{0637}', + '\u{064A}', + '\u{0644}', + '\u{0645}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0641}', + '\u{0635}', + '\u{0642}', + '\u{0631}', + '\u{0634}', + '\u{062A}', + '\u{062B}', + '\u{062E}', + '\u{0630}', + '\u{0636}', + '\u{0638}', + '\u{063A}', + '\u{0628}', + '\u{062C}', + '\u{062F}', + '\u{0648}', + '\u{0632}', + '\u{062D}', + '\u{0637}', + '\u{064A}', + '\u{0644}', + '\u{0645}', + '\u{0646}', + '\u{0633}', + '\u{0639}', + '\u{0641}', + '\u{0635}', + '\u{0642}', + '\u{0631}', + '\u{0634}', + '\u{062A}', + '\u{062B}', + '\u{062E}', + '\u{0630}', + '\u{0636}', + '\u{0638}', + '\u{063A}', + '\u{0030}', + '\u{002E}', + '\u{0030}', + '\u{002C}', + '\u{0031}', + '\u{002C}', + '\u{0032}', + '\u{002C}', + '\u{0033}', + '\u{002C}', + '\u{0034}', + '\u{002C}', + '\u{0035}', + '\u{002C}', + '\u{0036}', + '\u{002C}', + '\u{0037}', + '\u{002C}', + '\u{0038}', + '\u{002C}', + '\u{0039}', + '\u{002C}', + '\u{0028}', + '\u{0041}', + '\u{0029}', + '\u{0028}', + '\u{0042}', + '\u{0029}', + '\u{0028}', + '\u{0043}', + '\u{0029}', + '\u{0028}', + '\u{0044}', + '\u{0029}', + '\u{0028}', + '\u{0045}', + '\u{0029}', + '\u{0028}', + '\u{0046}', + '\u{0029}', + '\u{0028}', + '\u{0047}', + '\u{0029}', + '\u{0028}', + '\u{0048}', + '\u{0029}', + '\u{0028}', + '\u{0049}', + '\u{0029}', + '\u{0028}', + '\u{004A}', + '\u{0029}', + '\u{0028}', + '\u{004B}', + '\u{0029}', + '\u{0028}', + '\u{004C}', + '\u{0029}', + '\u{0028}', + '\u{004D}', + '\u{0029}', + '\u{0028}', + '\u{004E}', + '\u{0029}', + '\u{0028}', + '\u{004F}', + '\u{0029}', + '\u{0028}', + '\u{0050}', + '\u{0029}', + '\u{0028}', + '\u{0051}', + '\u{0029}', + '\u{0028}', + '\u{0052}', + '\u{0029}', + '\u{0028}', + '\u{0053}', + '\u{0029}', + '\u{0028}', + '\u{0054}', + '\u{0029}', + '\u{0028}', + '\u{0055}', + '\u{0029}', + '\u{0028}', + '\u{0056}', + '\u{0029}', + '\u{0028}', + '\u{0057}', + '\u{0029}', + '\u{0028}', + '\u{0058}', + '\u{0029}', + '\u{0028}', + '\u{0059}', + '\u{0029}', + '\u{0028}', + '\u{005A}', + '\u{0029}', + '\u{3014}', + '\u{0053}', + '\u{3015}', + '\u{0043}', + '\u{0052}', + '\u{0043}', + '\u{0044}', + '\u{0057}', + '\u{005A}', + '\u{0041}', + '\u{0042}', + '\u{0043}', + '\u{0044}', + '\u{0045}', + '\u{0046}', + '\u{0047}', + '\u{0048}', + '\u{0049}', + '\u{004A}', + '\u{004B}', + '\u{004C}', + '\u{004D}', + '\u{004E}', + '\u{004F}', + '\u{0050}', + '\u{0051}', + '\u{0052}', + '\u{0053}', + '\u{0054}', + '\u{0055}', + '\u{0056}', + '\u{0057}', + '\u{0058}', + '\u{0059}', + '\u{005A}', + '\u{0048}', + '\u{0056}', + '\u{004D}', + '\u{0056}', + '\u{0053}', + '\u{0044}', + '\u{0053}', + '\u{0053}', + '\u{0050}', + '\u{0050}', + '\u{0056}', + '\u{0057}', + '\u{0043}', + '\u{004D}', + '\u{0043}', + '\u{004D}', + '\u{0044}', + '\u{004D}', + '\u{0052}', + '\u{0044}', + '\u{004A}', + '\u{307B}', + '\u{304B}', + '\u{30B3}', + '\u{30B3}', + '\u{30B5}', + '\u{624B}', + '\u{5B57}', + '\u{53CC}', + '\u{30C6}', + '\u{3099}', + '\u{4E8C}', + '\u{591A}', + '\u{89E3}', + '\u{5929}', + '\u{4EA4}', + '\u{6620}', + '\u{7121}', + '\u{6599}', + '\u{524D}', + '\u{5F8C}', + '\u{518D}', + '\u{65B0}', + '\u{521D}', + '\u{7D42}', + '\u{751F}', + '\u{8CA9}', + '\u{58F0}', + '\u{5439}', + '\u{6F14}', + '\u{6295}', + '\u{6355}', + '\u{4E00}', + '\u{4E09}', + '\u{904A}', + '\u{5DE6}', + '\u{4E2D}', + '\u{53F3}', + '\u{6307}', + '\u{8D70}', + '\u{6253}', + '\u{7981}', + '\u{7A7A}', + '\u{5408}', + '\u{6E80}', + '\u{6709}', + '\u{6708}', + '\u{7533}', + '\u{5272}', + '\u{55B6}', + '\u{914D}', + '\u{3014}', + '\u{672C}', + '\u{3015}', + '\u{3014}', + '\u{4E09}', + '\u{3015}', + '\u{3014}', + '\u{4E8C}', + '\u{3015}', + '\u{3014}', + '\u{5B89}', + '\u{3015}', + '\u{3014}', + '\u{70B9}', + '\u{3015}', + '\u{3014}', + '\u{6253}', + '\u{3015}', + '\u{3014}', + '\u{76D7}', + '\u{3015}', + '\u{3014}', + '\u{52DD}', + '\u{3015}', + '\u{3014}', + '\u{6557}', + '\u{3015}', + '\u{5F97}', + '\u{53EF}', + '\u{0030}', + '\u{0031}', + '\u{0032}', + '\u{0033}', + '\u{0034}', + '\u{0035}', + '\u{0036}', + '\u{0037}', + '\u{0038}', + '\u{0039}', +]; + +pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ + 0x000, 0x000, 0x00A, 0x000, 0x000, 0x000, 0x001, 0x1B9F, 0x004, 0xF3F, 0x005, 0x185, 0x000, + 0x000, 0x001, 0x000, 0x001, 0x002, 0x19D, 0x000, 0x099, 0x000, 0x03E, 0x000, 0x00A, 0x3FC, + 0x0A1, 0x000, 0x000, 0x000, 0x000, 0x001, 0x1EA, 0x000, 0x59B, 0x001, 0x3D6, 0x000, 0x078, + 0x000, 0x2F7, 0x017, 0x00E, 0x0BA, 0x0B8, 0x000, 0x0A3, 0x089, 0x007, 0x014, 0x000, 0x000, + 0x000, 0x003, 0x000, 0x000, 0x000, 0x243, 0x047, 0x005, 0x000, 0x000, 0x13F, 0x009, 0x001, + 0x000, 0x000, 0x004, 0x015, 0x001, 0x0D6, 0x01C, 0x000, 0x002, 0x0FF, 0x1B5, 0x000, 0x000, + 0x002, 0x001, 0x006, 0x000, 0x0EC, 0x004, 0x038, 0x0F3, 0x000, 0x00A, 0x01A, 0x001, 0x000, + 0x0A1, 0x000, 0x000, 0x013, 0x0CC, 0x05C, 0x007, 0x000, 0x052, 0x000, 0x00D, 0x000, 0x000, + 0x043, 0x001, 0x004, 0x003, 0x05D, 0x11C, 0x004, 0x001, 0x000, 0x000, 0x053, 0x008, 0x000, + 0x000, 0x002, 0x000, 0x01E, 0x04D, 0x000, 0x022, 0x001, 0x01F, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x01E, 0x022, 0x013, 0x007, 0x004, 0x000, 0x060, 0x005, 0x000, 0x000, 0x000, 0x004, + 0x06A, 0x000, 0x000, 0x000, 0x088, 0x001, 0x000, 0x07F, 0x000, 0x002, 0x000, 0x000, 0x00D, + 0x038, 0x0A7, 0x049, 0x0D5, 0x001, 0x028, 0x004, 0x002, 0x000, 0x030, 0x00A, 0x001, 0x0F0, + 0x024, 0x002, 0x031, 0x09B, 0x000, 0x090, 0x003, 0x00B, 0x003, 0x002, 0x000, 0x057, 0x000, + 0x004, 0x000, 0x000, 0x000, 0x000, 0x005, 0x000, 0x03A, 0x006, 0x00E, 0x007, 0x000, 0x089, + 0x000, 0x000, 0x001, 0x005, 0x006, 0x02F, 0x000, 0x068, 0x001, 0x000, 0x043, 0x000, 0x028, + 0x000, 0x000, 0x0A4, 0x035, 0x013, 0x01F, 0x02F, 0x002, 0x011, 0x052, 0x008, 0x000, 0x000, + 0x013, 0x014, 0x000, 0x024, 0x000, 0x000, 0x001, 0x02C, 0x001, 0x000, 0x000, 0x014, 0x00C, + 0x016, 0x000, 0x000, 0x008, 0x00A, 0x006, 0x000, 0x000, 0x00D, 0x000, 0x0A9, 0x000, 0x000, + 0x000, 0x000, 0x009, 0x000, 0x000, 0x001, 0x000, 0x000, 0x002, 0x012, 0x000, 0x000, 0x036, + 0x002, 0x01E, 0x004, 0x00C, 0x000, 0x002, 0x000, 0x012, 0x001, 0x035, 0x000, 0x000, 0x00A, + 0x007, 0x015, 0x005, 0x01C, 0x024, 0x07A, 0x000, 0x005, 0x001, 0x012, 0x000, 0x004, 0x001, + 0x005, 0x010, 0x009, 0x000, 0x020, 0x01B, 0x006, 0x01E, 0x005, 0x04A, 0x000, 0x004, 0x000, + 0x014, 0x000, 0x009, 0x065, 0x000, 0x001, 0x000, 0x074, 0x000, 0x000, 0x045, 0x001, 0x000, + 0x000, 0x008, 0x000, 0x000, 0x017, 0x000, 0x000, 0x006, 0x000, 0x002, 0x000, 0x005, 0x000, + 0x01B, 0x000, 0x017, 0x000, 0x001, 0x003, 0x029, 0x002, 0x002, 0x007, 0x007, 0x001, 0x001, + 0x03A, 0x001, 0x001, 0x000, 0x003, 0x000, 0x004, 0x001, 0x011, 0x016, 0x000, 0x002, 0x000, + 0x002, 0x002, 0x002, 0x006, 0x000, 0x046, 0x000, 0x002, 0x000, 0x000, 0x00D, 0x011, 0x000, + 0x000, 0x01B, 0x03D, 0x007, 0x024, 0x019, 0x008, 0x05C, 0x000, 0x028, 0x004, 0x014, 0x002, + 0x004, 0x001, 0x001, 0x001, 0x000, 0x008, 0x008, 0x012, 0x002, 0x052, 0x00F, 0x000, 0x000, + 0x000, 0x007, 0x006, 0x000, 0x01E, 0x01D, 0x001, 0x010, 0x000, 0x000, 0x000, 0x001, 0x001, + 0x000, 0x004, 0x006, 0x017, 0x006, 0x004, 0x003, 0x003, 0x03E, 0x000, 0x002, 0x007, 0x023, + 0x000, 0x000, 0x001, 0x000, 0x000, 0x004, 0x007, 0x021, 0x010, 0x019, 0x005, 0x000, 0x007, + 0x000, 0x001, 0x000, 0x000, 0x000, 0x00C, 0x012, 0x02E, 0x000, 0x013, 0x027, 0x000, 0x013, + 0x000, 0x000, 0x006, 0x02C, 0x000, 0x006, 0x000, 0x00E, 0x001, 0x001, 0x005, 0x002, 0x004, + 0x016, 0x00D, 0x012, 0x008, 0x000, 0x001, 0x003, 0x000, 0x000, 0x001, 0x000, 0x000, 0x010, + 0x000, 0x000, 0x00B, 0x000, 0x000, 0x007, 0x004, 0x00F, 0x008, 0x001, 0x006, 0x001, 0x004, + 0x004, 0x00A, 0x002, 0x000, 0x002, 0x003, 0x005, 0x000, 0x000, 0x00B, 0x00B, 0x000, 0x005, + 0x003, 0x000, 0x000, 0x004, 0x004, 0x01C, 0x020, 0x000, 0x000, 0x000, 0x000, 0x013, 0x00D, + 0x00A, 0x003, 0x000, 0x00C, 0x00B, 0x000, 0x001, 0x000, 0x000, 0x003, 0x001, 0x001, 0x03E, + 0x000, 0x001, 0x017, 0x000, 0x019, 0x010, 0x003, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, + 0x008, 0x001, 0x000, 0x007, 0x003, 0x010, 0x001, 0x000, 0x002, 0x009, 0x000, 0x08B, 0x000, + 0x005, 0x000, 0x008, 0x000, 0x005, 0x012, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x001, 0x046, 0x000, 0x004, 0x00C, 0x000, 0x001, 0x006, 0x000, 0x014, 0x005, 0x01A, 0x007, + 0x000, 0x002, 0x005, 0x000, 0x007, 0x001, 0x020, 0x00D, 0x00B, 0x02B, 0x000, 0x01B, 0x000, + 0x003, 0x000, 0x001, 0x01A, 0x001, 0x004, 0x000, 0x000, 0x007, 0x000, 0x00C, 0x01B, 0x023, + 0x002, 0x000, 0x019, 0x01F, 0x001, 0x010, 0x008, 0x00A, 0x000, 0x000, 0x006, 0x002, 0x002, + 0x002, 0x012, 0x009, 0x01E, 0x004, 0x000, 0x00B, 0x004, 0x008, 0x01E, 0x003, 0x006, 0x00C, + 0x000, 0x000, 0x002, 0x000, 0x00A, 0x000, 0x01B, 0x000, 0x001, 0x009, 0x000, 0x00F, 0x002, + 0x000, 0x00A, 0x000, 0x008, 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x00C, 0x00C, 0x001, + 0x000, 0x000, 0x004, 0x000, 0x005, 0x000, 0x022, 0x002, 0x00F, 0x015, 0x00D, 0x000, 0x000, + 0x001, 0x000, 0x016, 0x000, 0x000, 0x000, 0x000, 0x008, 0x000, 0x000, 0x001, 0x000, 0x000, + 0x004, 0x001, 0x001, 0x004, 0x002, 0x002, 0x00F, 0x00A, 0x014, 0x000, 0x000, 0x001, 0x002, + 0x000, 0x002, 0x00F, 0x000, 0x000, 0x007, 0x000, 0x026, 0x000, 0x035, 0x009, 0x000, 0x005, + 0x002, 0x000, 0x00F, 0x003, 0x003, 0x006, 0x000, 0x02F, 0x002, 0x000, 0x007, 0x000, 0x000, + 0x001, 0x008, 0x016, 0x003, 0x000, 0x000, 0x016, 0x000, 0x002, 0x000, 0x00D, 0x000, 0x001, + 0x000, 0x005, 0x001, 0x00A, 0x000, 0x000, 0x002, 0x00A, 0x001, 0x000, 0x000, 0x006, 0x001, + 0x000, 0x003, 0x002, 0x015, 0x000, 0x002, 0x000, 0x000, 0x003, 0x001, 0x008, 0x002, 0x000, + 0x006, 0x000, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00D, 0x014, 0x000, 0x001, + 0x000, 0x004, 0x000, 0x003, 0x002, 0x000, 0x000, 0x004, 0x019, 0x006, 0x007, 0x013, 0x019, + 0x003, 0x00B, 0x008, 0x013, 0x007, 0x002, 0x009, 0x000, 0x000, 0x019, 0x016, 0x002, 0x015, + 0x000, 0x004, 0x000, 0x007, 0x000, 0x008, 0x000, 0x000, 0x007, 0x001, 0x006, 0x01E, 0x01B, + 0x000, 0x00C, 0x003, 0x00F, 0x000, 0x000, 0x001, 0x00A, 0x000, 0x000, 0x000, 0x006, 0x016, + 0x006, 0x002, 0x000, 0x015, 0x006, 0x004, 0x002, 0x009, 0x000, 0x009, 0x002, 0x000, 0x00A, + 0x000, 0x000, 0x005, 0x00C, 0x000, 0x005, 0x001, 0x004, 0x000, 0x00A, 0x001, 0x004, 0x008, + 0x00E, 0x000, 0x001, 0x002, 0x006, 0x001, 0x000, 0x024, 0x000, 0x000, 0x003, 0x001, 0x000, + 0x004, 0x002, 0x000, 0x016, 0x001, 0x009, 0x000, 0x007, 0x000, 0x017, 0x001, 0x000, 0x005, + 0x016, 0x002, 0x01F, 0x000, 0x000, 0x002, 0x000, 0x000, 0x00A, 0x001, 0x00A, 0x000, 0x007, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x005, 0x000, 0x005, 0x00B, 0x00C, 0x000, 0x000, + 0x001, 0x004, 0x006, 0x003, 0x001, 0x016, 0x001, 0x000, 0x000, 0x001, 0x004, 0x000, 0x001, + 0x019, 0x003, 0x003, 0x004, 0x005, 0x001, 0x01D, 0x000, 0x000, 0x007, 0x001, 0x001, 0x01F, + 0x000, 0x000, 0x001, 0x02B, 0x006, 0x010, 0x000, 0x009, 0x006, 0x00C, 0x00A, 0x002, 0x000, + 0x000, 0x001, 0x00C, 0x000, 0x000, 0x000, 0x016, 0x000, 0x000, 0x016, 0x00C, 0x00F, 0x000, + 0x010, 0x002, 0x000, 0x00C, 0x01C, 0x002, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000, + 0x003, 0x017, 0x004, 0x01C, 0x005, 0x00C, 0x001, 0x007, 0x004, 0x000, 0x001, 0x002, 0x000, + 0x00E, 0x00F, 0x002, 0x009, 0x001, 0x006, 0x020, 0x00B, 0x000, 0x000, 0x001, 0x00B, 0x002, + 0x002, 0x000, 0x000, 0x000, 0x007, 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x000, 0x007, + 0x000, 0x003, 0x006, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x00B, 0x002, 0x000, 0x006, + 0x001, 0x001, 0x000, 0x00E, 0x00C, 0x000, 0x006, 0x000, 0x000, 0x00E, 0x000, 0x003, 0x001, + 0x000, 0x000, 0x023, 0x009, 0x007, 0x000, 0x000, 0x011, 0x012, 0x000, 0x000, 0x006, 0x001, + 0x001, 0x000, 0x00D, 0x008, 0x007, 0x002, 0x029, 0x003, 0x008, 0x004, 0x002, 0x00C, 0x001, + 0x000, 0x001, 0x00E, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x002, 0x000, 0x007, + 0x005, 0x004, 0x000, 0x000, 0x002, 0x005, 0x005, 0x005, 0x001, 0x007, 0x002, 0x00C, 0x000, + 0x003, 0x008, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x006, 0x003, 0x008, + 0x000, 0x000, 0x006, 0x003, 0x004, 0x015, 0x000, 0x007, 0x005, 0x004, 0x000, 0x008, 0x000, + 0x006, 0x000, 0x006, 0x004, 0x002, 0x000, 0x00F, 0x001, 0x000, 0x000, 0x000, 0x002, 0x007, + 0x000, 0x01A, 0x008, 0x000, 0x000, 0x001, 0x003, 0x000, 0x00C, 0x000, 0x000, 0x001, 0x005, + 0x00C, 0x000, 0x000, 0x004, 0x002, 0x000, 0x003, 0x006, 0x001, 0x004, 0x00A, 0x000, 0x002, + 0x000, 0x000, 0x005, 0x007, 0x001, 0x013, 0x01A, 0x001, 0x003, 0x000, 0x003, 0x000, 0x000, + 0x006, 0x010, 0x000, 0x002, 0x019, 0x00B, 0x001, 0x00E, 0x000, 0x006, 0x016, 0x014, 0x000, + 0x000, 0x000, 0x004, 0x000, 0x000, 0x005, 0x002, 0x00B, 0x002, 0x016, 0x000, 0x000, 0x003, + 0x001, 0x000, 0x001, 0x000, 0x00C, 0x002, 0x014, 0x000, 0x000, 0x004, 0x003, 0x009, 0x009, + 0x000, 0x001, 0x000, 0x000, 0x002, 0x001, 0x001, 0x000, 0x001, 0x000, 0x001, 0x007, 0x005, + 0x005, 0x000, 0x000, 0x001, 0x003, 0x003, 0x002, 0x011, 0x01C, 0x002, 0x011, 0x003, 0x000, + 0x00D, 0x002, 0x001, 0x001, 0x030, 0x00B, 0x007, 0x000, 0x000, 0x01C, 0x001, 0x001, 0x003, + 0x002, 0x000, 0x001, 0x00D, 0x000, 0x009, 0x000, 0x001, 0x001, 0x006, 0x006, 0x002, 0x000, + 0x001, 0x003, 0x00D, 0x004, 0x003, 0x011, 0x005, 0x000, 0x009, 0x000, 0x000, 0x000, 0x002, + 0x002, 0x014, 0x000, 0x000, 0x000, 0x001, 0x004, 0x001, 0x000, 0x001, 0x003, 0x000, 0x000, + 0x002, 0x000, 0x009, 0x003, 0x000, 0x000, 0x000, 0x002, 0x000, 0x007, 0x003, 0x001, 0x000, + 0x003, 0x005, 0x010, 0x001, 0x000, 0x013, 0x000, 0x003, 0x005, 0x000, 0x002, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x003, 0x004, 0x003, 0x001, 0x00D, 0x000, 0x001, 0x002, 0x000, + 0x008, 0x007, 0x001, 0x003, 0x000, 0x000, 0x000, 0x00E, 0x004, 0x000, 0x006, 0x00D, 0x000, + 0x000, 0x000, 0x003, 0x000, 0x000, 0x003, 0x000, 0x000, 0x020, 0x00A, 0x000, 0x001, 0x002, + 0x000, 0x000, 0x000, 0x007, 0x008, 0x000, 0x008, 0x01F, 0x001, 0x000, 0x013, 0x008, 0x001, + 0x00A, 0x005, 0x004, 0x008, 0x001, 0x001, 0x000, 0x001, 0x004, 0x003, 0x006, 0x002, 0x001, + 0x000, 0x000, 0x000, 0x005, 0x000, 0x001, 0x000, 0x000, 0x000, 0x004, 0x000, 0x000, 0x00C, + 0x002, 0x007, 0x000, 0x000, 0x00C, 0x003, 0x000, 0x000, 0x009, 0x002, 0x001, 0x004, 0x000, + 0x000, 0x000, 0x000, 0x008, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x009, 0x007, 0x00F, + 0x001, 0x024, 0x00C, 0x002, 0x001, 0x000, 0x000, 0x000, 0x008, 0x001, 0x009, 0x00B, 0x000, + 0x00F, 0x002, 0x001, 0x000, 0x000, 0x000, 0x01C, 0x002, 0x001, 0x001, 0x003, 0x001, 0x001, + 0x000, 0x000, 0x005, 0x001, 0x000, 0x000, 0x000, 0x001, 0x006, 0x009, 0x002, 0x007, 0x005, + 0x00C, 0x002, 0x001, 0x006, 0x003, 0x002, 0x003, 0x002, 0x004, 0x003, 0x003, 0x007, 0x000, + 0x001, 0x004, 0x00A, 0x000, 0x001, 0x004, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x003, + 0x003, 0x001, 0x001, 0x008, 0x035, 0x000, 0x003, 0x002, 0x000, 0x002, 0x001, 0x000, 0x001, + 0x001, 0x002, 0x000, 0x00B, 0x002, 0x001, 0x000, 0x000, 0x006, 0x000, 0x004, 0x007, 0x001, + 0x004, 0x004, 0x002, 0x000, 0x000, 0x003, 0x002, 0x001, 0x000, 0x000, 0x00C, 0x002, 0x00B, + 0x001, 0x00C, 0x000, 0x000, 0x001, 0x000, 0x003, 0x014, 0x001, 0x003, 0x001, 0x001, 0x009, + 0x000, 0x005, 0x003, 0x00A, 0x000, 0x001, 0x009, 0x007, 0x000, 0x005, 0x000, 0x003, 0x002, + 0x000, 0x000, 0x00C, 0x00C, 0x00C, 0x00E, 0x000, 0x004, 0x001, 0x000, 0x002, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x001, 0x000, 0x001, 0x003, 0x004, 0x001, + 0x002, 0x002, 0x000, 0x005, 0x000, 0x005, 0x00C, 0x000, 0x000, 0x004, 0x001, 0x000, 0x000, + 0x034, 0x007, 0x003, 0x00A, 0x000, 0x000, 0x000, 0x002, 0x004, 0x005, 0x000, 0x002, 0x008, + 0x000, 0x000, 0x000, 0x006, 0x001, 0x000, 0x003, 0x000, 0x008, 0x010, 0x000, 0x004, 0x000, + 0x000, 0x000, 0x004, 0x000, 0x002, 0x002, 0x000, 0x003, 0x003, 0x001, 0x004, 0x000, 0x005, + 0x011, 0x001, 0x001, 0x002, 0x00C, 0x009, 0x00A, 0x000, 0x002, 0x004, 0x001, 0x021, 0x000, + 0x000, 0x000, 0x001, 0x005, 0x000, 0x006, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x001, 0x00C, 0x000, 0x001, 0x001, 0x000, 0x000, 0x007, 0x000, 0x000, 0x000, 0x002, 0x001, + 0x000, 0x001, 0x001, 0x002, 0x000, 0x008, 0x009, 0x005, 0x001, 0x003, 0x005, 0x002, 0x000, + 0x004, 0x002, 0x000, 0x000, 0x001, 0x002, 0x006, 0x007, 0x006, 0x003, 0x009, 0x000, 0x006, + 0x000, 0x006, 0x006, 0x007, 0x004, 0x000, 0x022, 0x002, 0x002, 0x002, 0x002, 0x008, 0x004, + 0x000, 0x004, 0x000, 0x009, 0x003, 0x001, 0x00A, 0x005, 0x002, 0x000, 0x000, 0x002, 0x007, + 0x001, 0x001, 0x006, 0x000, 0x001, 0x003, 0x000, 0x002, 0x001, 0x000, 0x005, 0x007, 0x001, + 0x027, 0x002, 0x008, 0x000, 0x001, 0x002, 0x003, 0x000, 0x000, 0x002, 0x001, 0x009, 0x002, + 0x001, 0x000, 0x002, 0x001, 0x011, 0x009, 0x000, 0x002, 0x001, 0x000, 0x00C, 0x007, 0x003, + 0x004, 0x007, 0x001, 0x00C, 0x001, 0x009, 0x000, 0x005, 0x002, 0x000, 0x009, 0x001, 0x001, + 0x003, 0x000, 0x007, 0x000, 0x00F, 0x000, 0x000, 0x000, 0x002, 0x002, 0x009, 0x000, 0x00A, + 0x002, 0x000, 0x000, 0x007, 0x005, 0x000, 0x001, 0x000, 0x005, 0x000, 0x009, 0x000, 0x001, + 0x002, 0x000, 0x000, 0x005, 0x009, 0x004, 0x003, 0x004, 0x000, 0x002, 0x001, 0x004, 0x001, + 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x009, 0x007, 0x000, 0x001, 0x005, 0x009, + 0x002, 0x00F, 0x001, 0x003, 0x001, 0x000, 0x000, 0x003, 0x000, 0x002, 0x000, 0x003, 0x005, + 0x000, 0x002, 0x000, 0x004, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x007, 0x000, + 0x002, 0x000, 0x002, 0x008, 0x000, 0x000, 0x009, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x002, 0x001, 0x002, 0x006, 0x000, 0x000, 0x00F, 0x000, 0x001, 0x007, 0x000, 0x001, 0x000, + 0x00D, 0x000, 0x002, 0x006, 0x000, 0x003, 0x003, 0x001, 0x007, 0x00D, 0x006, 0x004, 0x001, + 0x001, 0x000, 0x001, 0x000, 0x001, 0x005, 0x002, 0x000, 0x000, 0x000, 0x018, 0x002, 0x002, + 0x000, 0x000, 0x007, 0x000, 0x000, 0x003, 0x001, 0x008, 0x010, 0x003, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x004, 0x007, 0x000, 0x001, 0x000, 0x002, 0x004, 0x000, 0x008, 0x000, 0x000, + 0x000, 0x00B, 0x000, 0x001, 0x000, 0x008, 0x00A, 0x001, 0x005, 0x001, 0x000, 0x007, 0x006, + 0x000, 0x001, 0x000, 0x000, 0x001, 0x004, 0x000, 0x00B, 0x004, 0x003, 0x000, 0x000, 0x00C, + 0x001, 0x000, 0x003, 0x008, 0x000, 0x001, 0x001, 0x000, 0x003, 0x00B, 0x006, 0x000, 0x001, + 0x002, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x009, 0x003, 0x006, + 0x000, 0x003, 0x003, 0x001, 0x001, 0x001, 0x000, 0x000, 0x005, 0x000, 0x000, 0x007, 0x003, + 0x008, 0x002, 0x004, 0x000, 0x004, 0x006, 0x001, 0x002, 0x001, 0x002, 0x003, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x002, 0x000, 0x007, 0x003, 0x00A, 0x003, + 0x001, 0x004, 0x001, 0x004, 0x002, 0x006, 0x003, 0x002, 0x000, 0x000, 0x008, 0x011, 0x000, + 0x000, 0x00D, 0x000, 0x000, 0x000, 0x000, 0x000, 0x006, 0x005, 0x000, 0x001, 0x000, 0x000, + 0x001, 0x004, 0x000, 0x000, 0x004, 0x001, 0x001, 0x000, 0x000, 0x00F, 0x004, 0x002, 0x003, + 0x000, 0x000, 0x002, 0x002, 0x002, 0x000, 0x000, 0x000, 0x005, 0x002, 0x008, 0x002, 0x000, + 0x002, 0x000, 0x005, 0x006, 0x001, 0x009, 0x000, 0x001, 0x001, 0x004, 0x002, 0x001, 0x000, + 0x000, 0x000, 0x002, 0x002, 0x003, 0x001, 0x005, 0x002, 0x000, 0x000, 0x004, 0x005, 0x001, + 0x000, 0x001, 0x000, 0x009, 0x000, 0x002, 0x001, 0x000, 0x003, 0x000, 0x002, 0x002, 0x003, + 0x000, 0x000, 0x009, 0x001, 0x003, 0x000, 0x001, 0x006, 0x003, 0x000, 0x002, 0x001, 0x007, + 0x003, 0x000, 0x005, 0x000, 0x001, 0x000, 0x000, 0x000, 0x004, 0x005, 0x000, 0x001, 0x000, + 0x003, 0x002, 0x001, 0x000, 0x002, 0x000, 0x001, 0x011, 0x001, 0x001, 0x004, 0x000, 0x001, + 0x000, 0x001, 0x001, 0x000, 0x004, 0x003, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x017, + 0x004, 0x000, 0x000, 0x000, 0x003, 0x00C, 0x000, 0x008, 0x003, 0x002, 0x003, 0x005, 0x000, + 0x002, 0x003, 0x002, 0x001, 0x000, 0x003, 0x000, 0x001, 0x001, 0x000, 0x001, 0x000, 0x004, + 0x001, 0x006, 0x002, 0x01D, 0x004, 0x004, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x009, + 0x002, 0x007, 0x002, 0x005, 0x000, 0x000, 0x009, 0x001, 0x004, 0x000, 0x001, 0x000, 0x000, + 0x004, 0x007, 0x000, 0x006, 0x005, 0x000, 0x001, 0x001, 0x000, 0x003, 0x001, 0x001, 0x002, + 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x001, 0x000, 0x002, 0x003, 0x005, 0x001, + 0x007, 0x001, 0x001, 0x003, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x000, 0x002, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x004, 0x003, 0x002, + 0x004, 0x000, 0x000, 0x001, 0x000, 0x000, 0x002, 0x00B, 0x008, 0x000, 0x004, 0x003, 0x001, + 0x009, 0x003, 0x002, 0x001, 0x003, 0x000, 0x002, 0x005, 0x000, 0x005, 0x001, 0x003, 0x005, + 0x002, 0x001, 0x003, 0x000, 0x010, 0x002, 0x000, 0x000, 0x000, 0x001, 0x000, 0x006, 0x000, + 0x001, 0x003, 0x000, 0x008, 0x000, 0x000, 0x002, 0x006, 0x000, 0x004, 0x000, 0x000, 0x001, + 0x000, 0x004, 0x000, 0x003, 0x001, 0x003, 0x000, 0x002, 0x003, 0x001, 0x005, 0x003, 0x005, + 0x005, 0x001, 0x001, 0x001, 0x000, 0x006, 0x003, 0x001, 0x000, 0x001, 0x001, 0x000, 0x003, + 0x002, 0x001, 0x006, 0x000, 0x005, 0x002, 0x003, 0x009, 0x007, 0x004, 0x000, 0x002, 0x002, + 0x001, 0x002, 0x006, 0x000, 0x000, 0x000, 0x002, 0x000, 0x001, 0x000, 0x004, 0x003, 0x000, + 0x002, 0x005, 0x012, 0x005, 0x002, 0x000, 0x001, 0x00D, 0x003, 0x004, 0x000, 0x000, 0x001, + 0x002, 0x000, 0x00D, 0x000, 0x00D, 0x001, 0x000, 0x001, 0x000, 0x001, 0x001, 0x001, 0x001, + 0x001, 0x001, 0x002, 0x000, 0x001, 0x005, 0x003, 0x000, 0x005, 0x000, 0x001, 0x000, 0x000, + 0x004, 0x000, 0x002, 0x001, 0x000, 0x001, 0x002, 0x000, 0x000, 0x005, 0x000, 0x001, 0x000, + 0x000, 0x000, 0x001, 0x000, 0x003, 0x000, 0x001, 0x002, 0x002, 0x000, 0x000, 0x001, 0x000, + 0x005, 0x000, 0x00D, 0x000, 0x001, 0x002, 0x00A, 0x003, 0x000, 0x000, 0x002, 0x002, 0x001, + 0x002, 0x000, 0x002, 0x001, 0x001, 0x005, 0x000, 0x00A, 0x000, 0x000, 0x003, 0x003, 0x009, + 0x001, 0x004, 0x002, 0x002, 0x000, 0x000, 0x003, 0x006, 0x000, 0x000, 0x00A, 0x001, 0x003, + 0x001, 0x00C, 0x000, 0x000, 0x000, 0x002, 0x001, 0x006, 0x001, 0x000, 0x001, 0x002, 0x007, + 0x000, 0x000, 0x005, 0x002, 0x001, 0x000, 0x001, 0x001, 0x001, 0x000, 0x004, 0x000, 0x000, + 0x001, 0x000, 0x001, 0x000, 0x001, 0x006, 0x000, 0x008, 0x000, 0x002, 0x004, 0x002, 0x004, + 0x002, 0x002, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x005, 0x002, 0x006, + 0x000, 0x001, 0x002, 0x005, 0x000, 0x000, 0x001, 0x000, 0x002, 0x000, 0x005, 0x000, 0x001, + 0x001, 0x002, 0x003, 0x000, 0x000, 0x000, 0x000, 0x005, 0x000, 0x000, 0x001, 0x00D, 0x001, + 0x000, 0x000, 0x000, 0x001, 0x000, 0x005, 0x002, 0x000, 0x007, 0x009, 0x001, 0x002, 0x002, + 0x000, 0x001, 0x009, 0x007, 0x000, 0x005, 0x002, 0x000, 0x001, 0x001, 0x005, 0x006, 0x002, + 0x000, 0x00F, 0x000, 0x001, 0x000, 0x005, 0x001, 0x002, 0x001, 0x002, 0x000, 0x000, 0x002, + 0x003, 0x000, 0x007, 0x003, 0x000, 0x000, 0x003, 0x000, 0x002, 0x002, 0x001, 0x002, 0x001, + 0x002, 0x005, 0x001, 0x000, 0x009, 0x000, 0x000, 0x000, 0x006, 0x009, 0x001, 0x00A, 0x001, + 0x001, 0x000, 0x000, 0x003, 0x006, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000, 0x000, 0x007, + 0x002, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x003, 0x001, 0x000, 0x004, 0x001, 0x006, + 0x002, 0x002, 0x000, 0x000, 0x004, 0x00B, 0x001, 0x000, 0x000, 0x005, 0x001, 0x003, 0x000, + 0x002, 0x006, 0x008, 0x002, 0x000, 0x006, 0x000, 0x004, 0x001, 0x006, 0x000, 0x002, 0x003, + 0x001, 0x001, 0x001, 0x003, 0x002, 0x002, 0x002, 0x002, 0x00C, 0x001, 0x000, 0x004, 0x005, + 0x000, 0x004, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x002, 0x000, 0x000, + 0x000, 0x001, 0x002, 0x000, 0x000, 0x008, 0x004, 0x001, 0x002, 0x000, 0x003, 0x001, 0x002, + 0x000, 0x003, 0x003, 0x007, 0x000, 0x000, 0x000, 0x000, 0x001, 0x00B, 0x000, 0x001, 0x000, + 0x000, 0x002, 0x001, 0x002, 0x001, 0x007, 0x001, 0x002, 0x003, 0x002, 0x000, 0x000, 0x001, + 0x004, 0x001, 0x001, 0x001, 0x001, 0x001, 0x000, 0x00A, 0x001, 0x005, 0x000, 0x006, 0x000, + 0x000, 0x000, 0x001, 0x003, 0x001, 0x007, 0x002, 0x000, 0x000, 0x001, 0x002, 0x001, 0x002, + 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, 0x006, 0x000, 0x000, 0x000, 0x000, 0x003, 0x005, + 0x000, 0x003, 0x001, 0x002, 0x006, 0x001, 0x000, 0x001, 0x002, 0x000, 0x002, 0x003, 0x000, + 0x001, 0x000, 0x003, 0x002, 0x00C, 0x001, 0x006, 0x008, 0x007, 0x002, 0x001, 0x003, 0x000, + 0x006, 0x002, 0x000, 0x000, 0x001, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x005, + 0x000, 0x005, 0x000, 0x000, 0x001, 0x002, 0x001, 0x000, 0x001, 0x001, 0x000, 0x00A, 0x002, + 0x000, 0x000, 0x00C, 0x000, 0x001, 0x000, 0x002, 0x003, 0x001, 0x004, 0x001, 0x002, 0x001, + 0x000, 0x007, 0x001, 0x001, 0x008, 0x009, 0x002, 0x000, 0x002, 0x002, 0x003, 0x003, 0x001, + 0x003, 0x002, 0x000, 0x000, 0x001, 0x000, 0x006, 0x005, 0x000, 0x002, 0x002, 0x000, 0x001, + 0x002, 0x005, 0x004, 0x002, 0x001, 0x002, 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x002, + 0x000, 0x007, 0x005, 0x003, 0x000, 0x000, 0x001, 0x000, 0x004, 0x003, 0x000, 0x002, 0x007, + 0x001, 0x000, 0x002, 0x000, 0x002, 0x004, 0x002, 0x000, 0x000, 0x002, 0x000, 0x00E, 0x001, + 0x001, 0x000, 0x000, 0x003, 0x000, 0x003, 0x000, 0x000, 0x002, 0x000, 0x000, 0x006, 0x003, + 0x003, 0x003, 0x001, 0x000, 0x001, 0x000, 0x000, 0x003, 0x000, 0x000, 0x000, 0x000, 0x001, + 0x000, 0x007, 0x005, 0x001, 0x000, 0x001, 0x001, 0x003, 0x001, 0x009, 0x000, 0x000, 0x008, + 0x000, 0x000, 0x00F, 0x002, 0x002, 0x000, 0x004, 0x000, 0x000, 0x000, 0x002, 0x000, 0x001, + 0x007, 0x002, 0x001, 0x000, 0x001, 0x001, 0x002, 0x000, 0x000, 0x002, 0x000, 0x000, 0x002, + 0x000, 0x002, 0x002, 0x001, 0x006, 0x000, 0x001, 0x000, 0x001, 0x004, 0x000, 0x002, 0x003, + 0x001, 0x002, 0x000, 0x003, 0x002, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x002, 0x000, + 0x001, 0x004, 0x001, 0x00E, 0x003, 0x003, 0x000, 0x005, 0x001, 0x000, 0x000, 0x002, 0x001, + 0x002, 0x000, 0x000, 0x003, 0x000, 0x002, 0x001, 0x000, 0x001, 0x000, 0x001, 0x002, 0x000, + 0x001, 0x000, 0x001, 0x001, 0x001, 0x001, 0x005, 0x003, 0x000, 0x00A, 0x002, 0x002, 0x001, + 0x000, 0x000, 0x004, 0x000, 0x002, 0x00A, 0x000, 0x000, 0x008, 0x004, 0x000, 0x001, 0x004, + 0x005, 0x005, 0x002, 0x001, 0x000, 0x000, 0x000, 0x006, 0x000, 0x001, 0x001, 0x000, 0x000, + 0x001, 0x001, 0x002, 0x001, 0x000, 0x001, 0x002, 0x002, 0x002, 0x000, 0x001, 0x001, 0x001, + 0x002, 0x000, 0x001, 0x000, 0x001, 0x000, 0x001, 0x002, 0x001, 0x000, 0x001, 0x002, 0x000, + 0x002, 0x002, 0x000, 0x000, 0x000, 0x003, 0x000, 0x001, 0x003, 0x001, 0x002, 0x007, 0x000, + 0x002, 0x004, 0x004, 0x000, 0x005, 0x000, 0x000, 0x001, 0x003, 0x003, 0x000, 0x009, 0x001, + 0x000, 0x001, 0x002, 0x004, 0x003, 0x001, 0x000, 0x001, 0x001, 0x002, 0x003, 0x001, 0x006, + 0x003, 0x001, 0x003, 0x001, 0x005, 0x004, 0x001, 0x000, 0x001, 0x001, 0x000, 0x005, 0x001, + 0x000, 0x001, 0x001, 0x002, 0x000, 0x005, 0x008, 0x001, 0x000, 0x007, 0x000, 0x000, 0x000, + 0x005, 0x001, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x002, 0x002, 0x000, 0x000, + 0x00A, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x007, 0x002, 0x004, 0x000, 0x001, 0x005, + 0x000, 0x001, 0x000, 0x000, 0x000, 0x004, 0x000, 0x000, 0x004, 0x002, 0x000, 0x002, 0x001, + 0x001, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000, 0x000, + 0x004, 0x000, 0x001, 0x000, 0x003, 0x003, 0x000, 0x001, 0x003, 0x001, 0x000, 0x001, 0x000, + 0x000, 0x002, 0x000, 0x00A, 0x000, 0x001, 0x000, 0x000, 0x003, 0x001, 0x001, 0x005, 0x004, + 0x003, 0x000, 0x000, 0x002, 0x001, 0x000, 0x001, 0x000, 0x001, 0x002, 0x002, 0x001, 0x000, + 0x004, 0x001, 0x000, 0x003, 0x001, 0x001, 0x005, 0x001, 0x001, 0x007, 0x001, 0x003, 0x000, + 0x000, 0x004, 0x003, 0x001, 0x002, 0x00B, 0x002, 0x001, 0x000, 0x000, 0x000, 0x001, 0x002, + 0x001, 0x004, 0x003, 0x001, 0x001, 0x002, 0x000, 0x000, 0x002, 0x002, 0x000, 0x000, 0x000, + 0x002, 0x002, 0x001, 0x000, 0x002, 0x000, 0x000, 0x001, 0x001, 0x008, 0x002, 0x001, 0x000, + 0x003, 0x000, 0x001, 0x001, 0x001, 0x000, 0x003, 0x004, 0x002, 0x007, 0x003, 0x001, 0x009, + 0x002, 0x005, 0x002, 0x002, 0x003, 0x000, 0x00F, 0x000, 0x002, 0x001, 0x003, 0x004, 0x001, + 0x000, 0x003, 0x009, 0x002, 0x001, 0x008, 0x000, 0x001, 0x001, 0x000, 0x009, 0x000, 0x000, + 0x001, 0x000, 0x00A, 0x000, 0x004, 0x001, 0x000, 0x002, 0x003, 0x009, 0x002, 0x000, 0x000, + 0x005, 0x001, 0x002, 0x003, 0x002, 0x000, 0x001, 0x002, 0x002, 0x001, 0x003, 0x000, 0x000, + 0x002, 0x001, 0x001, 0x000, 0x001, 0x005, 0x001, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, + 0x008, 0x005, 0x000, 0x001, 0x001, 0x002, 0x000, 0x001, 0x000, 0x00B, 0x004, 0x000, 0x002, + 0x002, 0x004, 0x000, 0x001, 0x002, 0x000, 0x000, 0x001, 0x001, 0x001, 0x001, 0x002, 0x000, + 0x002, 0x000, 0x002, 0x005, 0x004, 0x000, 0x000, 0x000, 0x005, 0x000, 0x000, 0x003, 0x002, + 0x001, 0x000, 0x000, 0x000, 0x003, 0x000, 0x002, 0x000, 0x000, 0x001, 0x002, 0x002, 0x001, + 0x000, 0x001, 0x004, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000, + 0x004, 0x000, 0x001, 0x002, 0x000, 0x001, 0x002, 0x000, 0x000, 0x001, 0x000, 0x002, 0x002, + 0x001, 0x001, 0x001, 0x000, 0x003, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x001, 0x008, 0x004, 0x001, 0x002, 0x007, 0x005, 0x000, 0x003, 0x002, 0x000, 0x002, 0x002, + 0x004, 0x000, 0x004, 0x000, 0x004, 0x002, 0x001, 0x002, 0x002, 0x002, 0x001, 0x000, 0x000, + 0x001, 0x003, 0x003, 0x001, 0x001, 0x002, 0x002, 0x000, 0x001, 0x001, 0x000, 0x001, 0x000, + 0x001, 0x001, 0x003, 0x004, 0x001, 0x002, 0x002, 0x004, 0x000, 0x003, 0x001, 0x001, 0x001, + 0x000, 0x003, 0x001, 0x000, 0x003, 0x002, 0x001, 0x000, 0x003, 0x002, 0x001, 0x006, 0x006, + 0x000, 0x000, 0x002, 0x001, 0x000, 0x001, 0x002, 0x003, 0x002, 0x001, 0x003, 0x001, 0x000, + 0x001, 0x005, 0x003, 0x001, 0x002, 0x004, 0x00D, 0x000, 0x001, 0x000, 0x000, 0x001, 0x000, + 0x000, 0x001, 0x001, 0x001, 0x000, 0x000, 0x001, 0x001, 0x002, 0x000, 0x003, 0x003, 0x000, + 0x001, 0x000, 0x002, 0x000, 0x005, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x004, 0x001, + 0x002, 0x000, 0x000, 0x002, 0x002, 0x000, 0x000, 0x001, 0x004, 0x002, 0x000, 0x000, 0x004, + 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x001, 0x001, 0x002, 0x003, 0x000, 0x001, 0x002, + 0x003, 0x001, 0x000, 0x002, 0x001, 0x001, 0x000, 0x003, 0x002, 0x001, 0x001, 0x000, 0x000, + 0x003, 0x000, 0x003, 0x000, 0x000, 0x000, 0x003, 0x000, 0x002, 0x001, 0x001, 0x002, 0x000, + 0x004, 0x000, 0x001, 0x000, 0x001, 0x006, 0x000, 0x004, 0x001, 0x002, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x002, 0x000, 0x002, 0x000, 0x002, 0x000, 0x001, 0x002, 0x001, 0x002, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, 0x002, 0x001, 0x001, 0x000, 0x002, 0x000, + 0x000, 0x003, 0x008, 0x003, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x003, 0x003, 0x004, 0x000, 0x003, 0x001, 0x000, 0x001, 0x001, 0x000, 0x002, 0x004, + 0x001, 0x002, 0x001, 0x004, 0x002, 0x001, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, + 0x001, 0x008, 0x000, 0x003, 0x000, 0x001, 0x001, 0x004, 0x001, 0x002, 0x000, 0x001, 0x001, + 0x000, 0x003, 0x001, 0x000, 0x008, 0x000, 0x000, 0x002, 0x001, 0x004, 0x005, 0x006, 0x001, + 0x002, 0x000, 0x003, 0x003, 0x000, 0x001, 0x000, 0x003, 0x000, 0x004, 0x000, 0x005, 0x001, + 0x002, 0x001, 0x003, 0x002, 0x004, 0x001, 0x001, 0x002, 0x001, 0x003, 0x005, 0x001, 0x003, + 0x001, 0x000, 0x000, 0x003, 0x000, 0x003, 0x001, 0x005, 0x000, 0x001, 0x000, 0x001, 0x002, + 0x001, 0x000, 0x004, 0x002, 0x002, 0x001, 0x002, 0x001, 0x005, 0x000, 0x001, 0x002, 0x001, + 0x000, 0x000, 0x001, 0x00A, 0x003, 0x002, 0x002, 0x000, 0x004, 0x001, 0x000, 0x001, 0x000, + 0x003, 0x000, 0x001, 0x001, 0x000, 0x001, 0x001, 0x002, 0x000, 0x001, 0x002, 0x000, 0x002, + 0x000, 0x001, 0x002, 0x002, 0x003, 0x000, 0x003, 0x003, 0x004, 0x003, 0x000, 0x000, 0x007, + 0x000, 0x002, 0x002, 0x000, 0x001, 0x002, 0x000, 0x000, 0x002, 0x000, 0x002, 0x000, 0x000, + 0x001, 0x000, 0x001, 0x003, 0x002, 0x003, 0x002, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x001, 0x002, 0x001, 0x000, 0x001, 0x001, 0x000, +]; +pub(crate) const COMPATIBILITY_DECOMPOSED_KV: &[(u32, (u16, u16))] = &[ + (0x1D5E5, (0x12B4, 0x1)), + (0x1D430, (0x1117, 0x1)), + (0x0FDF1, (0xE6D, 0x3)), + (0x024DF, (0x33C, 0x1)), + (0x0FF18, (0xFC0, 0x1)), + (0x0FD72, (0xD6E, 0x3)), + (0x1D5A3, (0x1272, 0x1)), + (0x02000, (0x113, 0x1)), + (0x1D43F, (0x1126, 0x1)), + (0x03197, (0x49F, 0x1)), + (0x0FCCC, (0xC1F, 0x2)), + (0x033DA, (0x921, 0x2)), + (0x03289, (0x5EA, 0x1)), + (0x0FFEA, (0x1086, 0x1)), + (0x024E1, (0x33E, 0x1)), + (0x02155, (0x1C3, 0x3)), + (0x03298, (0x5F9, 0x1)), + (0x0FEF8, (0xF9C, 0x3)), + (0x0FF47, (0xFEF, 0x1)), + (0x0FBEC, (0xA3D, 0x3)), + (0x1D410, (0x10F7, 0x1)), + (0x02177, (0x20F, 0x4)), + (0x1D4D3, (0x11AE, 0x1)), + (0x0FD63, (0xD41, 0x3)), + (0x0335B, (0x7E8, 0x2)), + (0x0FED8, (0xF76, 0x1)), + (0x032B8, (0x620, 0x2)), + (0x1D5F4, (0x12C3, 0x1)), + (0x0FF27, (0xFCF, 0x1)), + (0x1E055, (0x14F0, 0x1)), + (0x0FFAC, (0x1054, 0x1)), + (0x01E9A, (0x0EA, 0x2)), + (0x1D532, (0x1208, 0x1)), + (0x0337A, (0x839, 0x2)), + (0x1E041, (0x14DC, 0x1)), + (0x02148, (0x1B1, 0x1)), + (0x1F21D, (0x1645, 0x1)), + (0x1D73C, (0x1409, 0x1)), + (0x01DA8, (0x0D2, 0x1)), + (0x02F4A, (0x3A3, 0x1)), + (0x0FF35, (0xFDD, 0x1)), + (0x1D48E, (0x1174, 0x1)), + (0x1EE10, (0x1518, 0x1)), + (0x02F7D, (0x3D6, 0x1)), + (0x02492, (0x2A7, 0x3)), + (0x0FB58, (0x9C1, 0x1)), + (0x1F227, (0x164F, 0x1)), + (0x02F4E, (0x3A7, 0x1)), + (0x1D652, (0x1321, 0x1)), + (0x1F106, (0x15A2, 0x2)), + (0x1D724, (0x13F1, 0x1)), + (0x1D6DA, (0x13A7, 0x1)), + (0x03204, (0x4B4, 0x3)), + (0x0FEE9, (0xF87, 0x1)), + (0x1F135, (0x1608, 0x1)), + (0x0203E, (0x134, 0x2)), + (0x1D46E, (0x1154, 0x1)), + (0x1D750, (0x141D, 0x1)), + (0x03399, (0x880, 0x2)), + (0x0FFD7, (0x1078, 0x1)), + (0x03211, (0x4DE, 0x4)), + (0x1D538, (0x120E, 0x1)), + (0x1E065, (0x1500, 0x1)), + (0x03315, (0x6D9, 0x6)), + (0x03382, (0x84B, 0x2)), + (0x03161, (0x46C, 0x1)), + (0x1D60A, (0x12D9, 0x1)), + (0x1D4E5, (0x11C0, 0x1)), + (0x02F24, (0x37D, 0x1)), + (0x0FE6B, (0xEF5, 0x1)), + (0x1D58F, (0x125E, 0x1)), + (0x0FEC2, (0xF60, 0x1)), + (0x0FC2E, (0xAD2, 0x2)), + (0x032F2, (0x677, 0x1)), + (0x0FF0C, (0xFB4, 0x1)), + (0x1E037, (0x14D2, 0x1)), + (0x1D7A1, (0x146E, 0x1)), + (0x03362, (0x7F6, 0x3)), + (0x0FB50, (0x9B9, 0x1)), + (0x1D7F2, (0x14BD, 0x1)), + (0x0FCA7, (0xBD5, 0x2)), + (0x1E059, (0x14F4, 0x1)), + (0x0FD99, (0xDDD, 0x3)), + (0x1D464, (0x114A, 0x1)), + (0x0FB78, (0x9E1, 0x1)), + (0x0FE58, (0xEE3, 0x1)), + (0x032EE, (0x673, 0x1)), + (0x107A8, (0x10B1, 0x1)), + (0x0FD5C, (0xD2C, 0x3)), + (0x0207E, (0x14D, 0x1)), + (0x0321A, (0x502, 0x4)), + (0x1D7D8, (0x14A3, 0x1)), + (0x01D40, (0x09A, 0x1)), + (0x0FCDE, (0xC43, 0x2)), + (0x1CCF7, (0x10E4, 0x1)), + (0x032A5, (0x606, 0x1)), + (0x0FC0C, (0xA8E, 0x2)), + (0x0FF40, (0xFE8, 0x1)), + (0x033C0, (0x8E2, 0x2)), + (0x0FC40, (0xAF6, 0x2)), + (0x1D5CD, (0x129C, 0x1)), + (0x1D7F8, (0x14C3, 0x1)), + (0x01DA1, (0x0CB, 0x1)), + (0x02F26, (0x37F, 0x1)), + (0x1D706, (0x13D3, 0x1)), + (0x0FF36, (0xFDE, 0x1)), + (0x0325A, (0x5A0, 0x2)), + (0x02F84, (0x3DD, 0x1)), + (0x0317D, (0x488, 0x1)), + (0x0FC16, (0xAA2, 0x2)), + (0x1D5B6, (0x1285, 0x1)), + (0x0FD3B, (0xD02, 0x2)), + (0x0313E, (0x449, 0x1)), + (0x1D69F, (0x136E, 0x1)), + (0x024A8, (0x2E9, 0x3)), + (0x1D50F, (0x11E7, 0x1)), + (0x0FD52, (0xD0E, 0x3)), + (0x02112, (0x187, 0x1)), + (0x0FDF0, (0xE6A, 0x3)), + (0x1D77A, (0x1447, 0x1)), + (0x0FF7E, (0x1026, 0x1)), + (0x1D7E0, (0x14AB, 0x1)), + (0x0FC07, (0xA84, 0x2)), + (0x0FB5B, (0x9C4, 0x1)), + (0x1D49C, (0x1182, 0x1)), + (0x0FE48, (0xED0, 0x1)), + (0x1F220, (0x1648, 0x1)), + (0x02F8B, (0x3E4, 0x1)), + (0x02048, (0x138, 0x2)), + (0x0FCEC, (0xC61, 0x2)), + (0x02F89, (0x3E2, 0x1)), + (0x0FC49, (0xB08, 0x2)), + (0x03293, (0x5F4, 0x1)), + (0x00385, (0x05C, 0x3)), + (0x0222C, (0x222, 0x2)), + (0x02FBA, (0x413, 0x1)), + (0x032C6, (0x63C, 0x2)), + (0x1D600, (0x12CF, 0x1)), + (0x1D58C, (0x125B, 0x1)), + (0x0FB71, (0x9DA, 0x1)), + (0x1D55F, (0x122E, 0x1)), + (0x1D494, (0x117A, 0x1)), + (0x0320C, (0x4CC, 0x3)), + (0x1D4E4, (0x11BF, 0x1)), + (0x01DB4, (0x0DE, 0x1)), + (0x0FF82, (0x102A, 0x1)), + (0x032B1, (0x612, 0x2)), + (0x02475, (0x24E, 0x3)), + (0x1D46B, (0x1151, 0x1)), + (0x01DA0, (0x0CA, 0x1)), + (0x1D4D4, (0x11AF, 0x1)), + (0x0FB8F, (0x9F8, 0x1)), + (0x1D7A2, (0x146F, 0x1)), + (0x02084, (0x153, 0x1)), + (0x1079A, (0x10A3, 0x1)), + (0x1D6F0, (0x13BD, 0x1)), + (0x107AF, (0x10B8, 0x1)), + (0x1D597, (0x1266, 0x1)), + (0x0FC14, (0xA9E, 0x2)), + (0x0319E, (0x4A6, 0x1)), + (0x03282, (0x5E3, 0x1)), + (0x10788, (0x1091, 0x1)), + (0x1EE22, (0x1529, 0x1)), + (0x0FD2A, (0xCE0, 0x2)), + (0x1F139, (0x160C, 0x1)), + (0x0FF0A, (0xFB2, 0x1)), + (0x03290, (0x5F1, 0x1)), + (0x1E039, (0x14D4, 0x1)), + (0x1F21E, (0x1646, 0x1)), + (0x03304, (0x697, 0x5)), + (0x1D6A1, (0x1370, 0x1)), + (0x024B3, (0x30A, 0x3)), + (0x03198, (0x4A0, 0x1)), + (0x1EE96, (0x1577, 0x1)), + (0x0FC41, (0xAF8, 0x2)), + (0x0FE3D, (0xEC7, 0x1)), + (0x1D73B, (0x1408, 0x1)), + (0x0A69D, (0x987, 0x1)), + (0x1D5AF, (0x127E, 0x1)), + (0x0316F, (0x47A, 0x1)), + (0x0FEF7, (0xF99, 0x3)), + (0x033E8, (0x93F, 0x2)), + (0x024BE, (0x31B, 0x1)), + (0x033BB, (0x8D8, 0x2)), + (0x033EC, (0x94A, 0x3)), + (0x0329F, (0x600, 0x1)), + (0x1D402, (0x10E9, 0x1)), + (0x02092, (0x160, 0x1)), + (0x033EE, (0x950, 0x3)), + (0x0FEA2, (0xF40, 0x1)), + (0x1D4D2, (0x11AD, 0x1)), + (0x0328A, (0x5EB, 0x1)), + (0x0FFA5, (0x104D, 0x1)), + (0x03299, (0x5FA, 0x1)), + (0x1D5C4, (0x1293, 0x1)), + (0x1D6B6, (0x1383, 0x1)), + (0x0FF08, (0xFB0, 0x1)), + (0x1D7EA, (0x14B5, 0x1)), + (0x02F15, (0x36E, 0x1)), + (0x024AB, (0x2F2, 0x3)), + (0x033D9, (0x91E, 0x3)), + (0x0FFE3, (0x107F, 0x2)), + (0x1D6E2, (0x13AF, 0x1)), + (0x1D728, (0x13F5, 0x1)), + (0x0FCAE, (0xBE3, 0x2)), + (0x02121, (0x193, 0x3)), + (0x1D422, (0x1109, 0x1)), + (0x1D41E, (0x1105, 0x1)), + (0x01D3F, (0x099, 0x1)), + (0x0FF86, (0x102E, 0x1)), + (0x0FDC1, (0xE55, 0x3)), + (0x0FC45, (0xB00, 0x2)), + (0x1CCDB, (0x10C8, 0x1)), + (0x1D50A, (0x11E4, 0x1)), + (0x1079D, (0x10A6, 0x1)), + (0x00140, (0x01E, 0x2)), + (0x1D76C, (0x1439, 0x1)), + (0x0FED4, (0xF72, 0x1)), + (0x1D67A, (0x1349, 0x1)), + (0x1F11B, (0x15CD, 0x3)), + (0x002B7, (0x045, 0x1)), + (0x1D458, (0x113E, 0x1)), + (0x0FD8E, (0xDC2, 0x3)), + (0x0FEB3, (0xF51, 0x1)), + (0x0FB5F, (0x9C8, 0x1)), + (0x02FC9, (0x422, 0x1)), + (0x024CC, (0x329, 0x1)), + (0x1D4A9, (0x1188, 0x1)), + (0x0FD31, (0xCEE, 0x2)), + (0x001C4, (0x023, 0x3)), + (0x03156, (0x461, 0x1)), + (0x1D4F3, (0x11CE, 0x1)), + (0x024C8, (0x325, 0x1)), + (0x0FB02, (0x997, 0x2)), + (0x0FBDD, (0xA29, 0x2)), + (0x1D768, (0x1435, 0x1)), + (0x002B6, (0x044, 0x1)), + (0x0FB7C, (0x9E5, 0x1)), + (0x02146, (0x1AF, 0x1)), + (0x0FFC2, (0x1067, 0x1)), + (0x1D6A2, (0x1371, 0x1)), + (0x02006, (0x119, 0x1)), + (0x1D445, (0x112C, 0x1)), + (0x0FF0B, (0xFB3, 0x1)), + (0x1D5FA, (0x12C9, 0x1)), + (0x02F0A, (0x363, 0x1)), + (0x02F14, (0x36D, 0x1)), + (0x0FE6A, (0xEF4, 0x1)), + (0x1D6C2, (0x138F, 0x1)), + (0x0FD7D, (0xD8F, 0x3)), + (0x03370, (0x820, 0x3)), + (0x0326F, (0x5BC, 0x2)), + (0x1EE2A, (0x152D, 0x1)), + (0x0FC86, (0xB8E, 0x2)), + (0x0FF12, (0xFBA, 0x1)), + (0x02F05, (0x35E, 0x1)), + (0x0FBE1, (0xA2E, 0x1)), + (0x1EE1B, (0x1523, 0x1)), + (0x0216A, (0x1F8, 0x2)), + (0x0FC78, (0xB72, 0x2)), + (0x1D4BE, (0x119A, 0x1)), + (0x03366, (0x802, 0x3)), + (0x1D69E, (0x136D, 0x1)), + (0x03182, (0x48D, 0x1)), + (0x1D425, (0x110C, 0x1)), + (0x1D760, (0x142D, 0x1)), + (0x02139, (0x1A5, 0x1)), + (0x0FDA5, (0xE01, 0x3)), + (0x033B8, (0x8D2, 0x2)), + (0x0FB03, (0x999, 0x3)), + (0x1D461, (0x1147, 0x1)), + (0x1D58B, (0x125A, 0x1)), + (0x0FC7E, (0xB7E, 0x2)), + (0x1D7ED, (0x14B8, 0x1)), + (0x1E047, (0x14E2, 0x1)), + (0x033C4, (0x8EC, 0x2)), + (0x1EEB0, (0x158A, 0x1)), + (0x02467, (0x233, 0x1)), + (0x1D4C8, (0x11A3, 0x1)), + (0x0FF70, (0x1018, 0x1)), + (0x0FC30, (0xAD6, 0x2)), + (0x1EE79, (0x155D, 0x1)), + (0x0FDC5, (0xE61, 0x3)), + (0x1D70D, (0x13DA, 0x1)), + (0x0FF61, (0x1009, 0x1)), + (0x1D7DE, (0x14A9, 0x1)), + (0x1D416, (0x10FD, 0x1)), + (0x0FF90, (0x1038, 0x1)), + (0x03390, (0x86A, 0x2)), + (0x1CCDD, (0x10CA, 0x1)), + (0x1078D, (0x1096, 0x1)), + (0x1EEA8, (0x1583, 0x1)), + (0x0FC50, (0xB16, 0x2)), + (0x1D572, (0x1241, 0x1)), + (0x0FED7, (0xF75, 0x1)), + (0x1D629, (0x12F8, 0x1)), + (0x1D693, (0x1362, 0x1)), + (0x0FDAC, (0xE16, 0x3)), + (0x033C3, (0x8EA, 0x2)), + (0x0FEF2, (0xF90, 0x1)), + (0x02156, (0x1C6, 0x3)), + (0x1F241, (0x1667, 0x3)), + (0x0203C, (0x132, 0x2)), + (0x1D40F, (0x10F6, 0x1)), + (0x02165, (0x1EC, 0x2)), + (0x003F1, (0x069, 0x1)), + (0x107A2, (0x10AB, 0x1)), + (0x0FB8D, (0x9F6, 0x1)), + (0x0FC24, (0xABE, 0x2)), + (0x1D510, (0x11E8, 0x1)), + (0x03239, (0x566, 0x3)), + (0x1D67E, (0x134D, 0x1)), + (0x0320D, (0x4CF, 0x3)), + (0x03330, (0x749, 0x3)), + (0x1D735, (0x1402, 0x1)), + (0x0FB72, (0x9DB, 0x1)), + (0x1EE51, (0x1543, 0x1)), + (0x1D635, (0x1304, 0x1)), + (0x0FC26, (0xAC2, 0x2)), + (0x1F218, (0x1640, 0x1)), + (0x02145, (0x1AE, 0x1)), + (0x01DB8, (0x0E2, 0x1)), + (0x1D79B, (0x1468, 0x1)), + (0x0314C, (0x457, 0x1)), + (0x0FC9C, (0xBBF, 0x2)), + (0x0FCEF, (0xC67, 0x2)), + (0x032DD, (0x662, 0x1)), + (0x0212C, (0x19A, 0x1)), + (0x1D488, (0x116E, 0x1)), + (0x02F68, (0x3C1, 0x1)), + (0x1E05B, (0x14F6, 0x1)), + (0x1E03D, (0x14D8, 0x1)), + (0x032B2, (0x614, 0x2)), + (0x0FD76, (0xD7A, 0x3)), + (0x0FD6F, (0xD65, 0x3)), + (0x1F141, (0x1614, 0x1)), + (0x1D627, (0x12F6, 0x1)), + (0x0FF97, (0x103F, 0x1)), + (0x02F9E, (0x3F7, 0x1)), + (0x0FD1A, (0xCC0, 0x2)), + (0x1F10A, (0x15AA, 0x2)), + (0x02FB7, (0x410, 0x1)), + (0x0FCDD, (0xC41, 0x2)), + (0x0FC10, (0xA96, 0x2)), + (0x03347, (0x7A1, 0x5)), + (0x03369, (0x80B, 0x3)), + (0x033C6, (0x8F0, 0x4)), + (0x0330F, (0x6C1, 0x4)), + (0x02F98, (0x3F1, 0x1)), + (0x0FB8A, (0x9F3, 0x1)), + (0x0FD56, (0xD1A, 0x3)), + (0x1D44C, (0x1133, 0x1)), + (0x1D68C, (0x135B, 0x1)), + (0x0FDB3, (0xE2B, 0x3)), + (0x02FAE, (0x407, 0x1)), + (0x1CCD6, (0x10C3, 0x1)), + (0x0FFB0, (0x1058, 0x1)), + (0x1D60E, (0x12DD, 0x1)), + (0x02070, (0x141, 0x1)), + (0x0AB69, (0x992, 0x1)), + (0x1E068, (0x1503, 0x1)), + (0x03140, (0x44B, 0x1)), + (0x0FFAE, (0x1056, 0x1)), + (0x03155, (0x460, 0x1)), + (0x0FB51, (0x9BA, 0x1)), + (0x01DBB, (0x0E5, 0x1)), + (0x02466, (0x232, 0x1)), + (0x1D729, (0x13F6, 0x1)), + (0x0FBFF, (0xA70, 0x1)), + (0x003D0, (0x05F, 0x1)), + (0x033D2, (0x90B, 0x3)), + (0x1F112, (0x15B2, 0x3)), + (0x01D37, (0x092, 0x1)), + (0x02057, (0x13C, 0x4)), + (0x0314F, (0x45A, 0x1)), + (0x002B3, (0x041, 0x1)), + (0x0FF64, (0x100C, 0x1)), + (0x0FEAE, (0xF4C, 0x1)), + (0x1F244, (0x1670, 0x3)), + (0x02F71, (0x3CA, 0x1)), + (0x0FE13, (0xEB0, 0x1)), + (0x02135, (0x1A1, 0x1)), + (0x0FF5A, (0x1002, 0x1)), + (0x03143, (0x44E, 0x1)), + (0x1D552, (0x1221, 0x1)), + (0x03339, (0x76E, 0x3)), + (0x0FCCA, (0xC1B, 0x2)), + (0x0FD19, (0xCBE, 0x2)), + (0x1D487, (0x116D, 0x1)), + (0x003F4, (0x06B, 0x1)), + (0x1E035, (0x14D0, 0x1)), + (0x0FD84, (0xDA4, 0x3)), + (0x1D4FA, (0x11D5, 0x1)), + (0x1D51B, (0x11F2, 0x1)), + (0x0FB7A, (0x9E3, 0x1)), + (0x0FFC7, (0x106C, 0x1)), + (0x1EE6D, (0x1553, 0x1)), + (0x024D3, (0x330, 0x1)), + (0x0FFEE, (0x108A, 0x1)), + (0x1D777, (0x1444, 0x1)), + (0x0FF34, (0xFDC, 0x1)), + (0x1D5DE, (0x12AD, 0x1)), + (0x1D482, (0x1168, 0x1)), + (0x1EE2B, (0x152E, 0x1)), + (0x024E6, (0x343, 0x1)), + (0x1EE67, (0x154E, 0x1)), + (0x0210B, (0x180, 0x1)), + (0x0FB75, (0x9DE, 0x1)), + (0x0FFD6, (0x1077, 0x1)), + (0x1D5E8, (0x12B7, 0x1)), + (0x01D56, (0x0AF, 0x1)), + (0x0FBE4, (0xA31, 0x1)), + (0x1F23A, (0x1662, 0x1)), + (0x0FD6B, (0xD59, 0x3)), + (0x1F235, (0x165D, 0x1)), + (0x0FDFC, (0xEA9, 0x4)), + (0x0FF9F, (0x1047, 0x1)), + (0x1EE80, (0x1562, 0x1)), + (0x1D485, (0x116B, 0x1)), + (0x0FD59, (0xD23, 0x3)), + (0x0FE34, (0xEBE, 0x1)), + (0x0FF41, (0xFE9, 0x1)), + (0x0FD6A, (0xD56, 0x3)), + (0x01DAF, (0x0D9, 0x1)), + (0x03176, (0x481, 0x1)), + (0x0FBD8, (0xA24, 0x1)), + (0x0FBA2, (0xA0B, 0x1)), + (0x02F2F, (0x388, 0x1)), + (0x1F13B, (0x160E, 0x1)), + (0x1D440, (0x1127, 0x1)), + (0x0FECD, (0xF6B, 0x1)), + (0x03138, (0x443, 0x1)), + (0x0FDC7, (0xE67, 0x3)), + (0x1D74A, (0x1417, 0x1)), + (0x0FEEC, (0xF8A, 0x1)), + (0x0316A, (0x475, 0x1)), + (0x02F8C, (0x3E5, 0x1)), + (0x033B1, (0x8C4, 0x2)), + (0x0FF2E, (0xFD6, 0x1)), + (0x02F3B, (0x394, 0x1)), + (0x1D63F, (0x130E, 0x1)), + (0x1D5C9, (0x1298, 0x1)), + (0x1D4B8, (0x1196, 0x1)), + (0x024B1, (0x304, 0x3)), + (0x1D45B, (0x1141, 0x1)), + (0x03170, (0x47B, 0x1)), + (0x1D7E3, (0x14AE, 0x1)), + (0x0FEB5, (0xF53, 0x1)), + (0x0339C, (0x886, 0x2)), + (0x0FC8C, (0xB9A, 0x2)), + (0x0FBDE, (0xA2B, 0x1)), + (0x0FD0A, (0xCA0, 0x2)), + (0x1E052, (0x14ED, 0x1)), + (0x0FD9B, (0xDE3, 0x3)), + (0x0331E, (0x704, 0x4)), + (0x02FB3, (0x40C, 0x1)), + (0x024E8, (0x345, 0x1)), + (0x033AF, (0x8BC, 0x6)), + (0x1D7AD, (0x147A, 0x1)), + (0x1EEAE, (0x1588, 0x1)), + (0x03303, (0x694, 0x3)), + (0x02470, (0x243, 0x2)), + (0x1D6DF, (0x13AC, 0x1)), + (0x0FF8B, (0x1033, 0x1)), + (0x1079E, (0x10A7, 0x1)), + (0x1D5C1, (0x1290, 0x1)), + (0x0FB24, (0x9B1, 0x1)), + (0x1D79C, (0x1469, 0x1)), + (0x1F133, (0x1606, 0x1)), + (0x0335A, (0x7E6, 0x2)), + (0x0FE19, (0xEB6, 0x3)), + (0x0208C, (0x15B, 0x1)), + (0x1D680, (0x134F, 0x1)), + (0x1D5D6, (0x12A5, 0x1)), + (0x1EEB8, (0x1592, 0x1)), + (0x01D58, (0x0B1, 0x1)), + (0x032F9, (0x67E, 0x1)), + (0x0FD86, (0xDAA, 0x3)), + (0x107B4, (0x10BC, 0x1)), + (0x0338E, (0x866, 0x2)), + (0x0FC35, (0xAE0, 0x2)), + (0x02C7D, (0x355, 0x1)), + (0x1EE35, (0x1537, 0x1)), + (0x0FD0E, (0xCA8, 0x2)), + (0x0325F, (0x5AA, 0x2)), + (0x033F2, (0x95C, 0x3)), + (0x01D4F, (0x0A8, 0x1)), + (0x1D6D2, (0x139F, 0x1)), + (0x0FC76, (0xB6E, 0x2)), + (0x1D406, (0x10ED, 0x1)), + (0x000BC, (0x00F, 0x3)), + (0x1F231, (0x1659, 0x1)), + (0x1EE89, (0x156B, 0x1)), + (0x1D415, (0x10FC, 0x1)), + (0x0FDF8, (0xE88, 0x4)), + (0x1D42B, (0x1112, 0x1)), + (0x0FCD5, (0xC31, 0x2)), + (0x0FCA5, (0xBD1, 0x2)), + (0x1D701, (0x13CE, 0x1)), + (0x0FF13, (0xFBB, 0x1)), + (0x1D41A, (0x1101, 0x1)), + (0x1D775, (0x1442, 0x1)), + (0x1D469, (0x114F, 0x1)), + (0x03284, (0x5E5, 0x1)), + (0x032BF, (0x62E, 0x2)), + (0x03322, (0x716, 0x3)), + (0x0FCF9, (0xC7E, 0x2)), + (0x02F45, (0x39E, 0x1)), + (0x0FD28, (0xCDC, 0x2)), + (0x03376, (0x82F, 0x2)), + (0x1D771, (0x143E, 0x1)), + (0x02F78, (0x3D1, 0x1)), + (0x0FF80, (0x1028, 0x1)), + (0x1D498, (0x117E, 0x1)), + (0x1F13F, (0x1612, 0x1)), + (0x1D710, (0x13DD, 0x1)), + (0x0FEBF, (0xF5D, 0x1)), + (0x032D1, (0x656, 0x1)), + (0x024BA, (0x317, 0x1)), + (0x1D6DC, (0x13A9, 0x1)), + (0x1D556, (0x1225, 0x1)), + (0x0FF38, (0xFE0, 0x1)), + (0x1D700, (0x13CD, 0x1)), + (0x0FC7B, (0xB78, 0x2)), + (0x02025, (0x122, 0x2)), + (0x0FD5E, (0xD32, 0x3)), + (0x0FE90, (0xF2E, 0x1)), + (0x1D78E, (0x145B, 0x1)), + (0x1D7DD, (0x14A8, 0x1)), + (0x0FF51, (0xFF9, 0x1)), + (0x1D648, (0x1317, 0x1)), + (0x1D73F, (0x140C, 0x1)), + (0x0328E, (0x5EF, 0x1)), + (0x1D795, (0x1462, 0x1)), + (0x02488, (0x292, 0x2)), + (0x024A6, (0x2E3, 0x3)), + (0x0319C, (0x4A4, 0x1)), + (0x1D717, (0x13E4, 0x1)), + (0x1D409, (0x10F0, 0x1)), + (0x1D4D8, (0x11B3, 0x1)), + (0x1D7FE, (0x14C9, 0x1)), + (0x03367, (0x805, 0x3)), + (0x0FF78, (0x1020, 0x1)), + (0x1D404, (0x10EB, 0x1)), + (0x1D43A, (0x1121, 0x1)), + (0x0FF88, (0x1030, 0x1)), + (0x0202F, (0x127, 0x1)), + (0x1D418, (0x10FF, 0x1)), + (0x0338C, (0x862, 0x2)), + (0x00EDD, (0x07E, 0x2)), + (0x1D5F1, (0x12C0, 0x1)), + (0x1D4C2, (0x119E, 0x1)), + (0x0FF24, (0xFCC, 0x1)), + (0x0FE49, (0xED1, 0x2)), + (0x0246E, (0x23F, 0x2)), + (0x0FFCF, (0x1072, 0x1)), + (0x02F0B, (0x364, 0x1)), + (0x01FDF, (0x106, 0x3)), + (0x1D6FA, (0x13C7, 0x1)), + (0x1D616, (0x12E5, 0x1)), + (0x0246D, (0x23D, 0x2)), + (0x0FEE7, (0xF85, 0x1)), + (0x0FC5B, (0xB2C, 0x2)), + (0x003D2, (0x061, 0x1)), + (0x1D524, (0x11FA, 0x1)), + (0x0336F, (0x81D, 0x3)), + (0x0FBB1, (0xA1D, 0x2)), + (0x0FCAF, (0xBE5, 0x2)), + (0x02151, (0x1B6, 0x3)), + (0x02F7F, (0x3D8, 0x1)), + (0x0337B, (0x83B, 0x2)), + (0x1F219, (0x1641, 0x1)), + (0x1EEA7, (0x1582, 0x1)), + (0x0334A, (0x7AC, 0x6)), + (0x1E05C, (0x14F7, 0x1)), + (0x03235, (0x55A, 0x3)), + (0x0FF5B, (0x1003, 0x1)), + (0x1D608, (0x12D7, 0x1)), + (0x03375, (0x82D, 0x2)), + (0x02F6C, (0x3C5, 0x1)), + (0x1CCF2, (0x10DF, 0x1)), + (0x1D47B, (0x1161, 0x1)), + (0x1D62F, (0x12FE, 0x1)), + (0x032F3, (0x678, 0x1)), + (0x032AC, (0x60D, 0x1)), + (0x1D721, (0x13EE, 0x1)), + (0x1EE70, (0x1556, 0x1)), + (0x000BE, (0x015, 0x3)), + (0x033E5, (0x939, 0x2)), + (0x0FE7F, (0xF10, 0x2)), + (0x1D55D, (0x122C, 0x1)), + (0x0337C, (0x83D, 0x2)), + (0x0FBA7, (0xA12, 0x1)), + (0x1D5B1, (0x1280, 0x1)), + (0x033FC, (0x97A, 0x3)), + (0x1D6AA, (0x1377, 0x1)), + (0x1D4DF, (0x11BA, 0x1)), + (0x1D45F, (0x1145, 0x1)), + (0x1E032, (0x14CD, 0x1)), + (0x01D48, (0x0A2, 0x1)), + (0x1D769, (0x1436, 0x1)), + (0x1D704, (0x13D1, 0x1)), + (0x1D621, (0x12F0, 0x1)), + (0x033D1, (0x909, 0x2)), + (0x0FDBF, (0xE4F, 0x3)), + (0x1D73E, (0x140B, 0x1)), + (0x0322D, (0x542, 0x3)), + (0x0FB27, (0x9B4, 0x1)), + (0x1F22A, (0x1652, 0x1)), + (0x0FE17, (0xEB4, 0x1)), + (0x01D31, (0x08C, 0x1)), + (0x0FCFC, (0xC84, 0x2)), + (0x03218, (0x4FA, 0x4)), + (0x1F14D, (0x1623, 0x2)), + (0x0FD07, (0xC9A, 0x2)), + (0x0330A, (0x6AF, 0x3)), + (0x02F64, (0x3BD, 0x1)), + (0x02F60, (0x3B9, 0x1)), + (0x02002, (0x115, 0x1)), + (0x0FF72, (0x101A, 0x1)), + (0x0FD11, (0xCAE, 0x2)), + (0x1D66F, (0x133E, 0x1)), + (0x1EEBB, (0x1595, 0x1)), + (0x01DA6, (0x0D0, 0x1)), + (0x0FB21, (0x9AE, 0x1)), + (0x1D450, (0x1137, 0x1)), + (0x1D670, (0x133F, 0x1)), + (0x02477, (0x254, 0x3)), + (0x0FD36, (0xCF8, 0x2)), + (0x0FC44, (0xAFE, 0x2)), + (0x1EEB5, (0x158F, 0x1)), + (0x02153, (0x1BD, 0x3)), + (0x1D787, (0x1454, 0x1)), + (0x0FC8D, (0xB9C, 0x2)), + (0x1D40C, (0x10F3, 0x1)), + (0x0FC62, (0xB3E, 0x3)), + (0x107B9, (0x10C1, 0x1)), + (0x03384, (0x84F, 0x2)), + (0x1EE77, (0x155C, 0x1)), + (0x0FCC1, (0xC09, 0x2)), + (0x0FCB8, (0xBF7, 0x2)), + (0x0335D, (0x7EC, 0x2)), + (0x1F11C, (0x15D0, 0x3)), + (0x1D5AD, (0x127C, 0x1)), + (0x0FB9B, (0xA04, 0x1)), + (0x01FCE, (0x0FA, 0x3)), + (0x01D5D, (0x0B6, 0x1)), + (0x032FA, (0x67F, 0x1)), + (0x032DB, (0x660, 0x1)), + (0x0FEE5, (0xF83, 0x1)), + (0x0FE41, (0xECB, 0x1)), + (0x0FF04, (0xFAC, 0x1)), + (0x0208D, (0x15C, 0x1)), + (0x024CE, (0x32B, 0x1)), + (0x0FD92, (0xDC8, 0x3)), + (0x1D441, (0x1128, 0x1)), + (0x1078A, (0x1093, 0x1)), + (0x02F73, (0x3CC, 0x1)), + (0x02111, (0x186, 0x1)), + (0x1078E, (0x1097, 0x1)), + (0x033CD, (0x901, 0x2)), + (0x0249A, (0x2BF, 0x3)), + (0x1D7CE, (0x1499, 0x1)), + (0x0FF67, (0x100F, 0x1)), + (0x0FC74, (0xB6A, 0x2)), + (0x0FC89, (0xB94, 0x2)), + (0x0217F, (0x21E, 0x1)), + (0x02168, (0x1F5, 0x2)), + (0x1D59D, (0x126C, 0x1)), + (0x03261, (0x5AD, 0x1)), + (0x1D68F, (0x135E, 0x1)), + (0x0FB63, (0x9CC, 0x1)), + (0x1EE37, (0x1539, 0x1)), + (0x1D56C, (0x123B, 0x1)), + (0x03171, (0x47C, 0x1)), + (0x1D56D, (0x123C, 0x1)), + (0x0FE4A, (0xED3, 0x2)), + (0x1EEA2, (0x157E, 0x1)), + (0x0FE5E, (0xEE9, 0x1)), + (0x1D6B4, (0x1381, 0x1)), + (0x1D69B, (0x136A, 0x1)), + (0x0208E, (0x15D, 0x1)), + (0x0FE98, (0xF36, 0x1)), + (0x1D61E, (0x12ED, 0x1)), + (0x1D439, (0x1120, 0x1)), + (0x02172, (0x204, 0x3)), + (0x02F30, (0x389, 0x1)), + (0x1D52B, (0x1201, 0x1)), + (0x1D49B, (0x1181, 0x1)), + (0x02109, (0x17D, 0x2)), + (0x0FF50, (0xFF8, 0x1)), + (0x0315C, (0x467, 0x1)), + (0x0335F, (0x7F0, 0x2)), + (0x0314E, (0x459, 0x1)), + (0x03267, (0x5B3, 0x1)), + (0x02F74, (0x3CD, 0x1)), + (0x0FC93, (0xBA8, 0x2)), + (0x1EE98, (0x1579, 0x1)), + (0x1F243, (0x166D, 0x3)), + (0x01D60, (0x0B9, 0x1)), + (0x0FF62, (0x100A, 0x1)), + (0x1D6D9, (0x13A6, 0x1)), + (0x03167, (0x472, 0x1)), + (0x02480, (0x272, 0x4)), + (0x0FD69, (0xD53, 0x3)), + (0x033E0, (0x92F, 0x2)), + (0x03175, (0x480, 0x1)), + (0x0FC15, (0xAA0, 0x2)), + (0x1D536, (0x120C, 0x1)), + (0x0FBF8, (0xA61, 0x3)), + (0x0FE3B, (0xEC5, 0x1)), + (0x0211B, (0x18E, 0x1)), + (0x024AD, (0x2F8, 0x3)), + (0x1CCE3, (0x10D0, 0x1)), + (0x0331F, (0x708, 0x4)), + (0x0FE72, (0xEFA, 0x2)), + (0x1D65D, (0x132C, 0x1)), + (0x0FC6B, (0xB58, 0x2)), + (0x1D56B, (0x123A, 0x1)), + (0x0217C, (0x21B, 0x1)), + (0x1D7E4, (0x14AF, 0x1)), + (0x1D586, (0x1255, 0x1)), + (0x0FC8B, (0xB98, 0x2)), + (0x1D4A2, (0x1185, 0x1)), + (0x0FD53, (0xD11, 0x3)), + (0x0A770, (0x988, 0x1)), + (0x1D517, (0x11EE, 0x1)), + (0x1D7AA, (0x1477, 0x1)), + (0x1EE6F, (0x1555, 0x1)), + (0x1D559, (0x1228, 0x1)), + (0x00675, (0x070, 0x2)), + (0x03337, (0x767, 0x3)), + (0x107B6, (0x10BE, 0x1)), + (0x0FED0, (0xF6E, 0x1)), + (0x001F3, (0x03C, 0x2)), + (0x1CCD8, (0x10C5, 0x1)), + (0x0FF17, (0xFBF, 0x1)), + (0x1F22D, (0x1655, 0x1)), + (0x10791, (0x109A, 0x1)), + (0x1D78A, (0x1457, 0x1)), + (0x1EE2D, (0x1530, 0x1)), + (0x033D0, (0x907, 0x2)), + (0x0FB04, (0x99C, 0x3)), + (0x01D66, (0x0BF, 0x1)), + (0x0332B, (0x730, 0x6)), + (0x1F16A, (0x162A, 0x2)), + (0x1D7AF, (0x147C, 0x1)), + (0x0FC90, (0xBA2, 0x2)), + (0x0FF1E, (0xFC6, 0x1)), + (0x1D6F1, (0x13BE, 0x1)), + (0x0FD6C, (0xD5C, 0x3)), + (0x0FB59, (0x9C2, 0x1)), + (0x0FEAA, (0xF48, 0x1)), + (0x0FE7E, (0xF0E, 0x2)), + (0x0315D, (0x468, 0x1)), + (0x02F7C, (0x3D5, 0x1)), + (0x1D7C4, (0x1491, 0x1)), + (0x02D6F, (0x356, 0x1)), + (0x1D653, (0x1322, 0x1)), + (0x0FE36, (0xEC0, 0x1)), + (0x0FEC3, (0xF61, 0x1)), + (0x03220, (0x51B, 0x3)), + (0x1D74F, (0x141C, 0x1)), + (0x02F63, (0x3BC, 0x1)), + (0x1D658, (0x1327, 0x1)), + (0x1D7CF, (0x149A, 0x1)), + (0x0FC04, (0xA7D, 0x3)), + (0x1D682, (0x1351, 0x1)), + (0x1D622, (0x12F1, 0x1)), + (0x033FA, (0x974, 0x3)), + (0x1D6EC, (0x13B9, 0x1)), + (0x01D5B, (0x0B4, 0x1)), + (0x0FCBA, (0xBFB, 0x2)), + (0x033F8, (0x96E, 0x3)), + (0x1D5BF, (0x128E, 0x1)), + (0x0FCA4, (0xBCF, 0x2)), + (0x1EEB4, (0x158E, 0x1)), + (0x1F217, (0x163F, 0x1)), + (0x01DA7, (0x0D1, 0x1)), + (0x1D736, (0x1403, 0x1)), + (0x1D720, (0x13ED, 0x1)), + (0x0FD94, (0xDCE, 0x3)), + (0x1D519, (0x11F0, 0x1)), + (0x1E03F, (0x14DA, 0x1)), + (0x1D7EF, (0x14BA, 0x1)), + (0x033A1, (0x892, 0x2)), + (0x1F143, (0x1616, 0x1)), + (0x1D4A5, (0x1186, 0x1)), + (0x02F9C, (0x3F5, 0x1)), + (0x0330B, (0x6B2, 0x3)), + (0x107A7, (0x10B0, 0x1)), + (0x0FF21, (0xFC9, 0x1)), + (0x02FC1, (0x41A, 0x1)), + (0x0FECA, (0xF68, 0x1)), + (0x1D63B, (0x130A, 0x1)), + (0x1F146, (0x1619, 0x1)), + (0x1CCF3, (0x10E0, 0x1)), + (0x1D633, (0x1302, 0x1)), + (0x024B9, (0x316, 0x1)), + (0x0334D, (0x7BA, 0x4)), + (0x032E9, (0x66E, 0x1)), + (0x033CF, (0x905, 0x2)), + (0x1D5E9, (0x12B8, 0x1)), + (0x024C0, (0x31D, 0x1)), + (0x1D64C, (0x131B, 0x1)), + (0x1D6C4, (0x1391, 0x1)), + (0x1E044, (0x14DF, 0x1)), + (0x1D407, (0x10EE, 0x1)), + (0x1D4AA, (0x1189, 0x1)), + (0x0328F, (0x5F0, 0x1)), + (0x1D529, (0x11FF, 0x1)), + (0x0249B, (0x2C2, 0x3)), + (0x03348, (0x7A6, 0x4)), + (0x02F08, (0x361, 0x1)), + (0x1D49E, (0x1183, 0x1)), + (0x03189, (0x494, 0x1)), + (0x1D42C, (0x1113, 0x1)), + (0x0207A, (0x149, 0x1)), + (0x1D6C5, (0x1392, 0x1)), + (0x02005, (0x118, 0x1)), + (0x1D5C2, (0x1291, 0x1)), + (0x0FB76, (0x9DF, 0x1)), + (0x1D6F9, (0x13C6, 0x1)), + (0x03147, (0x452, 0x1)), + (0x03184, (0x48F, 0x1)), + (0x02F92, (0x3EB, 0x1)), + (0x1D5D7, (0x12A6, 0x1)), + (0x0FB83, (0x9EC, 0x1)), + (0x02090, (0x15E, 0x1)), + (0x0FEA5, (0xF43, 0x1)), + (0x1D79D, (0x146A, 0x1)), + (0x1D7D9, (0x14A4, 0x1)), + (0x0FCC0, (0xC07, 0x2)), + (0x03279, (0x5D0, 0x2)), + (0x1D78F, (0x145C, 0x1)), + (0x0321D, (0x50E, 0x7)), + (0x1D6C7, (0x1394, 0x1)), + (0x1CCF5, (0x10E2, 0x1)), + (0x1EE8F, (0x1570, 0x1)), + (0x1EE0F, (0x1517, 0x1)), + (0x0FCDF, (0xC45, 0x3)), + (0x1D501, (0x11DC, 0x1)), + (0x1D610, (0x12DF, 0x1)), + (0x1CCE0, (0x10CD, 0x1)), + (0x0FD21, (0xCCE, 0x2)), + (0x032E4, (0x669, 0x1)), + (0x1F13D, (0x1610, 0x1)), + (0x0FCF7, (0xC7A, 0x2)), + (0x0313D, (0x448, 0x1)), + (0x01D9D, (0x0C7, 0x1)), + (0x02474, (0x24B, 0x3)), + (0x0FFBD, (0x1065, 0x1)), + (0x1D7D0, (0x149B, 0x1)), + (0x1F232, (0x165A, 0x1)), + (0x1F225, (0x164D, 0x1)), + (0x1D7F1, (0x14BC, 0x1)), + (0x03232, (0x551, 0x3)), + (0x0249E, (0x2CB, 0x3)), + (0x02F75, (0x3CE, 0x1)), + (0x1F210, (0x1637, 0x1)), + (0x1D4D5, (0x11B0, 0x1)), + (0x03222, (0x521, 0x3)), + (0x1D782, (0x144F, 0x1)), + (0x10789, (0x1092, 0x1)), + (0x03305, (0x69C, 0x3)), + (0x0FF4B, (0xFF3, 0x1)), + (0x0FCB2, (0xBEB, 0x2)), + (0x03199, (0x4A1, 0x1)), + (0x0FEEA, (0xF88, 0x1)), + (0x03396, (0x87A, 0x2)), + (0x03247, (0x58A, 0x1)), + (0x0FC88, (0xB92, 0x2)), + (0x0FBA6, (0xA11, 0x1)), + (0x01D9C, (0x0C6, 0x1)), + (0x0FC82, (0xB86, 0x2)), + (0x1EE6A, (0x1551, 0x1)), + (0x0FD38, (0xCFC, 0x2)), + (0x03325, (0x720, 0x3)), + (0x1D6BF, (0x138C, 0x1)), + (0x1D4B4, (0x1192, 0x1)), + (0x1D6CA, (0x1397, 0x1)), + (0x0339E, (0x88A, 0x2)), + (0x1D641, (0x1310, 0x1)), + (0x0FE63, (0xEEE, 0x1)), + (0x024D0, (0x32D, 0x1)), + (0x0FC9B, (0xBBC, 0x3)), + (0x0FE8D, (0xF2B, 0x1)), + (0x01DA5, (0x0CF, 0x1)), + (0x0A7F9, (0x98D, 0x1)), + (0x1D43B, (0x1122, 0x1)), + (0x0FDBA, (0xE40, 0x3)), + (0x1F134, (0x1607, 0x1)), + (0x0FC77, (0xB70, 0x2)), + (0x02FB0, (0x409, 0x1)), + (0x1D426, (0x110D, 0x1)), + (0x1D453, (0x113A, 0x1)), + (0x1D5DC, (0x12AB, 0x1)), + (0x1D6F3, (0x13C0, 0x1)), + (0x1D5EC, (0x12BB, 0x1)), + (0x024C5, (0x322, 0x1)), + (0x03168, (0x473, 0x1)), + (0x1D6CF, (0x139C, 0x1)), + (0x024B0, (0x301, 0x3)), + (0x1D568, (0x1237, 0x1)), + (0x1F122, (0x15E2, 0x3)), + (0x1D52E, (0x1204, 0x1)), + (0x1D511, (0x11E9, 0x1)), + (0x02FB1, (0x40A, 0x1)), + (0x1F137, (0x160A, 0x1)), + (0x0FFAA, (0x1052, 0x1)), + (0x0FB69, (0x9D2, 0x1)), + (0x01FCF, (0x0FD, 0x3)), + (0x1D5AA, (0x1279, 0x1)), + (0x1D6F6, (0x13C3, 0x1)), + (0x1D4EC, (0x11C7, 0x1)), + (0x1D5CF, (0x129E, 0x1)), + (0x032A4, (0x605, 0x1)), + (0x033CE, (0x903, 0x2)), + (0x10781, (0x108B, 0x1)), + (0x02F6F, (0x3C8, 0x1)), + (0x1F126, (0x15EE, 0x3)), + (0x02F5A, (0x3B3, 0x1)), + (0x0FF68, (0x1010, 0x1)), + (0x02F88, (0x3E1, 0x1)), + (0x01DB0, (0x0DA, 0x1)), + (0x0FCD0, (0xC27, 0x2)), + (0x033B0, (0x8C2, 0x2)), + (0x0333D, (0x77E, 0x5)), + (0x1E069, (0x1504, 0x1)), + (0x0FF8D, (0x1035, 0x1)), + (0x1D70C, (0x13D9, 0x1)), + (0x1D643, (0x1312, 0x1)), + (0x0FBA0, (0xA09, 0x1)), + (0x03157, (0x462, 0x1)), + (0x1D457, (0x113D, 0x1)), + (0x0FE95, (0xF33, 0x1)), + (0x0FD83, (0xDA1, 0x3)), + (0x1D56F, (0x123E, 0x1)), + (0x02F16, (0x36F, 0x1)), + (0x1D731, (0x13FE, 0x1)), + (0x1D459, (0x113F, 0x1)), + (0x1D698, (0x1367, 0x1)), + (0x1D740, (0x140D, 0x1)), + (0x033F5, (0x965, 0x3)), + (0x0339D, (0x888, 0x2)), + (0x03224, (0x527, 0x3)), + (0x0FC1C, (0xAAE, 0x2)), + (0x1F116, (0x15BE, 0x3)), + (0x0213F, (0x1AC, 0x1)), + (0x0FC39, (0xAE8, 0x2)), + (0x0FF2C, (0xFD4, 0x1)), + (0x1D5C7, (0x1296, 0x1)), + (0x03377, (0x831, 0x2)), + (0x1D788, (0x1455, 0x1)), + (0x02FD5, (0x42E, 0x1)), + (0x1D75E, (0x142B, 0x1)), + (0x1D743, (0x1410, 0x1)), + (0x0320B, (0x4C9, 0x3)), + (0x1F238, (0x1660, 0x1)), + (0x033A2, (0x894, 0x3)), + (0x0FE78, (0xF02, 0x2)), + (0x0FE93, (0xF31, 0x1)), + (0x1D683, (0x1352, 0x1)), + (0x0FD64, (0xD44, 0x3)), + (0x1D634, (0x1303, 0x1)), + (0x0FF3B, (0xFE3, 0x1)), + (0x01D9E, (0x0C8, 0x1)), + (0x03327, (0x726, 0x2)), + (0x1F236, (0x165E, 0x1)), + (0x1D5C0, (0x128F, 0x1)), + (0x02FCC, (0x425, 0x1)), + (0x1D431, (0x1118, 0x1)), + (0x1EE0B, (0x1513, 0x1)), + (0x1D7BA, (0x1487, 0x1)), + (0x0FC48, (0xB06, 0x2)), + (0x0FEF3, (0xF91, 0x1)), + (0x1D4CE, (0x11A9, 0x1)), + (0x0FFC3, (0x1068, 0x1)), + (0x1D4FD, (0x11D8, 0x1)), + (0x0FC1B, (0xAAC, 0x2)), + (0x1EE8C, (0x156D, 0x1)), + (0x1D784, (0x1451, 0x1)), + (0x03264, (0x5B0, 0x1)), + (0x0FF7B, (0x1023, 0x1)), + (0x1EE59, (0x1547, 0x1)), + (0x1D790, (0x145D, 0x1)), + (0x02F31, (0x38A, 0x1)), + (0x0FF22, (0xFCA, 0x1)), + (0x0211D, (0x190, 0x1)), + (0x1E057, (0x14F2, 0x1)), + (0x1D6FE, (0x13CB, 0x1)), + (0x1D484, (0x116A, 0x1)), + (0x1D668, (0x1337, 0x1)), + (0x0FE5F, (0xEEA, 0x1)), + (0x1D562, (0x1231, 0x1)), + (0x0319F, (0x4A7, 0x1)), + (0x02074, (0x143, 0x1)), + (0x1D5EF, (0x12BE, 0x1)), + (0x107AB, (0x10B4, 0x1)), + (0x020A8, (0x16B, 0x2)), + (0x1E063, (0x14FE, 0x1)), + (0x0FC57, (0xB24, 0x2)), + (0x03356, (0x7D9, 0x6)), + (0x1D43D, (0x1124, 0x1)), + (0x0FCCF, (0xC25, 0x2)), + (0x01D47, (0x0A1, 0x1)), + (0x1D654, (0x1323, 0x1)), + (0x0FFE8, (0x1084, 0x1)), + (0x03302, (0x68F, 0x5)), + (0x0FCD9, (0xC39, 0x2)), + (0x1D639, (0x1308, 0x1)), + (0x1D79F, (0x146C, 0x1)), + (0x1D6B2, (0x137F, 0x1)), + (0x0FE8E, (0xF2C, 0x1)), + (0x1E048, (0x14E3, 0x1)), + (0x03039, (0x432, 0x1)), + (0x1E064, (0x14FF, 0x1)), + (0x033A0, (0x88F, 0x3)), + (0x1D49F, (0x1184, 0x1)), + (0x02F4C, (0x3A5, 0x1)), + (0x0FC31, (0xAD8, 0x2)), + (0x1D491, (0x1177, 0x1)), + (0x1E04D, (0x14E8, 0x1)), + (0x0FF16, (0xFBE, 0x1)), + (0x01D68, (0x0C1, 0x1)), + (0x0FF71, (0x1019, 0x1)), + (0x1EE76, (0x155B, 0x1)), + (0x1D423, (0x110A, 0x1)), + (0x01FCD, (0x0F7, 0x3)), + (0x0FE44, (0xECE, 0x1)), + (0x1F132, (0x1605, 0x1)), + (0x1D77C, (0x1449, 0x1)), + (0x0FF93, (0x103B, 0x1)), + (0x0331B, (0x6FA, 0x4)), + (0x1D7F5, (0x14C0, 0x1)), + (0x0FF8F, (0x1037, 0x1)), + (0x032A2, (0x603, 0x1)), + (0x1EE0E, (0x1516, 0x1)), + (0x1D6E8, (0x13B5, 0x1)), + (0x1D520, (0x11F6, 0x1)), + (0x033E4, (0x937, 0x2)), + (0x1D44E, (0x1135, 0x1)), + (0x1CCD9, (0x10C6, 0x1)), + (0x02FC4, (0x41D, 0x1)), + (0x02024, (0x121, 0x1)), + (0x010FC, (0x087, 0x1)), + (0x0FDB0, (0xE22, 0x3)), + (0x1EE87, (0x1569, 0x1)), + (0x03000, (0x42F, 0x1)), + (0x1FBF6, (0x1687, 0x1)), + (0x1D76F, (0x143C, 0x1)), + (0x03385, (0x851, 0x2)), + (0x0325D, (0x5A6, 0x2)), + (0x1D6C3, (0x1390, 0x1)), + (0x0FC0A, (0xA8A, 0x2)), + (0x1D67C, (0x134B, 0x1)), + (0x0FF9B, (0x1043, 0x1)), + (0x0FE7A, (0xF06, 0x2)), + (0x02FB4, (0x40D, 0x1)), + (0x02096, (0x164, 0x1)), + (0x0247C, (0x263, 0x3)), + (0x1D64A, (0x1319, 0x1)), + (0x1D785, (0x1452, 0x1)), + (0x1D7DA, (0x14A5, 0x1)), + (0x0FB17, (0x9AB, 0x2)), + (0x1D761, (0x142E, 0x1)), + (0x032C7, (0x63E, 0x2)), + (0x01FC0, (0x0F2, 0x2)), + (0x033E3, (0x935, 0x2)), + (0x0FCDB, (0xC3D, 0x2)), + (0x1D5B4, (0x1283, 0x1)), + (0x1D48F, (0x1175, 0x1)), + (0x0FC2A, (0xACA, 0x2)), + (0x1D55B, (0x122A, 0x1)), + (0x1D68A, (0x1359, 0x1)), + (0x1D637, (0x1306, 0x1)), + (0x0FFB6, (0x105E, 0x1)), + (0x1D770, (0x143D, 0x1)), + (0x107A4, (0x10AD, 0x1)), + (0x03186, (0x491, 0x1)), + (0x0FE18, (0xEB5, 0x1)), + (0x03253, (0x592, 0x2)), + (0x02163, (0x1E9, 0x2)), + (0x02F51, (0x3AA, 0x1)), + (0x003F5, (0x06C, 0x1)), + (0x0329B, (0x5FC, 0x1)), + (0x0FFB8, (0x1060, 0x1)), + (0x03215, (0x4EE, 0x4)), + (0x0FFA3, (0x104B, 0x1)), + (0x1D4CA, (0x11A5, 0x1)), + (0x0FBAB, (0xA16, 0x1)), + (0x0FF65, (0x100D, 0x1)), + (0x0FE5C, (0xEE7, 0x1)), + (0x0FC52, (0xB1A, 0x2)), + (0x02F9B, (0x3F4, 0x1)), + (0x1D51A, (0x11F1, 0x1)), + (0x03234, (0x557, 0x3)), + (0x00E33, (0x078, 0x2)), + (0x0FD8A, (0xDB6, 0x3)), + (0x0FD5A, (0xD26, 0x3)), + (0x02494, (0x2AD, 0x3)), + (0x02F80, (0x3D9, 0x1)), + (0x0FB67, (0x9D0, 0x1)), + (0x032A1, (0x602, 0x1)), + (0x1D797, (0x1464, 0x1)), + (0x0309C, (0x436, 0x2)), + (0x0FFE1, (0x107D, 0x1)), + (0x0FD7B, (0xD89, 0x3)), + (0x0FB61, (0x9CA, 0x1)), + (0x0FF10, (0xFB8, 0x1)), + (0x03280, (0x5E1, 0x1)), + (0x1F138, (0x160B, 0x1)), + (0x033AE, (0x8B7, 0x5)), + (0x10798, (0x10A1, 0x1)), + (0x1D738, (0x1405, 0x1)), + (0x0FC5D, (0xB30, 0x2)), + (0x1D50E, (0x11E6, 0x1)), + (0x02F4B, (0x3A4, 0x1)), + (0x02FA4, (0x3FD, 0x1)), + (0x032B6, (0x61C, 0x2)), + (0x032EB, (0x670, 0x1)), + (0x03135, (0x440, 0x1)), + (0x1D5C3, (0x1292, 0x1)), + (0x0FB97, (0xA00, 0x1)), + (0x0FCE8, (0xC59, 0x2)), + (0x0322B, (0x53C, 0x3)), + (0x0FC43, (0xAFC, 0x2)), + (0x032E5, (0x66A, 0x1)), + (0x0FBA5, (0xA0F, 0x2)), + (0x1D6EE, (0x13BB, 0x1)), + (0x0FD80, (0xD98, 0x3)), + (0x01DAC, (0x0D6, 0x1)), + (0x1CCDF, (0x10CC, 0x1)), + (0x1E03C, (0x14D7, 0x1)), + (0x02037, (0x12F, 0x3)), + (0x1D5F8, (0x12C7, 0x1)), + (0x1D66C, (0x133B, 0x1)), + (0x03150, (0x45B, 0x1)), + (0x03276, (0x5CA, 0x2)), + (0x1D4EA, (0x11C5, 0x1)), + (0x032BC, (0x628, 0x2)), + (0x1F145, (0x1618, 0x1)), + (0x0213E, (0x1AB, 0x1)), + (0x1D412, (0x10F9, 0x1)), + (0x10790, (0x1099, 0x1)), + (0x0FEDA, (0xF78, 0x1)), + (0x1F12E, (0x1601, 0x2)), + (0x1D4F1, (0x11CC, 0x1)), + (0x0FED2, (0xF70, 0x1)), + (0x0FD81, (0xD9B, 0x3)), + (0x03306, (0x69F, 0x3)), + (0x02473, (0x249, 0x2)), + (0x1D6B0, (0x137D, 0x1)), + (0x0FB9F, (0xA08, 0x1)), + (0x033B4, (0x8CA, 0x2)), + (0x03214, (0x4EA, 0x4)), + (0x1D7E2, (0x14AD, 0x1)), + (0x0331D, (0x701, 0x3)), + (0x1D578, (0x1247, 0x1)), + (0x02122, (0x196, 0x2)), + (0x0FF44, (0xFEC, 0x1)), + (0x1D4F7, (0x11D2, 0x1)), + (0x0FCD3, (0xC2D, 0x2)), + (0x0FFCA, (0x106D, 0x1)), + (0x000B5, (0x00A, 0x1)), + (0x0FC32, (0xADA, 0x2)), + (0x1D7C5, (0x1492, 0x1)), + (0x1D625, (0x12F4, 0x1)), + (0x032A3, (0x604, 0x1)), + (0x03311, (0x6C9, 0x4)), + (0x1EE2C, (0x152F, 0x1)), + (0x03180, (0x48B, 0x1)), + (0x0FB5D, (0x9C6, 0x1)), + (0x0FB25, (0x9B2, 0x1)), + (0x0FBEE, (0xA43, 0x3)), + (0x02FC7, (0x420, 0x1)), + (0x0322F, (0x548, 0x3)), + (0x1D5FE, (0x12CD, 0x1)), + (0x02F36, (0x38F, 0x1)), + (0x1D74D, (0x141A, 0x1)), + (0x1D5A5, (0x1274, 0x1)), + (0x02FC3, (0x41C, 0x1)), + (0x1E06C, (0x1507, 0x1)), + (0x1D508, (0x11E2, 0x1)), + (0x1D741, (0x140E, 0x1)), + (0x03221, (0x51E, 0x3)), + (0x1D512, (0x11EA, 0x1)), + (0x0FECE, (0xF6C, 0x1)), + (0x1D6D5, (0x13A2, 0x1)), + (0x032A7, (0x608, 0x1)), + (0x1D6B8, (0x1385, 0x1)), + (0x0FF06, (0xFAE, 0x1)), + (0x0FFE5, (0x1082, 0x1)), + (0x0323C, (0x56F, 0x3)), + (0x1CCE1, (0x10CE, 0x1)), + (0x0FE39, (0xEC3, 0x1)), + (0x0FBFC, (0xA6D, 0x1)), + (0x1F11D, (0x15D3, 0x3)), + (0x0FCCD, (0xC21, 0x2)), + (0x0FF42, (0xFEA, 0x1)), + (0x02189, (0x21F, 0x3)), + (0x00149, (0x020, 0x2)), + (0x01DB3, (0x0DD, 0x1)), + (0x1EE4D, (0x1540, 0x1)), + (0x1D6E7, (0x13B4, 0x1)), + (0x107A0, (0x10A9, 0x1)), + (0x002DD, (0x051, 0x2)), + (0x02F97, (0x3F0, 0x1)), + (0x1D71E, (0x13EB, 0x1)), + (0x1D4F9, (0x11D4, 0x1)), + (0x02102, (0x173, 0x1)), + (0x1D7B4, (0x1481, 0x1)), + (0x0315B, (0x466, 0x1)), + (0x0AB5D, (0x98F, 0x1)), + (0x001CB, (0x034, 0x2)), + (0x0FED9, (0xF77, 0x1)), + (0x02167, (0x1F1, 0x4)), + (0x0FD20, (0xCCC, 0x2)), + (0x1D69D, (0x136C, 0x1)), + (0x1D561, (0x1230, 0x1)), + (0x0213D, (0x1AA, 0x1)), + (0x1D7F4, (0x14BF, 0x1)), + (0x1D632, (0x1301, 0x1)), + (0x0FF9A, (0x1042, 0x1)), + (0x03389, (0x85A, 0x4)), + (0x02034, (0x12A, 0x3)), + (0x01D67, (0x0C0, 0x1)), + (0x0FF23, (0xFCB, 0x1)), + (0x1D577, (0x1246, 0x1)), + (0x0FEDC, (0xF7A, 0x1)), + (0x1D75B, (0x1428, 0x1)), + (0x1D4B9, (0x1197, 0x1)), + (0x033BA, (0x8D6, 0x2)), + (0x1D667, (0x1336, 0x1)), + (0x0331C, (0x6FE, 0x3)), + (0x1CCD7, (0x10C4, 0x1)), + (0x0FEC7, (0xF65, 0x1)), + (0x1CCF6, (0x10E3, 0x1)), + (0x1EE99, (0x157A, 0x1)), + (0x1CCEE, (0x10DB, 0x1)), + (0x1D5DA, (0x12A9, 0x1)), + (0x1D454, (0x113B, 0x1)), + (0x1EE94, (0x1575, 0x1)), + (0x1D4FC, (0x11D7, 0x1)), + (0x1D7A5, (0x1472, 0x1)), + (0x1F120, (0x15DC, 0x3)), + (0x1D72C, (0x13F9, 0x1)), + (0x0FE52, (0xEDE, 0x1)), + (0x1D684, (0x1353, 0x1)), + (0x0FE86, (0xF1D, 0x2)), + (0x03360, (0x7F2, 0x2)), + (0x02F0F, (0x368, 0x1)), + (0x1D5CE, (0x129D, 0x1)), + (0x1D60B, (0x12DA, 0x1)), + (0x1D5BA, (0x1289, 0x1)), + (0x02F10, (0x369, 0x1)), + (0x1D726, (0x13F3, 0x1)), + (0x0FFEB, (0x1087, 0x1)), + (0x02491, (0x2A4, 0x3)), + (0x0FE16, (0xEB3, 0x1)), + (0x1D754, (0x1421, 0x1)), + (0x032AD, (0x60E, 0x1)), + (0x02116, (0x18A, 0x2)), + (0x1D6CE, (0x139B, 0x1)), + (0x1D71D, (0x13EA, 0x1)), + (0x0FEA8, (0xF46, 0x1)), + (0x1D434, (0x111B, 0x1)), + (0x1D483, (0x1169, 0x1)), + (0x1D443, (0x112A, 0x1)), + (0x0FF1C, (0xFC4, 0x1)), + (0x0210A, (0x17F, 0x1)), + (0x1D6C1, (0x138E, 0x1)), + (0x1E040, (0x14DB, 0x1)), + (0x02F41, (0x39A, 0x1)), + (0x01DBD, (0x0E7, 0x1)), + (0x0FC2B, (0xACC, 0x2)), + (0x032CA, (0x645, 0x3)), + (0x03321, (0x711, 0x5)), + (0x03364, (0x7FC, 0x3)), + (0x1F130, (0x1603, 0x1)), + (0x02FBE, (0x417, 0x1)), + (0x0FE68, (0xEF2, 0x1)), + (0x0FCC4, (0xC0F, 0x2)), + (0x1D719, (0x13E6, 0x1)), + (0x1D5C8, (0x1297, 0x1)), + (0x1D4DC, (0x11B7, 0x1)), + (0x1D537, (0x120D, 0x1)), + (0x0FD3A, (0xD00, 0x2)), + (0x01D64, (0x0BD, 0x1)), + (0x0315E, (0x469, 0x1)), + (0x1EE19, (0x1521, 0x1)), + (0x0FF01, (0xFA9, 0x1)), + (0x1EE3B, (0x153B, 0x1)), + (0x1D4FE, (0x11D9, 0x1)), + (0x01FBF, (0x0F0, 0x2)), + (0x0216E, (0x1FF, 0x1)), + (0x1D5B3, (0x1282, 0x1)), + (0x01D44, (0x09E, 0x1)), + (0x032CD, (0x64D, 0x3)), + (0x01D42, (0x09C, 0x1)), + (0x1D56E, (0x123D, 0x1)), + (0x033DF, (0x92C, 0x3)), + (0x0FFB5, (0x105D, 0x1)), + (0x1E042, (0x14DD, 0x1)), + (0x02F81, (0x3DA, 0x1)), + (0x0FB6B, (0x9D4, 0x1)), + (0x0FCBF, (0xC05, 0x2)), + (0x0FD58, (0xD20, 0x3)), + (0x1D64E, (0x131D, 0x1)), + (0x0FEFC, (0xFA7, 0x2)), + (0x03246, (0x589, 0x1)), + (0x03162, (0x46D, 0x1)), + (0x02F65, (0x3BE, 0x1)), + (0x0FD96, (0xDD4, 0x3)), + (0x1D5E7, (0x12B6, 0x1)), + (0x03273, (0x5C4, 0x2)), + (0x0FCCE, (0xC23, 0x2)), + (0x003D5, (0x066, 0x1)), + (0x0326B, (0x5B7, 0x1)), + (0x032D0, (0x655, 0x1)), + (0x0FFE9, (0x1085, 0x1)), + (0x1D5D5, (0x12A4, 0x1)), + (0x1F21F, (0x1647, 0x1)), + (0x0FB8B, (0x9F4, 0x1)), + (0x0FEE0, (0xF7E, 0x1)), + (0x02F99, (0x3F2, 0x1)), + (0x02FA3, (0x3FC, 0x1)), + (0x0FBF5, (0xA58, 0x3)), + (0x1D43C, (0x1123, 0x1)), + (0x1D7B6, (0x1483, 0x1)), + (0x0FBE0, (0xA2D, 0x1)), + (0x1D40D, (0x10F4, 0x1)), + (0x1F144, (0x1617, 0x1)), + (0x03165, (0x470, 0x1)), + (0x0323D, (0x572, 0x3)), + (0x1D46C, (0x1152, 0x1)), + (0x1D4AE, (0x118C, 0x1)), + (0x02085, (0x154, 0x1)), + (0x02F86, (0x3DF, 0x1)), + (0x1EE95, (0x1576, 0x1)), + (0x0FDA8, (0xE0A, 0x3)), + (0x03228, (0x533, 0x3)), + (0x03213, (0x4E6, 0x4)), + (0x02485, (0x286, 0x4)), + (0x1D70A, (0x13D7, 0x1)), + (0x02F57, (0x3B0, 0x1)), + (0x1F14E, (0x1625, 0x3)), + (0x0FB96, (0x9FF, 0x1)), + (0x0FCE5, (0xC53, 0x2)), + (0x0317A, (0x485, 0x1)), + (0x03294, (0x5F5, 0x1)), + (0x1D786, (0x1453, 0x1)), + (0x024E4, (0x341, 0x1)), + (0x02495, (0x2B0, 0x3)), + (0x1F124, (0x15E8, 0x3)), + (0x03272, (0x5C2, 0x2)), + (0x02F9A, (0x3F3, 0x1)), + (0x0FD61, (0xD3B, 0x3)), + (0x0FCB0, (0xBE7, 0x2)), + (0x0FD02, (0xC90, 0x2)), + (0x1EEAB, (0x1585, 0x1)), + (0x1079F, (0x10A8, 0x1)), + (0x1D5AE, (0x127D, 0x1)), + (0x1D7B1, (0x147E, 0x1)), + (0x024C3, (0x320, 0x1)), + (0x0FC8E, (0xB9E, 0x2)), + (0x1D5E0, (0x12AF, 0x1)), + (0x0FFA9, (0x1051, 0x1)), + (0x01D33, (0x08E, 0x1)), + (0x1D505, (0x11E0, 0x1)), + (0x1D767, (0x1434, 0x1)), + (0x1D53D, (0x1212, 0x1)), + (0x1078F, (0x1098, 0x1)), + (0x0FC3F, (0xAF4, 0x2)), + (0x1D6A9, (0x1376, 0x1)), + (0x1D47A, (0x1160, 0x1)), + (0x0FC72, (0xB66, 0x2)), + (0x03151, (0x45C, 0x1)), + (0x03335, (0x75F, 0x3)), + (0x1D579, (0x1248, 0x1)), + (0x02F72, (0x3CB, 0x1)), + (0x0222F, (0x227, 0x2)), + (0x000BA, (0x00E, 0x1)), + (0x1D6BB, (0x1388, 0x1)), + (0x0FF03, (0xFAB, 0x1)), + (0x033B6, (0x8CE, 0x2)), + (0x1D419, (0x1100, 0x1)), + (0x1D763, (0x1430, 0x1)), + (0x02171, (0x202, 0x2)), + (0x02017, (0x11F, 0x2)), + (0x032B5, (0x61A, 0x2)), + (0x00132, (0x018, 0x2)), + (0x1EE8D, (0x156E, 0x1)), + (0x0319B, (0x4A3, 0x1)), + (0x1D5ED, (0x12BC, 0x1)), + (0x0FF58, (0x1000, 0x1)), + (0x0313C, (0x447, 0x1)), + (0x0FB7D, (0x9E6, 0x1)), + (0x03394, (0x875, 0x3)), + (0x02124, (0x198, 0x1)), + (0x02F50, (0x3A9, 0x1)), + (0x1D522, (0x11F8, 0x1)), + (0x0FF66, (0x100E, 0x1)), + (0x0FDFA, (0xE8F, 0x12)), + (0x0FC71, (0xB64, 0x2)), + (0x1D772, (0x143F, 0x1)), + (0x1D65A, (0x1329, 0x1)), + (0x1D7C6, (0x1493, 0x1)), + (0x0FEB8, (0xF56, 0x1)), + (0x0FEEE, (0xF8C, 0x1)), + (0x1EE61, (0x154B, 0x1)), + (0x0FB68, (0x9D1, 0x1)), + (0x1F103, (0x159C, 0x2)), + (0x1D585, (0x1254, 0x1)), + (0x03352, (0x7CC, 0x2)), + (0x0FDF2, (0xE70, 0x4)), + (0x0331A, (0x6F4, 0x6)), + (0x1D52C, (0x1202, 0x1)), + (0x0013F, (0x01C, 0x2)), + (0x02FAF, (0x408, 0x1)), + (0x032C1, (0x632, 0x2)), + (0x03320, (0x70C, 0x5)), + (0x1D5FD, (0x12CC, 0x1)), + (0x0FEB7, (0xF55, 0x1)), + (0x0FFE6, (0x1083, 0x1)), + (0x0FCE9, (0xC5B, 0x2)), + (0x0FD7A, (0xD86, 0x3)), + (0x0FF87, (0x102F, 0x1)), + (0x1EE1A, (0x1522, 0x1)), + (0x1F248, (0x167C, 0x3)), + (0x1D7C2, (0x148F, 0x1)), + (0x1D694, (0x1363, 0x1)), + (0x033B5, (0x8CC, 0x2)), + (0x03245, (0x588, 0x1)), + (0x1EE27, (0x152B, 0x1)), + (0x0FDBE, (0xE4C, 0x3)), + (0x1EE91, (0x1572, 0x1)), + (0x03329, (0x72A, 0x3)), + (0x1D4CF, (0x11AA, 0x1)), + (0x0FED3, (0xF71, 0x1)), + (0x02134, (0x1A0, 0x1)), + (0x03287, (0x5E8, 0x1)), + (0x024AE, (0x2FB, 0x3)), + (0x0FEB9, (0xF57, 0x1)), + (0x032AB, (0x60C, 0x1)), + (0x1D596, (0x1265, 0x1)), + (0x1D4F8, (0x11D3, 0x1)), + (0x0FEC9, (0xF67, 0x1)), + (0x1F22C, (0x1654, 0x1)), + (0x1F13A, (0x160D, 0x1)), + (0x032EF, (0x674, 0x1)), + (0x1D77F, (0x144C, 0x1)), + (0x02F82, (0x3DB, 0x1)), + (0x1D6E1, (0x13AE, 0x1)), + (0x03314, (0x6D7, 0x2)), + (0x0FEA4, (0xF42, 0x1)), + (0x1F115, (0x15BB, 0x3)), + (0x0222D, (0x224, 0x3)), + (0x1D4C9, (0x11A4, 0x1)), + (0x1D567, (0x1236, 0x1)), + (0x1D7EE, (0x14B9, 0x1)), + (0x032F1, (0x676, 0x1)), + (0x0FF8C, (0x1034, 0x1)), + (0x1D5A6, (0x1275, 0x1)), + (0x0FE61, (0xEEC, 0x1)), + (0x033EF, (0x953, 0x3)), + (0x02140, (0x1AD, 0x1)), + (0x1D659, (0x1328, 0x1)), + (0x1D542, (0x1216, 0x1)), + (0x03137, (0x442, 0x1)), + (0x02F2D, (0x386, 0x1)), + (0x1D4EE, (0x11C9, 0x1)), + (0x0FFE0, (0x107C, 0x1)), + (0x1D4E0, (0x11BB, 0x1)), + (0x01D34, (0x08F, 0x1)), + (0x1D6ED, (0x13BA, 0x1)), + (0x01DAD, (0x0D7, 0x1)), + (0x1D766, (0x1433, 0x1)), + (0x03380, (0x847, 0x2)), + (0x02170, (0x201, 0x1)), + (0x0FE35, (0xEBF, 0x1)), + (0x033A8, (0x8A5, 0x4)), + (0x1D650, (0x131F, 0x1)), + (0x01DB2, (0x0DC, 0x1)), + (0x1D4DD, (0x11B8, 0x1)), + (0x1F222, (0x164A, 0x1)), + (0x00587, (0x06E, 0x2)), + (0x02080, (0x14F, 0x1)), + (0x0FC8A, (0xB96, 0x2)), + (0x1D71C, (0x13E9, 0x1)), + (0x1D52A, (0x1200, 0x1)), + (0x1D557, (0x1226, 0x1)), + (0x0A69C, (0x986, 0x1)), + (0x0FD66, (0xD4A, 0x3)), + (0x02A74, (0x34C, 0x3)), + (0x1D764, (0x1431, 0x1)), + (0x1D45D, (0x1143, 0x1)), + (0x0FCBE, (0xC03, 0x2)), + (0x1D7F0, (0x14BB, 0x1)), + (0x0FBEA, (0xA37, 0x3)), + (0x02036, (0x12D, 0x2)), + (0x01FBD, (0x0EE, 0x2)), + (0x1D527, (0x11FD, 0x1)), + (0x1D5FB, (0x12CA, 0x1)), + (0x0FD57, (0xD1D, 0x3)), + (0x0318B, (0x496, 0x1)), + (0x0FDF5, (0xE7C, 0x4)), + (0x1078C, (0x1095, 0x1)), + (0x1CCF9, (0x10E6, 0x1)), + (0x1EEB6, (0x1590, 0x1)), + (0x1D6E3, (0x13B0, 0x1)), + (0x03166, (0x471, 0x1)), + (0x0338A, (0x85E, 0x2)), + (0x1D5EE, (0x12BD, 0x1)), + (0x03241, (0x57E, 0x3)), + (0x03365, (0x7FF, 0x3)), + (0x0FD39, (0xCFE, 0x2)), + (0x1EE17, (0x151F, 0x1)), + (0x1D432, (0x1119, 0x1)), + (0x1D56A, (0x1239, 0x1)), + (0x1D606, (0x12D5, 0x1)), + (0x0FEDD, (0xF7B, 0x1)), + (0x0FE64, (0xEEF, 0x1)), + (0x1D496, (0x117C, 0x1)), + (0x1CCEB, (0x10D8, 0x1)), + (0x1D7FA, (0x14C5, 0x1)), + (0x1D4BB, (0x1198, 0x1)), + (0x1D75C, (0x1429, 0x1)), + (0x001C9, (0x030, 0x2)), + (0x1FBF3, (0x1684, 0x1)), + (0x01D45, (0x09F, 0x1)), + (0x1D708, (0x13D5, 0x1)), + (0x1D781, (0x144E, 0x1)), + (0x01FDE, (0x103, 0x3)), + (0x1D64F, (0x131E, 0x1)), + (0x02FBD, (0x416, 0x1)), + (0x1D500, (0x11DB, 0x1)), + (0x033D7, (0x918, 0x2)), + (0x033A3, (0x897, 0x3)), + (0x1D502, (0x11DD, 0x1)), + (0x1D444, (0x112B, 0x1)), + (0x1D7C0, (0x148D, 0x1)), + (0x1D489, (0x116F, 0x1)), + (0x0FC4A, (0xB0A, 0x2)), + (0x0FCC3, (0xC0D, 0x2)), + (0x033A5, (0x89D, 0x2)), + (0x1D6C6, (0x1393, 0x1)), + (0x03258, (0x59C, 0x2)), + (0x02149, (0x1B2, 0x1)), + (0x107BA, (0x10C2, 0x1)), + (0x0FED6, (0xF74, 0x1)), + (0x1EE05, (0x150D, 0x1)), + (0x02EF3, (0x358, 0x1)), + (0x0FF94, (0x103C, 0x1)), + (0x0FC65, (0xB47, 0x3)), + (0x1E04E, (0x14E9, 0x1)), + (0x0FB91, (0x9FA, 0x1)), + (0x0FD12, (0xCB0, 0x2)), + (0x1D6C8, (0x1395, 0x1)), + (0x0FE4B, (0xED5, 0x2)), + (0x0249F, (0x2CE, 0x3)), + (0x01DA3, (0x0CD, 0x1)), + (0x032C2, (0x634, 0x2)), + (0x01D51, (0x0AA, 0x1)), + (0x1D7FF, (0x14CA, 0x1)), + (0x02076, (0x145, 0x1)), + (0x02F3C, (0x395, 0x1)), + (0x0FF63, (0x100B, 0x1)), + (0x01D3C, (0x096, 0x1)), + (0x1E03E, (0x14D9, 0x1)), + (0x1FBF5, (0x1686, 0x1)), + (0x001CC, (0x036, 0x2)), + (0x03286, (0x5E7, 0x1)), + (0x1D4EB, (0x11C6, 0x1)), + (0x1F230, (0x1658, 0x1)), + (0x0FCAA, (0xBDB, 0x2)), + (0x02FC5, (0x41E, 0x1)), + (0x03227, (0x530, 0x3)), + (0x0FB00, (0x993, 0x2)), + (0x1F13E, (0x1611, 0x1)), + (0x0FE77, (0xF00, 0x2)), + (0x1D7B5, (0x1482, 0x1)), + (0x0FFBB, (0x1063, 0x1)), + (0x03353, (0x7CE, 0x4)), + (0x01D9B, (0x0C5, 0x1)), + (0x1D72B, (0x13F8, 0x1)), + (0x1F21B, (0x1643, 0x1)), + (0x0338B, (0x860, 0x2)), + (0x02F61, (0x3BA, 0x1)), + (0x02C7C, (0x354, 0x1)), + (0x0FC00, (0xA71, 0x3)), + (0x0FF96, (0x103E, 0x1)), + (0x003F0, (0x068, 0x1)), + (0x1EE0D, (0x1515, 0x1)), + (0x0FF6D, (0x1015, 0x1)), + (0x0FD54, (0xD14, 0x3)), + (0x0FE33, (0xEBD, 0x1)), + (0x02F09, (0x362, 0x1)), + (0x1D5A1, (0x1270, 0x1)), + (0x03233, (0x554, 0x3)), + (0x02F21, (0x37A, 0x1)), + (0x1D4F4, (0x11CF, 0x1)), + (0x02FAA, (0x403, 0x1)), + (0x02F55, (0x3AE, 0x1)), + (0x1D49A, (0x1180, 0x1)), + (0x1F234, (0x165C, 0x1)), + (0x1E060, (0x14FB, 0x1)), + (0x1D6E0, (0x13AD, 0x1)), + (0x1D433, (0x111A, 0x1)), + (0x1D77B, (0x1448, 0x1)), + (0x0FD22, (0xCD0, 0x2)), + (0x03141, (0x44C, 0x1)), + (0x0FE9C, (0xF3A, 0x1)), + (0x1D46D, (0x1153, 0x1)), + (0x0329D, (0x5FE, 0x1)), + (0x032EC, (0x671, 0x1)), + (0x0FFBC, (0x1064, 0x1)), + (0x0FC5F, (0xB35, 0x3)), + (0x1EE7B, (0x155F, 0x1)), + (0x03236, (0x55D, 0x3)), + (0x1D67B, (0x134A, 0x1)), + (0x033E1, (0x931, 0x2)), + (0x1EE18, (0x1520, 0x1)), + (0x024E3, (0x340, 0x1)), + (0x1F22E, (0x1656, 0x1)), + (0x1D657, (0x1326, 0x1)), + (0x1D4B7, (0x1195, 0x1)), + (0x030FF, (0x43A, 0x2)), + (0x0FB64, (0x9CD, 0x1)), + (0x0FCFF, (0xC8A, 0x2)), + (0x000B9, (0x00D, 0x1)), + (0x03139, (0x444, 0x1)), + (0x01D3E, (0x098, 0x1)), + (0x003D6, (0x067, 0x1)), + (0x02088, (0x157, 0x1)), + (0x0FE54, (0xEDF, 0x1)), + (0x03263, (0x5AF, 0x1)), + (0x0FFC4, (0x1069, 0x1)), + (0x1D7CB, (0x1498, 0x1)), + (0x1D584, (0x1253, 0x1)), + (0x02100, (0x16D, 0x3)), + (0x03332, (0x74F, 0x6)), + (0x0FBF2, (0xA4F, 0x3)), + (0x0317B, (0x486, 0x1)), + (0x0FBF1, (0xA4C, 0x3)), + (0x001C6, (0x029, 0x3)), + (0x0FC83, (0xB88, 0x2)), + (0x024A7, (0x2E6, 0x3)), + (0x1D6C9, (0x1396, 0x1)), + (0x01D53, (0x0AC, 0x1)), + (0x032BA, (0x624, 0x2)), + (0x1F13C, (0x160F, 0x1)), + (0x02178, (0x213, 0x2)), + (0x1F237, (0x165F, 0x1)), + (0x1D751, (0x141E, 0x1)), + (0x1D479, (0x115F, 0x1)), + (0x0215D, (0x1DB, 0x3)), + (0x02F17, (0x370, 0x1)), + (0x0FF48, (0xFF0, 0x1)), + (0x0FC38, (0xAE6, 0x2)), + (0x1D465, (0x114B, 0x1)), + (0x02FCD, (0x426, 0x1)), + (0x01D59, (0x0B2, 0x1)), + (0x1D65F, (0x132E, 0x1)), + (0x03393, (0x872, 0x3)), + (0x024E9, (0x346, 0x1)), + (0x024DB, (0x338, 0x1)), + (0x0FD0B, (0xCA2, 0x2)), + (0x0208A, (0x159, 0x1)), + (0x0FE5A, (0xEE5, 0x1)), + (0x01D4B, (0x0A5, 0x1)), + (0x0FD0D, (0xCA6, 0x2)), + (0x01D2E, (0x08A, 0x1)), + (0x03288, (0x5E9, 0x1)), + (0x1D699, (0x1368, 0x1)), + (0x0FE92, (0xF30, 0x1)), + (0x1F11A, (0x15CA, 0x3)), + (0x1D589, (0x1258, 0x1)), + (0x1E04B, (0x14E6, 0x1)), + (0x02F3D, (0x396, 0x1)), + (0x1D45A, (0x1140, 0x1)), + (0x0FF4C, (0xFF4, 0x1)), + (0x1D789, (0x1456, 0x1)), + (0x0A7F2, (0x989, 0x1)), + (0x02497, (0x2B6, 0x3)), + (0x0FF7C, (0x1024, 0x1)), + (0x033D6, (0x915, 0x3)), + (0x0FFA6, (0x104E, 0x1)), + (0x1E033, (0x14CE, 0x1)), + (0x1D581, (0x1250, 0x1)), + (0x0FF2D, (0xFD5, 0x1)), + (0x1D46F, (0x1155, 0x1)), + (0x1D5F5, (0x12C4, 0x1)), + (0x1EE7E, (0x1561, 0x1)), + (0x1D497, (0x117D, 0x1)), + (0x1D594, (0x1263, 0x1)), + (0x1D499, (0x117F, 0x1)), + (0x1D57C, (0x124B, 0x1)), + (0x01D32, (0x08D, 0x1)), + (0x1D5CB, (0x129A, 0x1)), + (0x1D783, (0x1450, 0x1)), + (0x1D4E8, (0x11C3, 0x1)), + (0x1D58E, (0x125D, 0x1)), + (0x0FF0D, (0xFB5, 0x1)), + (0x0FB88, (0x9F1, 0x1)), + (0x1D474, (0x115A, 0x1)), + (0x02F52, (0x3AB, 0x1)), + (0x1D68E, (0x135D, 0x1)), + (0x03297, (0x5F8, 0x1)), + (0x1EE83, (0x1565, 0x1)), + (0x02FCB, (0x424, 0x1)), + (0x0FF32, (0xFDA, 0x1)), + (0x0FFAB, (0x1053, 0x1)), + (0x1CCEF, (0x10DC, 0x1)), + (0x0FC95, (0xBAC, 0x2)), + (0x02A76, (0x351, 0x3)), + (0x0FE74, (0xEFC, 0x2)), + (0x1D63A, (0x1309, 0x1)), + (0x1D4CB, (0x11A6, 0x1)), + (0x033BF, (0x8E0, 0x2)), + (0x1D664, (0x1333, 0x1)), + (0x1F224, (0x164C, 0x1)), + (0x00676, (0x072, 0x2)), + (0x03277, (0x5CC, 0x2)), + (0x1D6AC, (0x1379, 0x1)), + (0x033E9, (0x941, 0x3)), + (0x0FEBE, (0xF5C, 0x1)), + (0x0FEE8, (0xF86, 0x1)), + (0x0FF3C, (0xFE4, 0x1)), + (0x1D7BE, (0x148B, 0x1)), + (0x0FDA0, (0xDF2, 0x3)), + (0x0314B, (0x456, 0x1)), + (0x02F79, (0x3D2, 0x1)), + (0x0FC66, (0xB4A, 0x3)), + (0x0FD1F, (0xCCA, 0x2)), + (0x0FB81, (0x9EA, 0x1)), + (0x0FCC9, (0xC19, 0x2)), + (0x1D5B5, (0x1284, 0x1)), + (0x0FEF4, (0xF92, 0x1)), + (0x0339F, (0x88C, 0x3)), + (0x1D6FD, (0x13CA, 0x1)), + (0x02107, (0x17C, 0x1)), + (0x0FE9E, (0xF3C, 0x1)), + (0x1D745, (0x1412, 0x1)), + (0x0249D, (0x2C8, 0x3)), + (0x02F8F, (0x3E8, 0x1)), + (0x1EE31, (0x1534, 0x1)), + (0x1D5B0, (0x127F, 0x1)), + (0x1D5F3, (0x12C2, 0x1)), + (0x01D5F, (0x0B8, 0x1)), + (0x1D7BB, (0x1488, 0x1)), + (0x0FF33, (0xFDB, 0x1)), + (0x1EE5B, (0x1548, 0x1)), + (0x1D747, (0x1414, 0x1)), + (0x0337D, (0x83F, 0x2)), + (0x0FCF8, (0xC7C, 0x2)), + (0x1D796, (0x1463, 0x1)), + (0x03194, (0x49C, 0x1)), + (0x03196, (0x49E, 0x1)), + (0x03292, (0x5F3, 0x1)), + (0x0FD3D, (0xD06, 0x2)), + (0x1D535, (0x120B, 0x1)), + (0x03149, (0x454, 0x1)), + (0x1D62D, (0x12FC, 0x1)), + (0x0FF55, (0xFFD, 0x1)), + (0x0FDB6, (0xE34, 0x3)), + (0x1D604, (0x12D3, 0x1)), + (0x02095, (0x163, 0x1)), + (0x03219, (0x4FE, 0x4)), + (0x032C8, (0x640, 0x2)), + (0x1CCDA, (0x10C7, 0x1)), + (0x0210E, (0x183, 0x1)), + (0x0FC2C, (0xACE, 0x2)), + (0x1F108, (0x15A6, 0x2)), + (0x1D687, (0x1356, 0x1)), + (0x1D702, (0x13CF, 0x1)), + (0x1D615, (0x12E4, 0x1)), + (0x02F0C, (0x365, 0x1)), + (0x03185, (0x490, 0x1)), + (0x1D42A, (0x1111, 0x1)), + (0x03254, (0x594, 0x2)), + (0x0FFB9, (0x1061, 0x1)), + (0x1D428, (0x110F, 0x1)), + (0x1D72E, (0x13FB, 0x1)), + (0x0209A, (0x168, 0x1)), + (0x1D689, (0x1358, 0x1)), + (0x033E2, (0x933, 0x2)), + (0x0FC75, (0xB6C, 0x2)), + (0x0FBF6, (0xA5B, 0x3)), + (0x0FBDA, (0xA26, 0x1)), + (0x1D44A, (0x1131, 0x1)), + (0x0FF5C, (0x1004, 0x1)), + (0x0FEE3, (0xF81, 0x1)), + (0x02162, (0x1E6, 0x3)), + (0x03181, (0x48C, 0x1)), + (0x0321E, (0x515, 0x6)), + (0x032BE, (0x62C, 0x2)), + (0x1F201, (0x1634, 0x2)), + (0x0FDF7, (0xE84, 0x4)), + (0x107A5, (0x10AE, 0x1)), + (0x0FC1F, (0xAB4, 0x2)), + (0x0FC84, (0xB8A, 0x2)), + (0x033C2, (0x8E6, 0x4)), + (0x0FDF6, (0xE80, 0x4)), + (0x02FA0, (0x3F9, 0x1)), + (0x1F109, (0x15A8, 0x2)), + (0x024B4, (0x30D, 0x3)), + (0x1D5B7, (0x1286, 0x1)), + (0x0248F, (0x2A0, 0x2)), + (0x0247A, (0x25D, 0x3)), + (0x0AB5E, (0x990, 0x1)), + (0x032DA, (0x65F, 0x1)), + (0x0FD50, (0xD08, 0x3)), + (0x0336B, (0x811, 0x3)), + (0x024D9, (0x336, 0x1)), + (0x0FD16, (0xCB8, 0x2)), + (0x03251, (0x58E, 0x2)), + (0x02F90, (0x3E9, 0x1)), + (0x0FE8F, (0xF2D, 0x1)), + (0x03398, (0x87E, 0x2)), + (0x02F1C, (0x375, 0x1)), + (0x0FCE1, (0xC4B, 0x2)), + (0x0249C, (0x2C5, 0x3)), + (0x1D7C9, (0x1496, 0x1)), + (0x0FD62, (0xD3E, 0x3)), + (0x0FD1B, (0xCC2, 0x2)), + (0x03373, (0x828, 0x2)), + (0x1E054, (0x14EF, 0x1)), + (0x0FD06, (0xC98, 0x2)), + (0x02FCA, (0x423, 0x1)), + (0x1D526, (0x11FC, 0x1)), + (0x02461, (0x22D, 0x1)), + (0x03136, (0x441, 0x1)), + (0x0FC7D, (0xB7C, 0x2)), + (0x0FB87, (0x9F0, 0x1)), + (0x0FEAC, (0xF4A, 0x1)), + (0x0317E, (0x489, 0x1)), + (0x032E7, (0x66C, 0x1)), + (0x1D76B, (0x1438, 0x1)), + (0x0FB9C, (0xA05, 0x1)), + (0x1D44B, (0x1132, 0x1)), + (0x1EE06, (0x150E, 0x1)), + (0x03216, (0x4F2, 0x4)), + (0x033BD, (0x8DC, 0x2)), + (0x1F148, (0x161B, 0x1)), + (0x1F216, (0x163E, 0x1)), + (0x1D4AC, (0x118B, 0x1)), + (0x0FB13, (0x9A3, 0x2)), + (0x1D5CC, (0x129B, 0x1)), + (0x1F214, (0x163C, 0x1)), + (0x0FC20, (0xAB6, 0x2)), + (0x02F04, (0x35D, 0x1)), + (0x1D78D, (0x145A, 0x1)), + (0x0FCA9, (0xBD9, 0x2)), + (0x0FE62, (0xEED, 0x1)), + (0x0FC7A, (0xB76, 0x2)), + (0x1D4F6, (0x11D1, 0x1)), + (0x1E034, (0x14CF, 0x1)), + (0x0FC1E, (0xAB2, 0x2)), + (0x01D5C, (0x0B5, 0x1)), + (0x01D4C, (0x0A6, 0x1)), + (0x0246A, (0x237, 0x2)), + (0x0FBD6, (0xA22, 0x1)), + (0x02F7B, (0x3D4, 0x1)), + (0x033CB, (0x8FD, 0x2)), + (0x0FD08, (0xC9C, 0x2)), + (0x1F190, (0x1630, 0x2)), + (0x1CCE4, (0x10D1, 0x1)), + (0x0FD78, (0xD80, 0x3)), + (0x0336D, (0x817, 0x3)), + (0x0A7F4, (0x98B, 0x1)), + (0x0FCF3, (0xC70, 0x3)), + (0x0217D, (0x21C, 0x1)), + (0x1D5A0, (0x126F, 0x1)), + (0x0FD5F, (0xD35, 0x3)), + (0x000B4, (0x008, 0x2)), + (0x0322E, (0x545, 0x3)), + (0x1EEBA, (0x1594, 0x1)), + (0x1F229, (0x1651, 0x1)), + (0x1D5DD, (0x12AC, 0x1)), + (0x1E067, (0x1502, 0x1)), + (0x0FC5A, (0xB2A, 0x2)), + (0x0FD95, (0xDD1, 0x3)), + (0x1F118, (0x15C4, 0x3)), + (0x1EE08, (0x1510, 0x1)), + (0x02FC8, (0x421, 0x1)), + (0x0FCC6, (0xC13, 0x2)), + (0x1D6B1, (0x137E, 0x1)), + (0x1D4CD, (0x11A8, 0x1)), + (0x1D472, (0x1158, 0x1)), + (0x1D74C, (0x1419, 0x1)), + (0x1D54C, (0x121C, 0x1)), + (0x1E031, (0x14CC, 0x1)), + (0x02490, (0x2A2, 0x2)), + (0x0FC09, (0xA88, 0x2)), + (0x1FBF4, (0x1685, 0x1)), + (0x02460, (0x22C, 0x1)), + (0x0FF07, (0xFAF, 0x1)), + (0x0FBF9, (0xA64, 0x3)), + (0x02154, (0x1C0, 0x3)), + (0x1D679, (0x1348, 0x1)), + (0x03223, (0x524, 0x3)), + (0x1D712, (0x13DF, 0x1)), + (0x0FE99, (0xF37, 0x1)), + (0x1D6D8, (0x13A5, 0x1)), + (0x1D677, (0x1346, 0x1)), + (0x1CCE7, (0x10D4, 0x1)), + (0x1D470, (0x1156, 0x1)), + (0x0FC69, (0xB53, 0x3)), + (0x02FC6, (0x41F, 0x1)), + (0x1D541, (0x1215, 0x1)), + (0x1D7E1, (0x14AC, 0x1)), + (0x0FF75, (0x101D, 0x1)), + (0x032D4, (0x659, 0x1)), + (0x01DAE, (0x0D8, 0x1)), + (0x0FFDC, (0x107B, 0x1)), + (0x033D4, (0x910, 0x2)), + (0x0FC94, (0xBAA, 0x2)), + (0x0FB28, (0x9B5, 0x1)), + (0x0FD67, (0xD4D, 0x3)), + (0x1CCE2, (0x10CF, 0x1)), + (0x0211A, (0x18D, 0x1)), + (0x0FE38, (0xEC2, 0x1)), + (0x01D39, (0x094, 0x1)), + (0x1D7F3, (0x14BE, 0x1)), + (0x1F11F, (0x15D9, 0x3)), + (0x0FF91, (0x1039, 0x1)), + (0x032E2, (0x667, 0x1)), + (0x0212D, (0x19B, 0x1)), + (0x1D467, (0x114D, 0x1)), + (0x02FA2, (0x3FB, 0x1)), + (0x0FC36, (0xAE2, 0x2)), + (0x1D730, (0x13FD, 0x1)), + (0x02F25, (0x37E, 0x1)), + (0x1D7D3, (0x149E, 0x1)), + (0x0FC27, (0xAC4, 0x2)), + (0x02079, (0x148, 0x1)), + (0x1D5A7, (0x1276, 0x1)), + (0x1D478, (0x115E, 0x1)), + (0x1F242, (0x166A, 0x3)), + (0x1EE71, (0x1557, 0x1)), + (0x1D59B, (0x126A, 0x1)), + (0x1078B, (0x1094, 0x1)), + (0x1D6F2, (0x13BF, 0x1)), + (0x0FDBC, (0xE46, 0x3)), + (0x0FB73, (0x9DC, 0x1)), + (0x02F69, (0x3C2, 0x1)), + (0x0200A, (0x11D, 0x1)), + (0x1EE69, (0x1550, 0x1)), + (0x1D57B, (0x124A, 0x1)), + (0x0FCEA, (0xC5D, 0x2)), + (0x0323F, (0x578, 0x3)), + (0x1D45C, (0x1142, 0x1)), + (0x0FFA0, (0x1048, 0x1)), + (0x1D429, (0x1110, 0x1)), + (0x1D5CA, (0x1299, 0x1)), + (0x1079C, (0x10A5, 0x1)), + (0x02F29, (0x382, 0x1)), + (0x0FD8D, (0xDBF, 0x3)), + (0x0FE50, (0xEDC, 0x1)), + (0x1D793, (0x1460, 0x1)), + (0x0209C, (0x16A, 0x1)), + (0x03340, (0x789, 0x5)), + (0x1EE7A, (0x155E, 0x1)), + (0x0326E, (0x5BA, 0x2)), + (0x1D69C, (0x136B, 0x1)), + (0x0317C, (0x487, 0x1)), + (0x1D424, (0x110B, 0x1)), + (0x0FCBB, (0xBFD, 0x2)), + (0x0FB7E, (0x9E7, 0x1)), + (0x1D678, (0x1347, 0x1)), + (0x024C6, (0x323, 0x1)), + (0x1E06B, (0x1506, 0x1)), + (0x1F110, (0x15AC, 0x3)), + (0x01D43, (0x09D, 0x1)), + (0x02498, (0x2B9, 0x3)), + (0x1D6AB, (0x1378, 0x1)), + (0x0FD7E, (0xD92, 0x3)), + (0x0FD9A, (0xDE0, 0x3)), + (0x1D449, (0x1130, 0x1)), + (0x1D5D9, (0x12A8, 0x1)), + (0x10784, (0x108E, 0x1)), + (0x01D5A, (0x0B3, 0x1)), + (0x0FC05, (0xA80, 0x2)), + (0x024BC, (0x319, 0x1)), + (0x033FB, (0x977, 0x3)), + (0x02F42, (0x39B, 0x1)), + (0x0338F, (0x868, 0x2)), + (0x0FC70, (0xB62, 0x2)), + (0x02091, (0x15F, 0x1)), + (0x03183, (0x48E, 0x1)), + (0x0336E, (0x81A, 0x3)), + (0x02093, (0x161, 0x1)), + (0x1D78C, (0x1459, 0x1)), + (0x1D5C6, (0x1295, 0x1)), + (0x0FDB5, (0xE31, 0x3)), + (0x1D5F9, (0x12C8, 0x1)), + (0x1D4BF, (0x119B, 0x1)), + (0x02F9F, (0x3F8, 0x1)), + (0x0319A, (0x4A2, 0x1)), + (0x03275, (0x5C8, 0x2)), + (0x1D5D1, (0x12A0, 0x1)), + (0x0FFED, (0x1089, 0x1)), + (0x0FDA4, (0xDFE, 0x3)), + (0x0FED1, (0xF6F, 0x1)), + (0x0FEA7, (0xF45, 0x1)), + (0x1D6A3, (0x1372, 0x1)), + (0x0FCE3, (0xC4F, 0x2)), + (0x1EEB1, (0x158B, 0x1)), + (0x03317, (0x6E5, 0x5)), + (0x0FE80, (0xF12, 0x1)), + (0x02101, (0x170, 0x3)), + (0x0328C, (0x5ED, 0x1)), + (0x0FBFD, (0xA6E, 0x1)), + (0x02F5F, (0x3B8, 0x1)), + (0x03278, (0x5CE, 0x2)), + (0x0FF11, (0xFB9, 0x1)), + (0x02F1A, (0x373, 0x1)), + (0x1EE90, (0x1571, 0x1)), + (0x024D5, (0x332, 0x1)), + (0x0247E, (0x26A, 0x4)), + (0x0FB93, (0x9FC, 0x1)), + (0x0FD10, (0xCAC, 0x2)), + (0x1D68D, (0x135C, 0x1)), + (0x1CCE8, (0x10D5, 0x1)), + (0x003F2, (0x06A, 0x1)), + (0x01DB9, (0x0E3, 0x1)), + (0x02F18, (0x371, 0x1)), + (0x1F149, (0x161C, 0x1)), + (0x01D65, (0x0BE, 0x1)), + (0x0FE8A, (0xF25, 0x2)), + (0x1F129, (0x15F7, 0x3)), + (0x0210D, (0x182, 0x1)), + (0x1D40E, (0x10F5, 0x1)), + (0x0333E, (0x783, 0x4)), + (0x1EE09, (0x1511, 0x1)), + (0x033DC, (0x925, 0x2)), + (0x0FDB4, (0xE2E, 0x3)), + (0x02099, (0x167, 0x1)), + (0x0FD2D, (0xCE6, 0x2)), + (0x032A0, (0x601, 0x1)), + (0x0FEBD, (0xF5B, 0x1)), + (0x0FF73, (0x101B, 0x1)), + (0x032D8, (0x65D, 0x1)), + (0x10794, (0x109D, 0x1)), + (0x0FBAA, (0xA15, 0x1)), + (0x0FE37, (0xEC1, 0x1)), + (0x0FF1A, (0xFC2, 0x1)), + (0x0FCA2, (0xBCB, 0x2)), + (0x0FD85, (0xDA7, 0x3)), + (0x1D78B, (0x1458, 0x1)), + (0x1D6A8, (0x1375, 0x1)), + (0x1D778, (0x1445, 0x1)), + (0x02F1B, (0x374, 0x1)), + (0x000B2, (0x006, 0x1)), + (0x03359, (0x7E4, 0x2)), + (0x03179, (0x484, 0x1)), + (0x0FB99, (0xA02, 0x1)), + (0x1D5B2, (0x1281, 0x1)), + (0x107A3, (0x10AC, 0x1)), + (0x1D626, (0x12F5, 0x1)), + (0x0318A, (0x495, 0x1)), + (0x1D4C0, (0x119C, 0x1)), + (0x0FBDF, (0xA2C, 0x1)), + (0x1D686, (0x1355, 0x1)), + (0x0FE40, (0xECA, 0x1)), + (0x02F2C, (0x385, 0x1)), + (0x1F136, (0x1609, 0x1)), + (0x02FCF, (0x428, 0x1)), + (0x02F3F, (0x398, 0x1)), + (0x0FE3E, (0xEC8, 0x1)), + (0x0327C, (0x5D6, 0x5)), + (0x0FF14, (0xFBC, 0x1)), + (0x1D53E, (0x1213, 0x1)), + (0x0314A, (0x455, 0x1)), + (0x1D636, (0x1305, 0x1)), + (0x0FDC3, (0xE5B, 0x3)), + (0x02F95, (0x3EE, 0x1)), + (0x1F113, (0x15B5, 0x3)), + (0x1D481, (0x1167, 0x1)), + (0x01DAA, (0x0D4, 0x1)), + (0x1D5F2, (0x12C1, 0x1)), + (0x1D5BD, (0x128C, 0x1)), + (0x1E045, (0x14E0, 0x1)), + (0x02F6A, (0x3C3, 0x1)), + (0x0FB8C, (0x9F5, 0x1)), + (0x02F5B, (0x3B4, 0x1)), + (0x1D7D4, (0x149F, 0x1)), + (0x0335E, (0x7EE, 0x2)), + (0x1D565, (0x1234, 0x1)), + (0x1D442, (0x1129, 0x1)), + (0x1D48A, (0x1170, 0x1)), + (0x0FCF2, (0xC6D, 0x3)), + (0x1F142, (0x1615, 0x1)), + (0x1D544, (0x1218, 0x1)), + (0x1D452, (0x1139, 0x1)), + (0x002D9, (0x049, 0x2)), + (0x1D573, (0x1242, 0x1)), + (0x0FF54, (0xFFC, 0x1)), + (0x0FCDC, (0xC3F, 0x2)), + (0x0FC4F, (0xB14, 0x2)), + (0x1D540, (0x1214, 0x1)), + (0x0FEAD, (0xF4B, 0x1)), + (0x0FCE0, (0xC48, 0x3)), + (0x0FDA6, (0xE04, 0x3)), + (0x0FB23, (0x9B0, 0x1)), + (0x1D446, (0x112D, 0x1)), + (0x1D66E, (0x133D, 0x1)), + (0x1EE07, (0x150F, 0x1)), + (0x01D36, (0x091, 0x1)), + (0x0FD1E, (0xCC8, 0x2)), + (0x10782, (0x108C, 0x1)), + (0x03160, (0x46B, 0x1)), + (0x03338, (0x76A, 0x4)), + (0x1D7C3, (0x1490, 0x1)), + (0x1F14F, (0x1628, 0x2)), + (0x1D41C, (0x1103, 0x1)), + (0x0FF60, (0x1008, 0x1)), + (0x1D7C1, (0x148E, 0x1)), + (0x1D473, (0x1159, 0x1)), + (0x0313F, (0x44A, 0x1)), + (0x1D582, (0x1251, 0x1)), + (0x0FC0F, (0xA94, 0x2)), + (0x1D569, (0x1238, 0x1)), + (0x03336, (0x762, 0x5)), + (0x03355, (0x7D7, 0x2)), + (0x1EE4B, (0x153F, 0x1)), + (0x03169, (0x474, 0x1)), + (0x0FB65, (0x9CE, 0x1)), + (0x0FFA7, (0x104F, 0x1)), + (0x03323, (0x719, 0x3)), + (0x1D6BC, (0x1389, 0x1)), + (0x01D4D, (0x0A7, 0x1)), + (0x1D7FB, (0x14C6, 0x1)), + (0x03300, (0x686, 0x5)), + (0x0FDF9, (0xE8C, 0x3)), + (0x1EE24, (0x152A, 0x1)), + (0x1EE03, (0x150C, 0x1)), + (0x03230, (0x54B, 0x3)), + (0x0FC19, (0xAA8, 0x2)), + (0x024A3, (0x2DA, 0x3)), + (0x1F239, (0x1661, 0x1)), + (0x0318C, (0x497, 0x1)), + (0x1D588, (0x1257, 0x1)), + (0x0FF69, (0x1011, 0x1)), + (0x0246F, (0x241, 0x2)), + (0x02F13, (0x36C, 0x1)), + (0x024C4, (0x321, 0x1)), + (0x03178, (0x483, 0x1)), + (0x1EE81, (0x1563, 0x1)), + (0x02E9F, (0x357, 0x1)), + (0x1D6AD, (0x137A, 0x1)), + (0x0FC4D, (0xB10, 0x2)), + (0x0FEAF, (0xF4D, 0x1)), + (0x033F4, (0x962, 0x3)), + (0x032E1, (0x666, 0x1)), + (0x03319, (0x6EE, 0x6)), + (0x033C1, (0x8E4, 0x2)), + (0x1F100, (0x1596, 0x2)), + (0x02F34, (0x38D, 0x1)), + (0x1E030, (0x14CB, 0x1)), + (0x0FD9D, (0xDE9, 0x3)), + (0x1D47F, (0x1165, 0x1)), + (0x0FBA1, (0xA0A, 0x1)), + (0x1D48D, (0x1173, 0x1)), + (0x1F228, (0x1650, 0x1)), + (0x02120, (0x191, 0x2)), + (0x0FE88, (0xF21, 0x2)), + (0x0FB4F, (0x9B7, 0x2)), + (0x0205F, (0x140, 0x1)), + (0x033C9, (0x8F9, 0x2)), + (0x0207F, (0x14E, 0x1)), + (0x1D716, (0x13E3, 0x1)), + (0x1D673, (0x1342, 0x1)), + (0x1EE9A, (0x157B, 0x1)), + (0x1D7D5, (0x14A0, 0x1)), + (0x1D649, (0x1318, 0x1)), + (0x1EE5F, (0x154A, 0x1)), + (0x1D75A, (0x1427, 0x1)), + (0x1D5D4, (0x12A3, 0x1)), + (0x002E2, (0x055, 0x1)), + (0x0FEC1, (0xF5F, 0x1)), + (0x0309F, (0x438, 0x2)), + (0x0FB5E, (0x9C7, 0x1)), + (0x1D47E, (0x1164, 0x1)), + (0x1D707, (0x13D4, 0x1)), + (0x02F5E, (0x3B7, 0x1)), + (0x0FB9D, (0xA06, 0x1)), + (0x03326, (0x723, 0x3)), + (0x0FEA3, (0xF41, 0x1)), + (0x1E038, (0x14D3, 0x1)), + (0x01FC1, (0x0F4, 0x3)), + (0x1D71B, (0x13E8, 0x1)), + (0x032F4, (0x679, 0x1)), + (0x03346, (0x79E, 0x3)), + (0x1D7A0, (0x146D, 0x1)), + (0x02F4F, (0x3A8, 0x1)), + (0x03361, (0x7F4, 0x2)), + (0x1F211, (0x1638, 0x1)), + (0x1EE2F, (0x1532, 0x1)), + (0x1D4ED, (0x11C8, 0x1)), + (0x0FC9A, (0xBB9, 0x3)), + (0x1D4E1, (0x11BC, 0x1)), + (0x032A8, (0x609, 0x1)), + (0x1F226, (0x164E, 0x1)), + (0x000B8, (0x00B, 0x2)), + (0x1EE54, (0x1545, 0x1)), + (0x01D69, (0x0C2, 0x1)), + (0x0207B, (0x14A, 0x1)), + (0x1079B, (0x10A4, 0x1)), + (0x0FC0E, (0xA92, 0x2)), + (0x1EE1E, (0x1526, 0x1)), + (0x1D518, (0x11EF, 0x1)), + (0x1D420, (0x1107, 0x1)), + (0x0FBA3, (0xA0C, 0x1)), + (0x02FD0, (0x429, 0x1)), + (0x1D4C6, (0x11A1, 0x1)), + (0x03133, (0x43E, 0x1)), + (0x0FD33, (0xCF2, 0x2)), + (0x0FC12, (0xA9A, 0x2)), + (0x0FFBA, (0x1062, 0x1)), + (0x01D50, (0x0A9, 0x1)), + (0x0248A, (0x296, 0x2)), + (0x0FD05, (0xC96, 0x2)), + (0x0FDB9, (0xE3D, 0x3)), + (0x0210C, (0x181, 0x1)), + (0x0339B, (0x884, 0x2)), + (0x033E6, (0x93B, 0x2)), + (0x1D613, (0x12E2, 0x1)), + (0x1D7B2, (0x147F, 0x1)), + (0x0FBAF, (0xA1A, 0x1)), + (0x01DA2, (0x0CC, 0x1)), + (0x0316E, (0x479, 0x1)), + (0x02F48, (0x3A1, 0x1)), + (0x000AF, (0x004, 0x2)), + (0x10799, (0x10A2, 0x1)), + (0x0FBEB, (0xA3A, 0x3)), + (0x0315F, (0x46A, 0x1)), + (0x1EEB2, (0x158C, 0x1)), + (0x1D468, (0x114E, 0x1)), + (0x1D42F, (0x1116, 0x1)), + (0x0FC55, (0xB20, 0x2)), + (0x1D51C, (0x11F3, 0x1)), + (0x0FF92, (0x103A, 0x1)), + (0x03395, (0x878, 0x2)), + (0x1D674, (0x1343, 0x1)), + (0x1D722, (0x13EF, 0x1)), + (0x0FBE6, (0xA33, 0x1)), + (0x033A4, (0x89A, 0x3)), + (0x033F7, (0x96B, 0x3)), + (0x02001, (0x114, 0x1)), + (0x1F14B, (0x161F, 0x2)), + (0x1D733, (0x1400, 0x1)), + (0x0FEC0, (0xF5E, 0x1)), + (0x1D67D, (0x134C, 0x1)), + (0x0FC23, (0xABC, 0x2)), + (0x1D601, (0x12D0, 0x1)), + (0x02F85, (0x3DE, 0x1)), + (0x0037A, (0x058, 0x2)), + (0x032CF, (0x652, 0x3)), + (0x1F200, (0x1632, 0x2)), + (0x02499, (0x2BC, 0x3)), + (0x1D490, (0x1176, 0x1)), + (0x032F0, (0x675, 0x1)), + (0x02F19, (0x372, 0x1)), + (0x1D696, (0x1365, 0x1)), + (0x1D55E, (0x122D, 0x1)), + (0x0FCF5, (0xC76, 0x2)), + (0x0FC7F, (0xB80, 0x2)), + (0x0FC64, (0xB44, 0x3)), + (0x0FFB3, (0x105B, 0x1)), + (0x1F105, (0x15A0, 0x2)), + (0x1D748, (0x1415, 0x1)), + (0x1D405, (0x10EC, 0x1)), + (0x02113, (0x188, 0x1)), + (0x0FEE1, (0xF7F, 0x1)), + (0x1E05F, (0x14FA, 0x1)), + (0x0FCFD, (0xC86, 0x2)), + (0x0FF4E, (0xFF6, 0x1)), + (0x1D7F7, (0x14C2, 0x1)), + (0x0FFD5, (0x1076, 0x1)), + (0x0FCB3, (0xBED, 0x2)), + (0x0FB52, (0x9BB, 0x1)), + (0x1D595, (0x1264, 0x1)), + (0x1F147, (0x161A, 0x1)), + (0x0FE5D, (0xEE8, 0x1)), + (0x1D655, (0x1324, 0x1)), + (0x1D6B5, (0x1382, 0x1)), + (0x024BF, (0x31C, 0x1)), + (0x03256, (0x598, 0x2)), + (0x01FFE, (0x111, 0x2)), + (0x024BB, (0x318, 0x1)), + (0x1D6AF, (0x137C, 0x1)), + (0x03260, (0x5AC, 0x1)), + (0x02F01, (0x35A, 0x1)), + (0x0FC80, (0xB82, 0x2)), + (0x0325C, (0x5A4, 0x2)), + (0x1D6A0, (0x136F, 0x1)), + (0x03383, (0x84D, 0x2)), + (0x0FB22, (0x9AF, 0x1)), + (0x1D61C, (0x12EB, 0x1)), + (0x0216F, (0x200, 0x1)), + (0x01D57, (0x0B0, 0x1)), + (0x024D8, (0x335, 0x1)), + (0x1D773, (0x1440, 0x1)), + (0x0FC5E, (0xB32, 0x3)), + (0x1F213, (0x163A, 0x2)), + (0x1D70F, (0x13DC, 0x1)), + (0x1D5E6, (0x12B5, 0x1)), + (0x0FFA4, (0x104C, 0x1)), + (0x1F12D, (0x15FF, 0x2)), + (0x0FB16, (0x9A9, 0x2)), + (0x1E05A, (0x14F5, 0x1)), + (0x0FC79, (0xB74, 0x2)), + (0x02FA7, (0x400, 0x1)), + (0x0327A, (0x5D2, 0x2)), + (0x032FB, (0x680, 0x1)), + (0x002D8, (0x047, 0x2)), + (0x1EEA5, (0x1580, 0x1)), + (0x1CCEA, (0x10D7, 0x1)), + (0x02493, (0x2AA, 0x3)), + (0x1E04A, (0x14E5, 0x1)), + (0x1D598, (0x1267, 0x1)), + (0x02FAB, (0x404, 0x1)), + (0x1D758, (0x1425, 0x1)), + (0x1D4DA, (0x11B5, 0x1)), + (0x0FBDB, (0xA27, 0x1)), + (0x02164, (0x1EB, 0x1)), + (0x0FF83, (0x102B, 0x1)), + (0x02F94, (0x3ED, 0x1)), + (0x02483, (0x27E, 0x4)), + (0x032ED, (0x672, 0x1)), + (0x0334F, (0x7C2, 0x3)), + (0x1D737, (0x1404, 0x1)), + (0x0FDC4, (0xE5E, 0x3)), + (0x0FE55, (0xEE0, 0x1)), + (0x0FF7D, (0x1025, 0x1)), + (0x02489, (0x294, 0x2)), + (0x02FB5, (0x40E, 0x1)), + (0x0FE3C, (0xEC6, 0x1)), + (0x1D628, (0x12F7, 0x1)), + (0x032F5, (0x67A, 0x1)), + (0x0FF05, (0xFAD, 0x1)), + (0x0FFA8, (0x1050, 0x1)), + (0x1EE1D, (0x1525, 0x1)), + (0x03159, (0x464, 0x1)), + (0x02A0C, (0x348, 0x4)), + (0x1D746, (0x1413, 0x1)), + (0x0FECF, (0xF6D, 0x1)), + (0x0FBFB, (0xA6A, 0x3)), + (0x1D6D6, (0x13A3, 0x1)), + (0x02152, (0x1B9, 0x4)), + (0x1E043, (0x14DE, 0x1)), + (0x03172, (0x47D, 0x1)), + (0x107AA, (0x10B3, 0x1)), + (0x0FBDC, (0xA28, 0x1)), + (0x02158, (0x1CC, 0x3)), + (0x1D63D, (0x130C, 0x1)), + (0x0FEE2, (0xF80, 0x1)), + (0x024DC, (0x339, 0x1)), + (0x0FDC0, (0xE52, 0x3)), + (0x02F1E, (0x377, 0x1)), + (0x01D54, (0x0AD, 0x1)), + (0x1D759, (0x1426, 0x1)), + (0x1D553, (0x1222, 0x1)), + (0x10795, (0x109E, 0x1)), + (0x033B9, (0x8D4, 0x2)), + (0x1D5D2, (0x12A1, 0x1)), + (0x1D451, (0x1138, 0x1)), + (0x0335C, (0x7EA, 0x2)), + (0x03283, (0x5E4, 0x1)), + (0x032E6, (0x66B, 0x1)), + (0x03281, (0x5E2, 0x1)), + (0x107B0, (0x10B9, 0x1)), + (0x03371, (0x823, 0x3)), + (0x0FCF1, (0xC6B, 0x2)), + (0x1EE86, (0x1568, 0x1)), + (0x0FFDB, (0x107A, 0x1)), + (0x1D647, (0x1316, 0x1)), + (0x03210, (0x4DA, 0x4)), + (0x1D7CA, (0x1497, 0x1)), + (0x0FDF4, (0xE78, 0x4)), + (0x0FD0C, (0xCA4, 0x2)), + (0x02007, (0x11A, 0x1)), + (0x0333B, (0x775, 0x5)), + (0x02A75, (0x34F, 0x2)), + (0x03231, (0x54E, 0x3)), + (0x02F8D, (0x3E6, 0x1)), + (0x1D6DD, (0x13AA, 0x1)), + (0x107B5, (0x10BD, 0x1)), + (0x02F54, (0x3AD, 0x1)), + (0x0FB98, (0xA01, 0x1)), + (0x0FD60, (0xD38, 0x3)), + (0x1D495, (0x117B, 0x1)), + (0x0FF4D, (0xFF5, 0x1)), + (0x0313B, (0x446, 0x1)), + (0x0A7F3, (0x98A, 0x1)), + (0x1D7E5, (0x14B0, 0x1)), + (0x1D4F2, (0x11CD, 0x1)), + (0x1D65E, (0x132D, 0x1)), + (0x02F6D, (0x3C6, 0x1)), + (0x1EE00, (0x1509, 0x1)), + (0x02103, (0x174, 0x2)), + (0x0FF5D, (0x1005, 0x1)), + (0x1F16B, (0x162C, 0x2)), + (0x0FF8A, (0x1032, 0x1)), + (0x1D4B3, (0x1191, 0x1)), + (0x032FD, (0x682, 0x1)), + (0x1D74B, (0x1418, 0x1)), + (0x0FD03, (0xC92, 0x2)), + (0x1D471, (0x1157, 0x1)), + (0x1D576, (0x1245, 0x1)), + (0x1D493, (0x1179, 0x1)), + (0x0FF6A, (0x1012, 0x1)), + (0x0FE31, (0xEBB, 0x1)), + (0x0323A, (0x569, 0x3)), + (0x01D49, (0x0A3, 0x1)), + (0x1D7E9, (0x14B4, 0x1)), + (0x0FB6E, (0x9D7, 0x1)), + (0x0FC51, (0xB18, 0x2)), + (0x033ED, (0x94D, 0x3)), + (0x0FE15, (0xEB2, 0x1)), + (0x02F28, (0x381, 0x1)), + (0x1D6A4, (0x1373, 0x1)), + (0x1D4E2, (0x11BD, 0x1)), + (0x032CE, (0x650, 0x2)), + (0x02094, (0x162, 0x1)), + (0x1D6FC, (0x13C9, 0x1)), + (0x032F6, (0x67B, 0x1)), + (0x0FE9A, (0xF38, 0x1)), + (0x01DBE, (0x0E8, 0x1)), + (0x01DB7, (0x0E1, 0x1)), + (0x1D4BD, (0x1199, 0x1)), + (0x0FDA1, (0xDF5, 0x3)), + (0x1D6D7, (0x13A4, 0x1)), + (0x1D7BF, (0x148C, 0x1)), + (0x03316, (0x6DF, 0x6)), + (0x03391, (0x86C, 0x3)), + (0x1D744, (0x1411, 0x1)), + (0x1D41F, (0x1106, 0x1)), + (0x1EE84, (0x1566, 0x1)), + (0x0FFBE, (0x1066, 0x1)), + (0x03244, (0x587, 0x1)), + (0x1D58D, (0x125C, 0x1)), + (0x02FD1, (0x42A, 0x1)), + (0x0FF19, (0xFC1, 0x1)), + (0x1D5C5, (0x1294, 0x1)), + (0x1D663, (0x1332, 0x1)), + (0x1D723, (0x13F0, 0x1)), + (0x1F247, (0x1679, 0x3)), + (0x1F23B, (0x1663, 0x1)), + (0x0FCD6, (0xC33, 0x2)), + (0x01DB5, (0x0DF, 0x1)), + (0x02083, (0x152, 0x1)), + (0x024C9, (0x326, 0x1)), + (0x1D6CD, (0x139A, 0x1)), + (0x1D5A9, (0x1278, 0x1)), + (0x03307, (0x6A2, 0x6)), + (0x1D7DF, (0x14AA, 0x1)), + (0x1D692, (0x1361, 0x1)), + (0x1D509, (0x11E3, 0x1)), + (0x024AF, (0x2FE, 0x3)), + (0x1CCDE, (0x10CB, 0x1)), + (0x1EE93, (0x1574, 0x1)), + (0x0FD14, (0xCB4, 0x2)), + (0x0316C, (0x477, 0x1)), + (0x0FC42, (0xAFA, 0x2)), + (0x0FB70, (0x9D9, 0x1)), + (0x02F06, (0x35F, 0x1)), + (0x0FD8B, (0xDB9, 0x3)), + (0x03271, (0x5C0, 0x2)), + (0x03342, (0x791, 0x3)), + (0x03269, (0x5B5, 0x1)), + (0x1FBF1, (0x1682, 0x1)), + (0x032D6, (0x65B, 0x1)), + (0x0209B, (0x169, 0x1)), + (0x1D7B8, (0x1485, 0x1)), + (0x0FF56, (0xFFE, 0x1)), + (0x0FE60, (0xEEB, 0x1)), + (0x1D5E4, (0x12B3, 0x1)), + (0x1F233, (0x165B, 0x1)), + (0x0FF1D, (0xFC5, 0x1)), + (0x0FCF6, (0xC78, 0x2)), + (0x1D4DB, (0x11B6, 0x1)), + (0x02F67, (0x3C0, 0x1)), + (0x1D53B, (0x1210, 0x1)), + (0x0FBA4, (0xA0D, 0x2)), + (0x0336A, (0x80E, 0x3)), + (0x0FD1C, (0xCC4, 0x2)), + (0x1E061, (0x14FC, 0x1)), + (0x0FB95, (0x9FE, 0x1)), + (0x03257, (0x59A, 0x2)), + (0x1D560, (0x122F, 0x1)), + (0x032C5, (0x63A, 0x2)), + (0x1EE30, (0x1533, 0x1)), + (0x1D466, (0x114C, 0x1)), + (0x0FE9F, (0xF3D, 0x1)), + (0x03038, (0x431, 0x1)), + (0x032AE, (0x60F, 0x1)), + (0x1D7B0, (0x147D, 0x1)), + (0x1CCF0, (0x10DD, 0x1)), + (0x1D7E6, (0x14B1, 0x1)), + (0x0FCA0, (0xBC7, 0x2)), + (0x0336C, (0x814, 0x3)), + (0x0FD2B, (0xCE2, 0x2)), + (0x0FBAE, (0xA19, 0x1)), + (0x0FFB4, (0x105C, 0x1)), + (0x02F33, (0x38C, 0x1)), + (0x0FD3C, (0xD04, 0x2)), + (0x0FF31, (0xFD9, 0x1)), + (0x0332C, (0x736, 0x4)), + (0x1F12B, (0x15FD, 0x1)), + (0x033FE, (0x980, 0x3)), + (0x01D41, (0x09B, 0x1)), + (0x107B8, (0x10C0, 0x1)), + (0x1D62A, (0x12F9, 0x1)), + (0x1D631, (0x1300, 0x1)), + (0x1EEAC, (0x1586, 0x1)), + (0x02FB8, (0x411, 0x1)), + (0x1D4FB, (0x11D6, 0x1)), + (0x0FF76, (0x101E, 0x1)), + (0x0FC37, (0xAE4, 0x2)), + (0x0FC29, (0xAC8, 0x2)), + (0x1D6E6, (0x13B3, 0x1)), + (0x107A1, (0x10AA, 0x1)), + (0x0319D, (0x4A5, 0x1)), + (0x0FCAC, (0xBDF, 0x2)), + (0x03344, (0x798, 0x3)), + (0x0FE4C, (0xED7, 0x2)), + (0x0208B, (0x15A, 0x1)), + (0x107A9, (0x10B2, 0x1)), + (0x0FE96, (0xF34, 0x1)), + (0x0FC56, (0xB22, 0x2)), + (0x0FBFA, (0xA67, 0x3)), + (0x0FB85, (0x9EE, 0x1)), + (0x0FD89, (0xDB3, 0x3)), + (0x03295, (0x5F6, 0x1)), + (0x0FCA8, (0xBD7, 0x2)), + (0x002E0, (0x053, 0x1)), + (0x03350, (0x7C5, 0x3)), + (0x02147, (0x1B0, 0x1)), + (0x01D30, (0x08B, 0x1)), + (0x03387, (0x855, 0x2)), + (0x0317F, (0x48A, 0x1)), + (0x1F107, (0x15A4, 0x2)), + (0x1D555, (0x1224, 0x1)), + (0x1D6BE, (0x138B, 0x1)), + (0x0FEF5, (0xF93, 0x3)), + (0x03351, (0x7C8, 0x4)), + (0x1D4AB, (0x118A, 0x1)), + (0x02479, (0x25A, 0x3)), + (0x024CB, (0x328, 0x1)), + (0x0FF1F, (0xFC7, 0x1)), + (0x03212, (0x4E2, 0x4)), + (0x032C0, (0x630, 0x2)), + (0x1EE75, (0x155A, 0x1)), + (0x0A7F8, (0x98C, 0x1)), + (0x1F245, (0x1673, 0x3)), + (0x0FB57, (0x9C0, 0x1)), + (0x1F215, (0x163D, 0x1)), + (0x0FEA9, (0xF47, 0x1)), + (0x02484, (0x282, 0x4)), + (0x02FBF, (0x418, 0x1)), + (0x0FED5, (0xF73, 0x1)), + (0x1D4D6, (0x11B1, 0x1)), + (0x02F7A, (0x3D3, 0x1)), + (0x03242, (0x581, 0x3)), + (0x1D456, (0x113C, 0x1)), + (0x0FE14, (0xEB1, 0x1)), + (0x0FC59, (0xB28, 0x2)), + (0x0FCD7, (0xC35, 0x2)), + (0x0FE43, (0xECD, 0x1)), + (0x1D7D1, (0x149C, 0x1)), + (0x1D563, (0x1232, 0x1)), + (0x0FC4E, (0xB12, 0x2)), + (0x1F250, (0x167F, 0x1)), + (0x1D4F5, (0x11D0, 0x1)), + (0x0FBD5, (0xA21, 0x1)), + (0x1D661, (0x1330, 0x1)), + (0x03252, (0x590, 0x2)), + (0x0FECC, (0xF6A, 0x1)), + (0x0FF85, (0x102D, 0x1)), + (0x0FD51, (0xD0B, 0x3)), + (0x1D605, (0x12D4, 0x1)), + (0x0FBE5, (0xA32, 0x1)), + (0x1D4CC, (0x11A7, 0x1)), + (0x1F119, (0x15C7, 0x3)), + (0x1D638, (0x1307, 0x1)), + (0x0FDAF, (0xE1F, 0x3)), + (0x1D739, (0x1406, 0x1)), + (0x1F21A, (0x1642, 0x1)), + (0x0318E, (0x499, 0x1)), + (0x0316D, (0x478, 0x1)), + (0x03374, (0x82A, 0x3)), + (0x02469, (0x235, 0x2)), + (0x0FB29, (0x9B6, 0x1)), + (0x1EE01, (0x150A, 0x1)), + (0x0248E, (0x29E, 0x2)), + (0x1D623, (0x12F2, 0x1)), + (0x032D9, (0x65E, 0x1)), + (0x1D531, (0x1207, 0x1)), + (0x03146, (0x451, 0x1)), + (0x1E051, (0x14EC, 0x1)), + (0x1D48C, (0x1172, 0x1)), + (0x0FCF0, (0xC69, 0x2)), + (0x0FB80, (0x9E9, 0x1)), + (0x0FEB1, (0xF4F, 0x1)), + (0x02FD3, (0x42C, 0x1)), + (0x0FD77, (0xD7D, 0x3)), + (0x02482, (0x27A, 0x4)), + (0x03152, (0x45D, 0x1)), + (0x02176, (0x20C, 0x3)), + (0x024B8, (0x315, 0x1)), + (0x0322C, (0x53F, 0x3)), + (0x0FE56, (0xEE1, 0x1)), + (0x03397, (0x87C, 0x2)), + (0x02476, (0x251, 0x3)), + (0x10796, (0x109F, 0x1)), + (0x1D4D0, (0x11AB, 0x1)), + (0x107B3, (0x10BB, 0x1)), + (0x1D779, (0x1446, 0x1)), + (0x0FD7C, (0xD8C, 0x3)), + (0x02F22, (0x37B, 0x1)), + (0x0FC34, (0xADE, 0x2)), + (0x0FCB9, (0xBF9, 0x2)), + (0x1D676, (0x1345, 0x1)), + (0x1D408, (0x10EF, 0x1)), + (0x0FB74, (0x9DD, 0x1)), + (0x0332A, (0x72D, 0x3)), + (0x1D7B3, (0x1480, 0x1)), + (0x03202, (0x4AE, 0x3)), + (0x02230, (0x229, 0x3)), + (0x0FE65, (0xEF0, 0x1)), + (0x032DF, (0x664, 0x1)), + (0x03177, (0x482, 0x1)), + (0x0FD2C, (0xCE4, 0x2)), + (0x0FEED, (0xF8B, 0x1)), + (0x1F12A, (0x15FA, 0x3)), + (0x02F62, (0x3BB, 0x1)), + (0x02FA6, (0x3FF, 0x1)), + (0x0248C, (0x29A, 0x2)), + (0x0FF6B, (0x1013, 0x1)), + (0x0FEF1, (0xF8F, 0x1)), + (0x1D4B5, (0x1193, 0x1)), + (0x1D6E4, (0x13B1, 0x1)), + (0x03312, (0x6CD, 0x4)), + (0x1EE21, (0x1528, 0x1)), + (0x0FD18, (0xCBC, 0x2)), + (0x1D57A, (0x1249, 0x1)), + (0x0216C, (0x1FD, 0x1)), + (0x03131, (0x43C, 0x1)), + (0x03217, (0x4F6, 0x4)), + (0x03386, (0x853, 0x2)), + (0x1D711, (0x13DE, 0x1)), + (0x03200, (0x4A8, 0x3)), + (0x1D62C, (0x12FB, 0x1)), + (0x1D590, (0x125F, 0x1)), + (0x1D53C, (0x1211, 0x1)), + (0x032CB, (0x648, 0x3)), + (0x0FD29, (0xCDE, 0x2)), + (0x1EEA1, (0x157D, 0x1)), + (0x0FE4F, (0xEDB, 0x1)), + (0x0FB54, (0x9BD, 0x1)), + (0x0322A, (0x539, 0x3)), + (0x1F14A, (0x161D, 0x2)), + (0x02136, (0x1A2, 0x1)), + (0x0FF2B, (0xFD3, 0x1)), + (0x0FCFB, (0xC82, 0x2)), + (0x0FDB2, (0xE28, 0x3)), + (0x1EE36, (0x1538, 0x1)), + (0x0FD2E, (0xCE8, 0x2)), + (0x0FF46, (0xFEE, 0x1)), + (0x1CCF8, (0x10E5, 0x1)), + (0x1D60C, (0x12DB, 0x1)), + (0x033AB, (0x8AE, 0x3)), + (0x1D7BC, (0x1489, 0x1)), + (0x1D4C1, (0x119D, 0x1)), + (0x0FDBD, (0xE49, 0x3)), + (0x03331, (0x74C, 0x3)), + (0x1EE34, (0x1536, 0x1)), + (0x1D6CC, (0x1399, 0x1)), + (0x1D44F, (0x1136, 0x1)), + (0x0332E, (0x73F, 0x6)), + (0x0FF6E, (0x1016, 0x1)), + (0x01D78, (0x0C4, 0x1)), + (0x1D780, (0x144D, 0x1)), + (0x1D765, (0x1432, 0x1)), + (0x0FE71, (0xEF8, 0x2)), + (0x02496, (0x2B3, 0x3)), + (0x1D460, (0x1146, 0x1)), + (0x1D756, (0x1423, 0x1)), + (0x0FC5C, (0xB2E, 0x2)), + (0x0337F, (0x843, 0x4)), + (0x0FC2D, (0xAD0, 0x2)), + (0x024AA, (0x2EF, 0x3)), + (0x1D546, (0x1219, 0x1)), + (0x1D624, (0x12F3, 0x1)), + (0x1EEB9, (0x1593, 0x1)), + (0x01D63, (0x0BC, 0x1)), + (0x001CA, (0x032, 0x2)), + (0x03240, (0x57B, 0x3)), + (0x1D4E3, (0x11BE, 0x1)), + (0x1E062, (0x14FD, 0x1)), + (0x03225, (0x52A, 0x3)), + (0x0FE79, (0xF04, 0x2)), + (0x02F20, (0x379, 0x1)), + (0x0FCAD, (0xBE1, 0x2)), + (0x0FC85, (0xB8C, 0x2)), + (0x02FB9, (0x412, 0x1)), + (0x1D7D2, (0x149D, 0x1)), + (0x0332D, (0x73A, 0x5)), + (0x1D4E6, (0x11C1, 0x1)), + (0x024E2, (0x33F, 0x1)), + (0x1EEAF, (0x1589, 0x1)), + (0x032B0, (0x611, 0x1)), + (0x1D575, (0x1244, 0x1)), + (0x0FD6E, (0xD62, 0x3)), + (0x0FD71, (0xD6B, 0x3)), + (0x1D521, (0x11F7, 0x1)), + (0x0FF9D, (0x1045, 0x1)), + (0x1D671, (0x1340, 0x1)), + (0x0247B, (0x260, 0x3)), + (0x1D7D7, (0x14A2, 0x1)), + (0x03174, (0x47F, 0x1)), + (0x1D7A8, (0x1475, 0x1)), + (0x1F16C, (0x162E, 0x2)), + (0x0FB14, (0x9A5, 0x2)), + (0x1D5D3, (0x12A2, 0x1)), + (0x1F123, (0x15E5, 0x3)), + (0x0FBAD, (0xA18, 0x1)), + (0x03308, (0x6A8, 0x4)), + (0x03164, (0x46F, 0x1)), + (0x02033, (0x128, 0x2)), + (0x1D644, (0x1313, 0x1)), + (0x0FCD8, (0xC37, 0x2)), + (0x0FC22, (0xABA, 0x2)), + (0x0215A, (0x1D2, 0x3)), + (0x1D64B, (0x131A, 0x1)), + (0x0FBEF, (0xA46, 0x3)), + (0x01DBF, (0x0E9, 0x1)), + (0x033A6, (0x89F, 0x3)), + (0x0FD74, (0xD74, 0x3)), + (0x1D533, (0x1209, 0x1)), + (0x01DA4, (0x0CE, 0x1)), + (0x1D40A, (0x10F1, 0x1)), + (0x0FEA0, (0xF3E, 0x1)), + (0x01D61, (0x0BA, 0x1)), + (0x1E03A, (0x14D5, 0x1)), + (0x0FCB5, (0xBF1, 0x2)), + (0x1D4D7, (0x11B2, 0x1)), + (0x03145, (0x450, 0x1)), + (0x0FC98, (0xBB3, 0x3)), + (0x1D539, (0x120F, 0x1)), + (0x1EE72, (0x1558, 0x1)), + (0x001F2, (0x03A, 0x2)), + (0x1D51E, (0x11F4, 0x1)), + (0x024A0, (0x2D1, 0x3)), + (0x0FB56, (0x9BF, 0x1)), + (0x024BD, (0x31A, 0x1)), + (0x0FFB7, (0x105F, 0x1)), + (0x1D77D, (0x144A, 0x1)), + (0x0217E, (0x21D, 0x1)), + (0x1D43E, (0x1125, 0x1)), + (0x033D3, (0x90E, 0x2)), + (0x0FE7D, (0xF0C, 0x2)), + (0x000AA, (0x003, 0x1)), + (0x0309B, (0x434, 0x2)), + (0x01D4A, (0x0A4, 0x1)), + (0x1EE52, (0x1544, 0x1)), + (0x032A6, (0x607, 0x1)), + (0x1EE7C, (0x1560, 0x1)), + (0x0332F, (0x745, 0x4)), + (0x01D46, (0x0A0, 0x1)), + (0x1D792, (0x145F, 0x1)), + (0x1D593, (0x1262, 0x1)), + (0x032BB, (0x626, 0x2)), + (0x03343, (0x794, 0x4)), + (0x02FD4, (0x42D, 0x1)), + (0x0FCD2, (0xC2B, 0x2)), + (0x1D66B, (0x133A, 0x1)), + (0x107AE, (0x10B7, 0x1)), + (0x0FC3C, (0xAEE, 0x2)), + (0x1D656, (0x1325, 0x1)), + (0x02464, (0x230, 0x1)), + (0x02105, (0x176, 0x3)), + (0x0FB5C, (0x9C5, 0x1)), + (0x0FE47, (0xECF, 0x1)), + (0x0329A, (0x5FB, 0x1)), + (0x1EE42, (0x153C, 0x1)), + (0x01D3D, (0x097, 0x1)), + (0x033D8, (0x91A, 0x4)), + (0x1D666, (0x1335, 0x1)), + (0x03358, (0x7E2, 0x2)), + (0x0FB6C, (0x9D5, 0x1)), + (0x1D5A8, (0x1277, 0x1)), + (0x02F7E, (0x3D7, 0x1)), + (0x0FF3D, (0xFE5, 0x1)), + (0x033FD, (0x97D, 0x3)), + (0x0FD70, (0xD68, 0x3)), + (0x032A9, (0x60A, 0x1)), + (0x02F2B, (0x384, 0x1)), + (0x1D48B, (0x1171, 0x1)), + (0x02081, (0x150, 0x1)), + (0x0FE9D, (0xF3B, 0x1)), + (0x00F79, (0x084, 0x3)), + (0x0329E, (0x5FF, 0x1)), + (0x0247F, (0x26E, 0x4)), + (0x01D52, (0x0AB, 0x1)), + (0x02F5D, (0x3B6, 0x1)), + (0x02133, (0x19F, 0x1)), + (0x0FEAB, (0xF49, 0x1)), + (0x1D463, (0x1149, 0x1)), + (0x0FBE7, (0xA34, 0x1)), + (0x000BD, (0x012, 0x3)), + (0x0329C, (0x5FD, 0x1)), + (0x01D5E, (0x0B7, 0x1)), + (0x0FC3A, (0xAEA, 0x2)), + (0x002E3, (0x056, 0x1)), + (0x1D675, (0x1344, 0x1)), + (0x03354, (0x7D2, 0x5)), + (0x1D5E3, (0x12B2, 0x1)), + (0x0FE8B, (0xF27, 0x2)), + (0x0FF77, (0x101F, 0x1)), + (0x032B7, (0x61E, 0x2)), + (0x0FD65, (0xD47, 0x3)), + (0x03203, (0x4B1, 0x3)), + (0x1D54B, (0x121B, 0x1)), + (0x024CD, (0x32A, 0x1)), + (0x002DA, (0x04B, 0x2)), + (0x1D62B, (0x12FA, 0x1)), + (0x1EE82, (0x1564, 0x1)), + (0x1E04C, (0x14E7, 0x1)), + (0x0248B, (0x298, 0x2)), + (0x0FB62, (0x9CB, 0x1)), + (0x1F212, (0x1639, 0x1)), + (0x1D7FC, (0x14C7, 0x1)), + (0x0FFA2, (0x104A, 0x1)), + (0x0FC96, (0xBAE, 0x2)), + (0x0FCED, (0xC63, 0x2)), + (0x0FBA9, (0xA14, 0x1)), + (0x1D5A2, (0x1271, 0x1)), + (0x0FF9E, (0x1046, 0x1)), + (0x0FB5A, (0x9C3, 0x1)), + (0x024A4, (0x2DD, 0x3)), + (0x1D4B2, (0x1190, 0x1)), + (0x1EE11, (0x1519, 0x1)), + (0x0FCC8, (0xC17, 0x2)), + (0x03250, (0x58B, 0x3)), + (0x1D421, (0x1108, 0x1)), + (0x1D7E7, (0x14B2, 0x1)), + (0x033F3, (0x95F, 0x3)), + (0x107AC, (0x10B5, 0x1)), + (0x033A9, (0x8A9, 0x2)), + (0x1EE9B, (0x157C, 0x1)), + (0x02F77, (0x3D0, 0x1)), + (0x0FF20, (0xFC8, 0x1)), + (0x02089, (0x158, 0x1)), + (0x0FE5B, (0xEE6, 0x1)), + (0x0FCA3, (0xBCD, 0x2)), + (0x1D6B7, (0x1384, 0x1)), + (0x0FE76, (0xEFE, 0x2)), + (0x0FE59, (0xEE4, 0x1)), + (0x1D6D4, (0x13A1, 0x1)), + (0x02F6B, (0x3C4, 0x1)), + (0x1EE1F, (0x1527, 0x1)), + (0x1D74E, (0x141B, 0x1)), + (0x0FFD4, (0x1075, 0x1)), + (0x001C5, (0x026, 0x3)), + (0x01D2D, (0x089, 0x1)), + (0x02F35, (0x38E, 0x1)), + (0x1F104, (0x159E, 0x2)), + (0x0FBF4, (0xA55, 0x3)), + (0x1D411, (0x10F8, 0x1)), + (0x1D42E, (0x1115, 0x1)), + (0x01FEE, (0x10C, 0x3)), + (0x0FC54, (0xB1E, 0x2)), + (0x1F22F, (0x1657, 0x1)), + (0x1D5E2, (0x12B1, 0x1)), + (0x1D60F, (0x12DE, 0x1)), + (0x0FC6F, (0xB60, 0x2)), + (0x1D476, (0x115C, 0x1)), + (0x033CA, (0x8FB, 0x2)), + (0x02FCE, (0x427, 0x1)), + (0x1D59A, (0x1269, 0x1)), + (0x02175, (0x20A, 0x2)), + (0x1D6D0, (0x139D, 0x1)), + (0x02150, (0x1B3, 0x3)), + (0x1D7AE, (0x147B, 0x1)), + (0x1D6CB, (0x1398, 0x1)), + (0x0FC02, (0xA77, 0x3)), + (0x0FFC5, (0x106A, 0x1)), + (0x1D76A, (0x1437, 0x1)), + (0x0FE69, (0xEF3, 0x1)), + (0x0326C, (0x5B8, 0x1)), + (0x0FE89, (0xF23, 0x2)), + (0x02FBB, (0x414, 0x1)), + (0x1D514, (0x11EC, 0x1)), + (0x03036, (0x430, 0x1)), + (0x0FD97, (0xDD7, 0x3)), + (0x0FC11, (0xA98, 0x2)), + (0x02F44, (0x39D, 0x1)), + (0x0FBD3, (0xA1F, 0x1)), + (0x0FFCD, (0x1070, 0x1)), + (0x0FD88, (0xDB0, 0x3)), + (0x1D507, (0x11E1, 0x1)), + (0x0FF02, (0xFAA, 0x1)), + (0x1EEB3, (0x158D, 0x1)), + (0x1D7D6, (0x14A1, 0x1)), + (0x032BD, (0x62A, 0x2)), + (0x1D603, (0x12D2, 0x1)), + (0x0FC4C, (0xB0E, 0x2)), + (0x0FCC5, (0xC11, 0x2)), + (0x02F8E, (0x3E7, 0x1)), + (0x0FFAD, (0x1055, 0x1)), + (0x0FD68, (0xD50, 0x3)), + (0x1D435, (0x111C, 0x1)), + (0x0FE4E, (0xEDA, 0x1)), + (0x0318D, (0x498, 0x1)), + (0x1D75F, (0x142C, 0x1)), + (0x032C9, (0x642, 0x3)), + (0x0313A, (0x445, 0x1)), + (0x1D7A4, (0x1471, 0x1)), + (0x1F117, (0x15C1, 0x3)), + (0x033C7, (0x8F4, 0x3)), + (0x1D6E5, (0x13B2, 0x1)), + (0x03207, (0x4BD, 0x3)), + (0x1D614, (0x12E3, 0x1)), + (0x1D571, (0x1240, 0x1)), + (0x1D6F7, (0x13C4, 0x1)), + (0x1D52F, (0x1205, 0x1)), + (0x032FE, (0x683, 0x1)), + (0x0FDC6, (0xE64, 0x3)), + (0x1EE29, (0x152C, 0x1)), + (0x1D5EA, (0x12B9, 0x1)), + (0x002DB, (0x04D, 0x2)), + (0x0FCCB, (0xC1D, 0x2)), + (0x02137, (0x1A3, 0x1)), + (0x0FCA6, (0xBD3, 0x2)), + (0x02166, (0x1EE, 0x3)), + (0x033BC, (0x8DA, 0x2)), + (0x0FBD9, (0xA25, 0x1)), + (0x02FA9, (0x402, 0x1)), + (0x03206, (0x4BA, 0x3)), + (0x0FBE2, (0xA2F, 0x1)), + (0x1CCED, (0x10DA, 0x1)), + (0x0FCD4, (0xC2F, 0x2)), + (0x1EEA9, (0x1584, 0x1)), + (0x01D6A, (0x0C3, 0x1)), + (0x1E05E, (0x14F9, 0x1)), + (0x1D64D, (0x131C, 0x1)), + (0x1D504, (0x11DF, 0x1)), + (0x0FBAC, (0xA17, 0x1)), + (0x01D35, (0x090, 0x1)), + (0x0FC25, (0xAC0, 0x2)), + (0x002B5, (0x043, 0x1)), + (0x0FC8F, (0xBA0, 0x2)), + (0x1D79A, (0x1467, 0x1)), + (0x003D4, (0x064, 0x2)), + (0x03392, (0x86F, 0x3)), + (0x02486, (0x28A, 0x4)), + (0x02F1F, (0x378, 0x1)), + (0x03313, (0x6D1, 0x6)), + (0x1D4C7, (0x11A2, 0x1)), + (0x0325E, (0x5A8, 0x2)), + (0x03238, (0x563, 0x3)), + (0x0FD32, (0xCF0, 0x2)), + (0x0FF53, (0xFFB, 0x1)), + (0x0FE66, (0xEF1, 0x1)), + (0x0AB5C, (0x98E, 0x1)), + (0x024D7, (0x334, 0x1)), + (0x10783, (0x108D, 0x1)), + (0x024B2, (0x307, 0x3)), + (0x02487, (0x28E, 0x4)), + (0x0FF6F, (0x1017, 0x1)), + (0x0FC63, (0xB41, 0x3)), + (0x0FD6D, (0xD5F, 0x3)), + (0x02110, (0x185, 0x1)), + (0x0FBA8, (0xA13, 0x1)), + (0x1F251, (0x1680, 0x1)), + (0x0FBED, (0xA40, 0x3)), + (0x033BE, (0x8DE, 0x2)), + (0x0FB05, (0x99F, 0x2)), + (0x0FC99, (0xBB6, 0x3)), + (0x1EE15, (0x151D, 0x1)), + (0x1EE13, (0x151B, 0x1)), + (0x024A1, (0x2D4, 0x3)), + (0x033DE, (0x929, 0x3)), + (0x1D5B9, (0x1288, 0x1)), + (0x1D690, (0x135F, 0x1)), + (0x01D2C, (0x088, 0x1)), + (0x0FB90, (0x9F9, 0x1)), + (0x1D42D, (0x1114, 0x1)), + (0x024C2, (0x31F, 0x1)), + (0x1D4FF, (0x11DA, 0x1)), + (0x01DBC, (0x0E6, 0x1)), + (0x0FCB7, (0xBF5, 0x2)), + (0x0FC67, (0xB4D, 0x3)), + (0x000B3, (0x007, 0x1)), + (0x0FC2F, (0xAD4, 0x2)), + (0x03345, (0x79B, 0x3)), + (0x01FFD, (0x10F, 0x2)), + (0x1D7EC, (0x14B7, 0x1)), + (0x033A7, (0x8A2, 0x3)), + (0x1D51F, (0x11F5, 0x1)), + (0x032CC, (0x64B, 0x2)), + (0x02130, (0x19D, 0x1)), + (0x0FF5F, (0x1007, 0x1)), + (0x02174, (0x209, 0x1)), + (0x0337E, (0x841, 0x2)), + (0x1D523, (0x11F9, 0x1)), + (0x0207C, (0x14B, 0x1)), + (0x033D5, (0x912, 0x3)), + (0x1D65C, (0x132B, 0x1)), + (0x024A9, (0x2EC, 0x3)), + (0x0FD9F, (0xDEF, 0x3)), + (0x1D762, (0x142F, 0x1)), + (0x03154, (0x45F, 0x1)), + (0x0215F, (0x1E1, 0x2)), + (0x0FF4A, (0xFF2, 0x1)), + (0x1D477, (0x115D, 0x1)), + (0x1D400, (0x10E7, 0x1)), + (0x1D525, (0x11FB, 0x1)), + (0x03255, (0x596, 0x2)), + (0x1F111, (0x15AF, 0x3)), + (0x0FF8E, (0x1036, 0x1)), + (0x1D709, (0x13D6, 0x1)), + (0x1E06A, (0x1505, 0x1)), + (0x1D4E9, (0x11C4, 0x1)), + (0x1CCE9, (0x10D6, 0x1)), + (0x003F9, (0x06D, 0x1)), + (0x0FE3A, (0xEC4, 0x1)), + (0x03259, (0x59E, 0x2)), + (0x1D6A5, (0x1374, 0x1)), + (0x02F02, (0x35B, 0x1)), + (0x0FD01, (0xC8E, 0x2)), + (0x0325B, (0x5A2, 0x2)), + (0x02008, (0x11B, 0x1)), + (0x0FD8F, (0xDC5, 0x3)), + (0x1D7DC, (0x14A7, 0x1)), + (0x1D447, (0x112E, 0x1)), + (0x02086, (0x155, 0x1)), + (0x1D492, (0x1178, 0x1)), + (0x1D70B, (0x13D8, 0x1)), + (0x1D5FC, (0x12CB, 0x1)), + (0x0FE81, (0xF13, 0x2)), + (0x0FB86, (0x9EF, 0x1)), + (0x0FD30, (0xCEC, 0x2)), + (0x02F3A, (0x393, 0x1)), + (0x1D5BB, (0x128A, 0x1)), + (0x0FC9D, (0xBC1, 0x2)), + (0x0FC3E, (0xAF2, 0x2)), + (0x0FE7B, (0xF08, 0x2)), + (0x0FFAF, (0x1057, 0x1)), + (0x0FF57, (0xFFF, 0x1)), + (0x0FBFE, (0xA6F, 0x1)), + (0x1D59F, (0x126E, 0x1)), + (0x1D646, (0x1315, 0x1)), + (0x0FBF0, (0xA49, 0x3)), + (0x0315A, (0x465, 0x1)), + (0x0FEA6, (0xF44, 0x1)), + (0x0FCE6, (0xC55, 0x2)), + (0x1D554, (0x1223, 0x1)), + (0x1D791, (0x145E, 0x1)), + (0x02F1D, (0x376, 0x1)), + (0x03363, (0x7F9, 0x3)), + (0x0FC60, (0xB38, 0x3)), + (0x03268, (0x5B4, 0x1)), + (0x1D695, (0x1364, 0x1)), + (0x0FF29, (0xFD1, 0x1)), + (0x0FE57, (0xEE2, 0x1)), + (0x02F47, (0x3A0, 0x1)), + (0x0210F, (0x184, 0x1)), + (0x01D55, (0x0AE, 0x1)), + (0x1D4EF, (0x11CA, 0x1)), + (0x033B2, (0x8C6, 0x2)), + (0x024D2, (0x32F, 0x1)), + (0x1E049, (0x14E4, 0x1)), + (0x02F32, (0x38B, 0x1)), + (0x1CCF4, (0x10E1, 0x1)), + (0x1EE85, (0x1567, 0x1)), + (0x02F4D, (0x3A6, 0x1)), + (0x0FF84, (0x102C, 0x1)), + (0x1F114, (0x15B8, 0x3)), + (0x0FD7F, (0xD95, 0x3)), + (0x0314D, (0x458, 0x1)), + (0x01D62, (0x0BB, 0x1)), + (0x1D697, (0x1366, 0x1)), + (0x1F102, (0x159A, 0x2)), + (0x0333F, (0x787, 0x2)), + (0x02138, (0x1A4, 0x1)), + (0x1D54A, (0x121A, 0x1)), + (0x0FB7F, (0x9E8, 0x1)), + (0x0FB06, (0x9A1, 0x2)), + (0x0FD24, (0xCD4, 0x2)), + (0x1D66A, (0x1339, 0x1)), + (0x0FC53, (0xB1C, 0x2)), + (0x1D45E, (0x1144, 0x1)), + (0x1D76E, (0x143B, 0x1)), + (0x03378, (0x833, 0x3)), + (0x1D61F, (0x12EE, 0x1)), + (0x1D7A6, (0x1473, 0x1)), + (0x1D7C7, (0x1494, 0x1)), + (0x0FF2F, (0xFD7, 0x1)), + (0x0FC1D, (0xAB0, 0x2)), + (0x1D65B, (0x132A, 0x1)), + (0x0213B, (0x1A6, 0x3)), + (0x1D6BA, (0x1387, 0x1)), + (0x0333C, (0x77A, 0x4)), + (0x002B4, (0x042, 0x1)), + (0x0FD26, (0xCD8, 0x2)), + (0x0FF25, (0xFCD, 0x1)), + (0x0217A, (0x216, 0x2)), + (0x0FC13, (0xA9C, 0x2)), + (0x1D54E, (0x121E, 0x1)), + (0x00678, (0x076, 0x2)), + (0x1D7E8, (0x14B3, 0x1)), + (0x1D6D1, (0x139E, 0x1)), + (0x03274, (0x5C6, 0x2)), + (0x032E3, (0x668, 0x1)), + (0x1D6FF, (0x13CC, 0x1)), + (0x1D58A, (0x1259, 0x1)), + (0x0FDBB, (0xE43, 0x3)), + (0x1E04F, (0x14EA, 0x1)), + (0x0FD09, (0xC9E, 0x2)), + (0x024DD, (0x33A, 0x1)), + (0x0FCE4, (0xC51, 0x2)), + (0x1D47C, (0x1162, 0x1)), + (0x0AB5F, (0x991, 0x1)), + (0x0FF98, (0x1040, 0x1)), + (0x0FBF7, (0xA5E, 0x3)), + (0x03187, (0x492, 0x1)), + (0x0FF37, (0xFDF, 0x1)), + (0x02FA1, (0x3FA, 0x1)), + (0x0FB9E, (0xA07, 0x1)), + (0x03237, (0x560, 0x3)), + (0x0FCE7, (0xC57, 0x2)), + (0x1CCDC, (0x10C9, 0x1)), + (0x1D755, (0x1422, 0x1)), + (0x02011, (0x11E, 0x1)), + (0x1EEB7, (0x1591, 0x1)), + (0x0FC46, (0xB02, 0x2)), + (0x033DB, (0x923, 0x2)), + (0x0334B, (0x7B2, 0x3)), + (0x0339A, (0x882, 0x2)), + (0x0FE83, (0xF17, 0x2)), + (0x0FEC8, (0xF66, 0x1)), + (0x0FFDA, (0x1079, 0x1)), + (0x01D38, (0x093, 0x1)), + (0x0FBE8, (0xA35, 0x1)), + (0x1D55C, (0x122B, 0x1)), + (0x024A2, (0x2D7, 0x3)), + (0x1F131, (0x1604, 0x1)), + (0x0FFE2, (0x107E, 0x1)), + (0x0303A, (0x433, 0x1)), + (0x0FD35, (0xCF6, 0x2)), + (0x03301, (0x68B, 0x4)), + (0x1FBF0, (0x1681, 0x1)), + (0x002DC, (0x04F, 0x2)), + (0x0FE85, (0xF1B, 0x2)), + (0x01D3A, (0x095, 0x1)), + (0x0FC17, (0xAA4, 0x2)), + (0x1FBF7, (0x1688, 0x1)), + (0x0FB66, (0x9CF, 0x1)), + (0x1EEA3, (0x157F, 0x1)), + (0x0FD04, (0xC94, 0x2)), + (0x0323E, (0x575, 0x3)), + (0x0328D, (0x5EE, 0x1)), + (0x1D7BD, (0x148A, 0x1)), + (0x1D6C0, (0x138D, 0x1)), + (0x03328, (0x728, 0x2)), + (0x1D602, (0x12D1, 0x1)), + (0x1D607, (0x12D6, 0x1)), + (0x1F125, (0x15EB, 0x3)), + (0x02468, (0x234, 0x1)), + (0x0FE11, (0xEAE, 0x1)), + (0x02098, (0x166, 0x1)), + (0x0FD98, (0xDDA, 0x3)), + (0x0FC6E, (0xB5E, 0x2)), + (0x1CCF1, (0x10DE, 0x1)), + (0x03310, (0x6C5, 0x4)), + (0x1D530, (0x1206, 0x1)), + (0x02179, (0x215, 0x1)), + (0x00F77, (0x081, 0x3)), + (0x1D7B7, (0x1484, 0x1)), + (0x033EB, (0x947, 0x3)), + (0x0326D, (0x5B9, 0x1)), + (0x03372, (0x826, 0x2)), + (0x0FBD4, (0xA20, 0x1)), + (0x1D550, (0x1220, 0x1)), + (0x03144, (0x44F, 0x1)), + (0x002B8, (0x046, 0x1)), + (0x1D725, (0x13F2, 0x1)), + (0x1EE32, (0x1535, 0x1)), + (0x02131, (0x19E, 0x1)), + (0x033C5, (0x8EE, 0x2)), + (0x1CCE5, (0x10D2, 0x1)), + (0x0FE51, (0xEDD, 0x1)), + (0x0334E, (0x7BE, 0x4)), + (0x10785, (0x108F, 0x1)), + (0x1D427, (0x110E, 0x1)), + (0x1D6F4, (0x13C1, 0x1)), + (0x02075, (0x144, 0x1)), + (0x1D660, (0x132F, 0x1)), + (0x0FF5E, (0x1006, 0x1)), + (0x0FC0B, (0xA8C, 0x2)), + (0x0FD37, (0xCFA, 0x2)), + (0x02F03, (0x35C, 0x1)), + (0x024B7, (0x314, 0x1)), + (0x02F43, (0x39C, 0x1)), + (0x0FD1D, (0xCC6, 0x2)), + (0x03142, (0x44D, 0x1)), + (0x0247D, (0x266, 0x4)), + (0x0FF3E, (0xFE6, 0x1)), + (0x1D776, (0x1443, 0x1)), + (0x01D9F, (0x0C9, 0x1)), + (0x1EE16, (0x151E, 0x1)), + (0x1D6BD, (0x138A, 0x1)), + (0x02F46, (0x39F, 0x1)), + (0x0FF7A, (0x1022, 0x1)), + (0x0FEBC, (0xF5A, 0x1)), + (0x0FF59, (0x1001, 0x1)), + (0x1D665, (0x1334, 0x1)), + (0x1F12C, (0x15FE, 0x1)), + (0x02F59, (0x3B2, 0x1)), + (0x1D7B9, (0x1486, 0x1)), + (0x0321B, (0x506, 0x4)), + (0x0FFD2, (0x1073, 0x1)), + (0x02F2A, (0x383, 0x1)), + (0x002E1, (0x054, 0x1)), + (0x0FC68, (0xB50, 0x3)), + (0x1F128, (0x15F4, 0x3)), + (0x02003, (0x116, 0x1)), + (0x0FEC4, (0xF62, 0x1)), + (0x0FD75, (0xD77, 0x3)), + (0x02F12, (0x36B, 0x1)), + (0x1D6B9, (0x1386, 0x1)), + (0x0FD17, (0xCBA, 0x2)), + (0x0FDB1, (0xE25, 0x3)), + (0x0330D, (0x6B9, 0x4)), + (0x02F9D, (0x3F6, 0x1)), + (0x0FF43, (0xFEB, 0x1)), + (0x032B4, (0x618, 0x2)), + (0x1D72D, (0x13FA, 0x1)), + (0x1D669, (0x1338, 0x1)), + (0x0FE87, (0xF1F, 0x2)), + (0x1EE92, (0x1573, 0x1)), + (0x000A0, (0x000, 0x1)), + (0x1F140, (0x1613, 0x1)), + (0x1D685, (0x1354, 0x1)), + (0x02087, (0x156, 0x1)), + (0x1D6E9, (0x13B6, 0x1)), + (0x1D75D, (0x142A, 0x1)), + (0x02F40, (0x399, 0x1)), + (0x0FD5B, (0xD29, 0x3)), + (0x0FCBC, (0xBFF, 0x2)), + (0x02097, (0x165, 0x1)), + (0x033F6, (0x968, 0x3)), + (0x1D794, (0x1461, 0x1)), + (0x1D44D, (0x1134, 0x1)), + (0x1D6EF, (0x13BC, 0x1)), + (0x0FE70, (0xEF6, 0x2)), + (0x0FCFE, (0xC88, 0x2)), + (0x1D448, (0x112F, 0x1)), + (0x0FC92, (0xBA6, 0x2)), + (0x1D40B, (0x10F2, 0x1)), + (0x02161, (0x1E4, 0x2)), + (0x02047, (0x136, 0x2)), + (0x1D7F6, (0x14C1, 0x1)), + (0x1D691, (0x1360, 0x1)), + (0x1F11E, (0x15D6, 0x3)), + (0x0FD55, (0xD17, 0x3)), + (0x0FEE4, (0xF82, 0x1)), + (0x1D69A, (0x1369, 0x1)), + (0x032D2, (0x657, 0x1)), + (0x0FFEC, (0x1088, 0x1)), + (0x0FF1B, (0xFC3, 0x1)), + (0x03266, (0x5B2, 0x1)), + (0x1E056, (0x14F1, 0x1)), + (0x0FE10, (0xEAD, 0x1)), + (0x03388, (0x857, 0x3)), + (0x1EE97, (0x1578, 0x1)), + (0x03173, (0x47E, 0x1)), + (0x1D583, (0x1252, 0x1)), + (0x1FBF9, (0x168A, 0x1)), + (0x0FE4D, (0xED9, 0x1)), + (0x024DE, (0x33B, 0x1)), + (0x1D543, (0x1217, 0x1)), + (0x1D57D, (0x124C, 0x1)), + (0x0FF7F, (0x1027, 0x1)), + (0x1F240, (0x1664, 0x3)), + (0x1D534, (0x120A, 0x1)), + (0x0FD23, (0xCD2, 0x2)), + (0x0FF45, (0xFED, 0x1)), + (0x033AD, (0x8B4, 0x3)), + (0x1D618, (0x12E7, 0x1)), + (0x0FC6D, (0xB5C, 0x2)), + (0x000A8, (0x001, 0x2)), + (0x0FB77, (0x9E0, 0x1)), + (0x0FEFA, (0xFA2, 0x3)), + (0x1EE5D, (0x1549, 0x1)), + (0x032EA, (0x66F, 0x1)), + (0x02F23, (0x37C, 0x1)), + (0x01DAB, (0x0D5, 0x1)), + (0x00EDC, (0x07C, 0x2)), + (0x0FE97, (0xF35, 0x1)), + (0x0FCB4, (0xBEF, 0x2)), + (0x02FA5, (0x3FE, 0x1)), + (0x1D438, (0x111F, 0x1)), + (0x03195, (0x49D, 0x1)), + (0x1D727, (0x13F4, 0x1)), + (0x1D662, (0x1331, 0x1)), + (0x1D70E, (0x13DB, 0x1)), + (0x1D417, (0x10FE, 0x1)), + (0x1D436, (0x111D, 0x1)), + (0x0FC1A, (0xAAA, 0x2)), + (0x1D7DB, (0x14A6, 0x1)), + (0x1D6FB, (0x13C8, 0x1)), + (0x0FEF6, (0xF96, 0x3)), + (0x03193, (0x49B, 0x1)), + (0x10787, (0x1090, 0x1)), + (0x1E053, (0x14EE, 0x1)), + (0x1D651, (0x1320, 0x1)), + (0x1E046, (0x14E1, 0x1)), + (0x0FE3F, (0xEC9, 0x1)), + (0x0FF49, (0xFF1, 0x1)), + (0x02026, (0x124, 0x3)), + (0x033E7, (0x93D, 0x2)), + (0x0211C, (0x18F, 0x1)), + (0x02F58, (0x3B1, 0x1)), + (0x1D5FF, (0x12CE, 0x1)), + (0x0FE9B, (0xF39, 0x1)), + (0x0FD2F, (0xCEA, 0x2)), + (0x0FF09, (0xFB1, 0x1)), + (0x1D61A, (0x12E9, 0x1)), + (0x1D7AB, (0x1478, 0x1)), + (0x1D5A4, (0x1273, 0x1)), + (0x0328B, (0x5EC, 0x1)), + (0x1D4C3, (0x119F, 0x1)), + (0x1CCE6, (0x10D3, 0x1)), + (0x0FF0E, (0xFB6, 0x1)), + (0x00677, (0x074, 0x2)), + (0x02F00, (0x359, 0x1)), + (0x0248D, (0x29C, 0x2)), + (0x0FD27, (0xCDA, 0x2)), + (0x01DB6, (0x0E0, 0x1)), + (0x0326A, (0x5B6, 0x1)), + (0x1D566, (0x1235, 0x1)), + (0x024C7, (0x324, 0x1)), + (0x032FF, (0x684, 0x2)), + (0x10797, (0x10A0, 0x1)), + (0x024A5, (0x2E0, 0x3)), + (0x0FE30, (0xEB9, 0x2)), + (0x1D437, (0x111E, 0x1)), + (0x0FF0F, (0xFB7, 0x1)), + (0x0FC58, (0xB26, 0x2)), + (0x1D7A7, (0x1474, 0x1)), + (0x0215C, (0x1D8, 0x3)), + (0x0FDA3, (0xDFB, 0x3)), + (0x1D516, (0x11ED, 0x1)), + (0x02F8A, (0x3E3, 0x1)), + (0x0FD0F, (0xCAA, 0x2)), + (0x1D403, (0x10EA, 0x1)), + (0x1D413, (0x10FA, 0x1)), + (0x03262, (0x5AE, 0x1)), + (0x1EE0A, (0x1512, 0x1)), + (0x0FFB1, (0x1059, 0x1)), + (0x1F22B, (0x1653, 0x1)), + (0x1D703, (0x13D0, 0x1)), + (0x02F6E, (0x3C7, 0x1)), + (0x024EA, (0x347, 0x1)), + (0x1D73D, (0x140A, 0x1)), + (0x0FCDA, (0xC3B, 0x2)), + (0x02F49, (0x3A2, 0x1)), + (0x03148, (0x453, 0x1)), + (0x0FC0D, (0xA90, 0x2)), + (0x02F93, (0x3EC, 0x1)), + (0x033AA, (0x8AB, 0x3)), + (0x02F27, (0x380, 0x1)), + (0x032E8, (0x66D, 0x1)), + (0x1FBF8, (0x1689, 0x1)), + (0x1F101, (0x1598, 0x2)), + (0x1D462, (0x1148, 0x1)), + (0x1D749, (0x1416, 0x1)), + (0x1D7A9, (0x1476, 0x1)), + (0x1D57F, (0x124E, 0x1)), + (0x03132, (0x43D, 0x1)), + (0x0FF6C, (0x1014, 0x1)), + (0x0FD9C, (0xDE6, 0x3)), + (0x03192, (0x49A, 0x1)), + (0x02FC2, (0x41B, 0x1)), + (0x1D799, (0x1466, 0x1)), + (0x0213C, (0x1A9, 0x1)), + (0x1E06D, (0x1508, 0x1)), + (0x1D4E7, (0x11C2, 0x1)), + (0x0FB15, (0x9A7, 0x2)), + (0x02FBC, (0x415, 0x1)), + (0x024E0, (0x33D, 0x1)), + (0x03209, (0x4C3, 0x3)), + (0x033EA, (0x944, 0x3)), + (0x0FC6C, (0xB5A, 0x2)), + (0x02FAC, (0x405, 0x1)), + (0x1F202, (0x1636, 0x1)), + (0x0FBF3, (0xA52, 0x3)), + (0x0327B, (0x5D4, 0x2)), + (0x02F38, (0x391, 0x1)), + (0x02F2E, (0x387, 0x1)), + (0x00F0C, (0x080, 0x1)), + (0x0FDAB, (0xE13, 0x3)), + (0x1EE64, (0x154D, 0x1)), + (0x0FC3B, (0xAEC, 0x2)), + (0x1EE6E, (0x1554, 0x1)), + (0x1D63E, (0x130D, 0x1)), + (0x1D47D, (0x1163, 0x1)), + (0x0FF28, (0xFD0, 0x1)), + (0x0FCF4, (0xC73, 0x3)), + (0x0FC9E, (0xBC3, 0x2)), + (0x1D7AC, (0x1479, 0x1)), + (0x1D7FD, (0x14C8, 0x1)), + (0x0FB01, (0x995, 0x2)), + (0x0FDAE, (0xE1C, 0x3)), + (0x0316B, (0x476, 0x1)), + (0x1D63C, (0x130B, 0x1)), + (0x0FDB7, (0xE37, 0x3)), + (0x1D66D, (0x133C, 0x1)), + (0x03334, (0x759, 0x6)), + (0x0FC6A, (0xB56, 0x2)), + (0x1EE62, (0x154C, 0x1)), + (0x0338D, (0x864, 0x2)), + (0x033AC, (0x8B1, 0x3)), + (0x0330E, (0x6BD, 0x4)), + (0x0FE82, (0xF15, 0x2)), + (0x03333, (0x755, 0x4)), + (0x0246C, (0x23B, 0x2)), + (0x1D73A, (0x1407, 0x1)), + (0x0FC87, (0xB90, 0x2)), + (0x1E066, (0x1501, 0x1)), + (0x0FD00, (0xC8C, 0x2)), + (0x03291, (0x5F2, 0x1)), + (0x1D732, (0x13FF, 0x1)), + (0x0216B, (0x1FA, 0x3)), + (0x02FB6, (0x40F, 0x1)), + (0x024E7, (0x344, 0x1)), + (0x02FC0, (0x419, 0x1)), + (0x033F9, (0x971, 0x3)), + (0x0FC9F, (0xBC5, 0x2)), + (0x03188, (0x493, 0x1)), + (0x0FD79, (0xD83, 0x3)), + (0x03229, (0x536, 0x3)), + (0x1D4C5, (0x11A0, 0x1)), + (0x024B5, (0x310, 0x3)), + (0x1D591, (0x1260, 0x1)), + (0x03163, (0x46E, 0x1)), + (0x033DD, (0x927, 0x2)), + (0x032C3, (0x636, 0x2)), + (0x01DA9, (0x0D3, 0x1)), + (0x0FC4B, (0xB0C, 0x2)), + (0x0FBE9, (0xA36, 0x1)), + (0x1D71F, (0x13EC, 0x1)), + (0x0334C, (0x7B5, 0x5)), + (0x10793, (0x109C, 0x1)), + (0x02F56, (0x3AF, 0x1)), + (0x1D4D1, (0x11AC, 0x1)), + (0x0FB53, (0x9BC, 0x1)), + (0x00EB3, (0x07A, 0x2)), + (0x02F11, (0x36A, 0x1)), + (0x0FB89, (0x9F2, 0x1)), + (0x03201, (0x4AB, 0x3)), + (0x0FD82, (0xD9E, 0x3)), + (0x1D503, (0x11DE, 0x1)), + (0x0FEC5, (0xF63, 0x1)), + (0x1D486, (0x116C, 0x1)), + (0x1D753, (0x1420, 0x1)), + (0x0FF3F, (0xFE7, 0x1)), + (0x03349, (0x7AA, 0x2)), + (0x1D5F7, (0x12C6, 0x1)), + (0x1D599, (0x1268, 0x1)), + (0x1D558, (0x1227, 0x1)), + (0x1D5B8, (0x1287, 0x1)), + (0x02F07, (0x360, 0x1)), + (0x03381, (0x849, 0x2)), + (0x0FC47, (0xB04, 0x2)), + (0x0330C, (0x6B5, 0x4)), + (0x02169, (0x1F7, 0x1)), + (0x03285, (0x5E6, 0x1)), + (0x1D612, (0x12E1, 0x1)), + (0x0FB55, (0x9BE, 0x1)), + (0x1D68B, (0x135A, 0x1)), + (0x1D798, (0x1465, 0x1)), + (0x033F0, (0x956, 0x3)), + (0x0FEBA, (0xF58, 0x1)), + (0x1D4B1, (0x118F, 0x1)), + (0x0FF99, (0x1041, 0x1)), + (0x02159, (0x1CF, 0x3)), + (0x0FF39, (0xFE1, 0x1)), + (0x1D5F0, (0x12BF, 0x1)), + (0x1D480, (0x1166, 0x1)), + (0x0FEEB, (0xF89, 0x1)), + (0x1EE8E, (0x156F, 0x1)), + (0x02128, (0x199, 0x1)), + (0x1E036, (0x14D1, 0x1)), + (0x0FEFB, (0xFA5, 0x2)), + (0x1D6DB, (0x13A8, 0x1)), + (0x1D6EA, (0x13B7, 0x1)), + (0x0FEC6, (0xF64, 0x1)), + (0x1EE6C, (0x1552, 0x1)), + (0x024C1, (0x31E, 0x1)), + (0x1D6B3, (0x1380, 0x1)), + (0x1D713, (0x13E0, 0x1)), + (0x0FE8C, (0xF29, 0x2)), + (0x0FCC2, (0xC0B, 0x2)), + (0x024E5, (0x342, 0x1)), + (0x0FCC7, (0xC15, 0x2)), + (0x00133, (0x01A, 0x2)), + (0x1D640, (0x130F, 0x1)), + (0x0FFCB, (0x106E, 0x1)), + (0x0FDAD, (0xE19, 0x3)), + (0x1D57E, (0x124D, 0x1)), + (0x1D757, (0x1424, 0x1)), + (0x032D3, (0x658, 0x1)), + (0x02F76, (0x3CF, 0x1)), + (0x02465, (0x231, 0x1)), + (0x1EE1C, (0x1524, 0x1)), + (0x032D5, (0x65A, 0x1)), + (0x0FD73, (0xD71, 0x3)), + (0x0FBB0, (0xA1B, 0x2)), + (0x02F66, (0x3BF, 0x1)), + (0x1D5F6, (0x12C5, 0x1)), + (0x0FEBB, (0xF59, 0x1)), + (0x002B1, (0x03F, 0x1)), + (0x1EE2E, (0x1531, 0x1)), + (0x02071, (0x142, 0x1)), + (0x0FDFB, (0xEA1, 0x8)), + (0x0FC81, (0xB84, 0x2)), + (0x0FEEF, (0xF8D, 0x1)), + (0x02173, (0x207, 0x2)), + (0x1EEA6, (0x1581, 0x1)), + (0x02478, (0x257, 0x3)), + (0x1D6F8, (0x13C5, 0x1)), + (0x1EEAD, (0x1587, 0x1)), + (0x1D5BC, (0x128B, 0x1)), + (0x1D6AE, (0x137B, 0x1)), + (0x0FEDF, (0xF7D, 0x1)), + (0x1D5BE, (0x128D, 0x1)), + (0x1D672, (0x1341, 0x1)), + (0x0FD25, (0xCD6, 0x2)), + (0x01DBA, (0x0E4, 0x1)), + (0x02463, (0x22F, 0x1)), + (0x0FCE2, (0xC4D, 0x2)), + (0x0215B, (0x1D5, 0x3)), + (0x1D7F9, (0x14C4, 0x1)), + (0x032D7, (0x65C, 0x1)), + (0x1D4AF, (0x118D, 0x1)), + (0x02F91, (0x3EA, 0x1)), + (0x0246B, (0x239, 0x2)), + (0x107AD, (0x10B6, 0x1)), + (0x003D1, (0x060, 0x1)), + (0x0FFCC, (0x106F, 0x1)), + (0x0FD9E, (0xDEC, 0x3)), + (0x02115, (0x189, 0x1)), + (0x1D715, (0x13E2, 0x1)), + (0x1D5DB, (0x12AA, 0x1)), + (0x1D774, (0x1441, 0x1)), + (0x0FC61, (0xB3B, 0x3)), + (0x1D401, (0x10E8, 0x1)), + (0x03309, (0x6AC, 0x3)), + (0x1EE68, (0x154F, 0x1)), + (0x1EE49, (0x153E, 0x1)), + (0x02119, (0x18C, 0x1)), + (0x0FB82, (0x9EB, 0x1)), + (0x1D642, (0x1311, 0x1)), + (0x0FC97, (0xBB0, 0x3)), + (0x107B7, (0x10BF, 0x1)), + (0x0FB9A, (0xA03, 0x1)), + (0x0FFC6, (0x106B, 0x1)), + (0x03265, (0x5B1, 0x1)), + (0x0333A, (0x771, 0x4)), + (0x1D61D, (0x12EC, 0x1)), + (0x02F53, (0x3AC, 0x1)), + (0x02082, (0x151, 0x1)), + (0x1D734, (0x1401, 0x1)), + (0x02106, (0x179, 0x3)), + (0x10792, (0x109B, 0x1)), + (0x1D61B, (0x12EA, 0x1)), + (0x1D513, (0x11EB, 0x1)), + (0x0FFA1, (0x1049, 0x1)), + (0x0FE12, (0xEAF, 0x1)), + (0x0FDA2, (0xDF8, 0x3)), + (0x0FC91, (0xBA4, 0x2)), + (0x01FED, (0x109, 0x3)), + (0x1D5DF, (0x12AE, 0x1)), + (0x032F8, (0x67D, 0x1)), + (0x02FB2, (0x40B, 0x1)), + (0x032C4, (0x638, 0x2)), + (0x03158, (0x463, 0x1)), + (0x1D6D3, (0x13A0, 0x1)), + (0x0FB84, (0x9ED, 0x1)), + (0x024CA, (0x327, 0x1)), + (0x03208, (0x4C0, 0x3)), + (0x032FC, (0x681, 0x1)), + (0x0FE94, (0xF32, 0x1)), + (0x02157, (0x1C9, 0x3)), + (0x03357, (0x7DF, 0x3)), + (0x0320A, (0x4C6, 0x3)), + (0x024DA, (0x337, 0x1)), + (0x0FDC2, (0xE58, 0x3)), + (0x1D617, (0x12E6, 0x1)), + (0x1D5E1, (0x12B0, 0x1)), + (0x1D570, (0x123F, 0x1)), + (0x0327E, (0x5DF, 0x2)), + (0x01FDD, (0x100, 0x3)), + (0x0FD5D, (0xD2F, 0x3)), + (0x02F83, (0x3DC, 0x1)), + (0x0FFE4, (0x1081, 0x1)), + (0x0FD87, (0xDAD, 0x3)), + (0x024D1, (0x32E, 0x1)), + (0x00384, (0x05A, 0x2)), + (0x024D6, (0x333, 0x1)), + (0x1EE47, (0x153D, 0x1)), + (0x003D3, (0x062, 0x2)), + (0x032F7, (0x67C, 0x1)), + (0x1D609, (0x12D8, 0x1)), + (0x024AC, (0x2F5, 0x3)), + (0x02F39, (0x392, 0x1)), + (0x0FBD7, (0xA23, 0x1)), + (0x0FB6F, (0x9D8, 0x1)), + (0x0FD13, (0xCB2, 0x2)), + (0x0320F, (0x4D6, 0x4)), + (0x0FCEE, (0xC65, 0x2)), + (0x1D52D, (0x1203, 0x1)), + (0x1D62E, (0x12FD, 0x1)), + (0x02FAD, (0x406, 0x1)), + (0x1D414, (0x10FB, 0x1)), + (0x0FE84, (0xF19, 0x2)), + (0x1D76D, (0x143A, 0x1)), + (0x1F223, (0x164B, 0x1)), + (0x02F87, (0x3E0, 0x1)), + (0x02FD2, (0x42B, 0x1)), + (0x0FF95, (0x103D, 0x1)), + (0x1EE02, (0x150B, 0x1)), + (0x02471, (0x245, 0x2)), + (0x1D714, (0x13E1, 0x1)), + (0x1D718, (0x13E5, 0x1)), + (0x0FFCE, (0x1071, 0x1)), + (0x002B0, (0x03E, 0x1)), + (0x1EE57, (0x1546, 0x1)), + (0x01DB1, (0x0DB, 0x1)), + (0x0FBE3, (0xA30, 0x1)), + (0x1E058, (0x14F3, 0x1)), + (0x03153, (0x45E, 0x1)), + (0x0FF52, (0xFFA, 0x1)), + (0x03243, (0x584, 0x3)), + (0x03226, (0x52D, 0x3)), + (0x0FB6A, (0x9D3, 0x1)), + (0x1EE74, (0x1559, 0x1)), + (0x032DC, (0x661, 0x1)), + (0x0FC03, (0xA7A, 0x3)), + (0x01E9B, (0x0EC, 0x2)), + (0x0FDA7, (0xE07, 0x3)), + (0x0FD15, (0xCB6, 0x2)), + (0x0FC01, (0xA74, 0x3)), + (0x0FC7C, (0xB7A, 0x2)), + (0x03341, (0x78E, 0x3)), + (0x03324, (0x71C, 0x4)), + (0x02FA8, (0x401, 0x1)), + (0x02F3E, (0x397, 0x1)), + (0x0FF9C, (0x1044, 0x1)), + (0x0FB20, (0x9AD, 0x1)), + (0x02F0D, (0x366, 0x1)), + (0x1D5EB, (0x12BA, 0x1)), + (0x1D59C, (0x126B, 0x1)), + (0x0017F, (0x022, 0x1)), + (0x1D79E, (0x146B, 0x1)), + (0x1EE14, (0x151C, 0x1)), + (0x0FD8C, (0xDBC, 0x3)), + (0x0FCBD, (0xC01, 0x2)), + (0x1F221, (0x1649, 0x1)), + (0x02049, (0x13A, 0x2)), + (0x1D4D9, (0x11B4, 0x1)), + (0x0FDAA, (0xE10, 0x3)), + (0x0320E, (0x4D2, 0x4)), + (0x1EE39, (0x153A, 0x1)), + (0x1D72A, (0x13F7, 0x1)), + (0x032AF, (0x610, 0x1)), + (0x0FB8E, (0x9F7, 0x1)), + (0x02077, (0x146, 0x1)), + (0x1D4A6, (0x1187, 0x1)), + (0x02F70, (0x3C9, 0x1)), + (0x03368, (0x808, 0x3)), + (0x0FB6D, (0x9D6, 0x1)), + (0x02F5C, (0x3B5, 0x1)), + (0x03134, (0x43F, 0x1)), + (0x024B6, (0x313, 0x1)), + (0x1D630, (0x12FF, 0x1)), + (0x033CC, (0x8FF, 0x2)), + (0x0FB92, (0x9FB, 0x1)), + (0x024D4, (0x331, 0x1)), + (0x1D46A, (0x1150, 0x1)), + (0x0FF30, (0xFD8, 0x1)), + (0x0FC08, (0xA86, 0x2)), + (0x0FFB2, (0x105A, 0x1)), + (0x033FF, (0x983, 0x3)), + (0x0217B, (0x218, 0x3)), + (0x0FEDE, (0xF7C, 0x1)), + (0x02004, (0x117, 0x1)), + (0x0FCD1, (0xC29, 0x2)), + (0x0207D, (0x14C, 0x1)), + (0x0FB94, (0x9FD, 0x1)), + (0x02078, (0x147, 0x1)), + (0x1D4DE, (0x11B9, 0x1)), + (0x0FC06, (0xA82, 0x2)), + (0x1D5AB, (0x127A, 0x1)), + (0x1D6EB, (0x13B8, 0x1)), + (0x0FF79, (0x1021, 0x1)), + (0x1D705, (0x13D2, 0x1)), + (0x02462, (0x22E, 0x1)), + (0x0FCA1, (0xBC9, 0x2)), + (0x0FC28, (0xAC6, 0x2)), + (0x1D77E, (0x144B, 0x1)), + (0x0FEE6, (0xF84, 0x1)), + (0x1F127, (0x15F1, 0x3)), + (0x1D580, (0x124F, 0x1)), + (0x1EE4F, (0x1542, 0x1)), + (0x1D619, (0x12E8, 0x1)), + (0x0323B, (0x56C, 0x3)), + (0x001C8, (0x02E, 0x2)), + (0x1F21C, (0x1644, 0x1)), + (0x1FBF2, (0x1683, 0x1)), + (0x0FB26, (0x9B3, 0x1)), + (0x1E03B, (0x14D6, 0x1)), + (0x0FDB8, (0xE3A, 0x3)), + (0x1D54F, (0x121F, 0x1)), + (0x1D564, (0x1233, 0x1)), + (0x1D7EB, (0x14B6, 0x1)), + (0x1E050, (0x14EB, 0x1)), + (0x1D5D8, (0x12A7, 0x1)), + (0x1D4F0, (0x11CB, 0x1)), + (0x0FFD3, (0x1074, 0x1)), + (0x032DE, (0x663, 0x1)), + (0x1D574, (0x1243, 0x1)), + (0x002E4, (0x057, 0x1)), + (0x1D59E, (0x126D, 0x1)), + (0x0FF74, (0x101C, 0x1)), + (0x0215E, (0x1DE, 0x3)), + (0x0FD34, (0xCF4, 0x2)), + (0x0FF2A, (0xFD2, 0x1)), + (0x0FF15, (0xFBD, 0x1)), + (0x1D50D, (0x11E5, 0x1)), + (0x0FC21, (0xAB8, 0x2)), + (0x0FF4F, (0xFF7, 0x1)), + (0x0FEA1, (0xF3F, 0x1)), + (0x1D60D, (0x12DC, 0x1)), + (0x0FF3A, (0xFE2, 0x1)), + (0x1EE12, (0x151A, 0x1)), + (0x03318, (0x6EA, 0x4)), + (0x0FE7C, (0xF0A, 0x2)), + (0x0FCAB, (0xBDD, 0x2)), + (0x03205, (0x4B7, 0x3)), + (0x001F1, (0x038, 0x2)), + (0x0FE42, (0xECC, 0x1)), + (0x0FE91, (0xF2F, 0x1)), + (0x001C7, (0x02C, 0x2)), + (0x1D681, (0x1350, 0x1)), + (0x1D6DE, (0x13AB, 0x1)), + (0x1D4B0, (0x118E, 0x1)), + (0x1D742, (0x140F, 0x1)), + (0x1D67F, (0x134E, 0x1)), + (0x1D645, (0x1314, 0x1)), + (0x0FEB0, (0xF4E, 0x1)), + (0x1F121, (0x15DF, 0x3)), + (0x1D611, (0x12E0, 0x1)), + (0x1D752, (0x141F, 0x1)), + (0x0FE32, (0xEBC, 0x1)), + (0x0FF81, (0x1029, 0x1)), + (0x02009, (0x11C, 0x1)), + (0x1F14C, (0x1621, 0x2)), + (0x0FEDB, (0xF79, 0x1)), + (0x1D5D0, (0x129F, 0x1)), + (0x0FCFA, (0xC80, 0x2)), + (0x03296, (0x5F7, 0x1)), + (0x1D71A, (0x13E7, 0x1)), + (0x107A6, (0x10AF, 0x1)), + (0x1D5AC, (0x127B, 0x1)), + (0x0FD93, (0xDCB, 0x3)), + (0x1EE8B, (0x156C, 0x1)), + (0x0FECB, (0xF69, 0x1)), + (0x1D7A3, (0x1470, 0x1)), + (0x02F96, (0x3EF, 0x1)), + (0x1EE4E, (0x1541, 0x1)), + (0x024CF, (0x32C, 0x1)), + (0x032AA, (0x60B, 0x1)), + (0x1EE88, (0x156A, 0x1)), + (0x03270, (0x5BE, 0x2)), + (0x0FCEB, (0xC5F, 0x2)), + (0x032E0, (0x665, 0x1)), + (0x1D587, (0x1256, 0x1)), + (0x1CCEC, (0x10D9, 0x1)), + (0x1D7C8, (0x1495, 0x1)), + (0x0FEB2, (0xF50, 0x1)), + (0x03379, (0x836, 0x3)), + (0x1D688, (0x1357, 0x1)), + (0x107B2, (0x10BA, 0x1)), + (0x033C8, (0x8F7, 0x2)), + (0x1D620, (0x12EF, 0x1)), + (0x0FC3D, (0xAF0, 0x2)), + (0x0FDA9, (0xE0D, 0x3)), + (0x1F246, (0x1676, 0x3)), + (0x0FEF9, (0xF9F, 0x3)), + (0x02160, (0x1E3, 0x1)), + (0x1D72F, (0x13FC, 0x1)), + (0x0FC73, (0xB68, 0x2)), + (0x02481, (0x276, 0x4)), + (0x1D528, (0x11FE, 0x1)), + (0x0327D, (0x5DB, 0x4)), + (0x0FB60, (0x9C9, 0x1)), + (0x033B3, (0x8C8, 0x2)), + (0x02F37, (0x390, 0x1)), + (0x1D54D, (0x121D, 0x1)), + (0x0FC33, (0xADC, 0x2)), + (0x032B3, (0x616, 0x2)), + (0x1D41B, (0x1102, 0x1)), + (0x1D475, (0x115B, 0x1)), + (0x0216D, (0x1FE, 0x1)), + (0x0FEB4, (0xF52, 0x1)), + (0x1D41D, (0x1104, 0x1)), + (0x1EE0C, (0x1514, 0x1)), + (0x0FEB6, (0xF54, 0x1)), + (0x1E05D, (0x14F8, 0x1)), + (0x0FF26, (0xFCE, 0x1)), + (0x1D592, (0x1261, 0x1)), + (0x0212F, (0x19C, 0x1)), + (0x0FC18, (0xAA6, 0x2)), + (0x0FDF3, (0xE74, 0x4)), + (0x033F1, (0x959, 0x3)), + (0x0FCB6, (0xBF3, 0x2)), + (0x032B9, (0x622, 0x2)), + (0x0FB79, (0x9E2, 0x1)), + (0x1D4B6, (0x1194, 0x1)), + (0x0FEF0, (0xF8E, 0x1)), + (0x033B7, (0x8D0, 0x2)), + (0x0FB7B, (0x9E4, 0x1)), + (0x1D55A, (0x1229, 0x1)), + (0x0FCB1, (0xBE9, 0x2)), + (0x02472, (0x247, 0x2)), + (0x0321C, (0x50A, 0x4)), + (0x002B2, (0x040, 0x1)), + (0x02F0E, (0x367, 0x1)), + (0x0FF89, (0x1031, 0x1)), + (0x1D6F5, (0x13C2, 0x1)), +]; +pub(crate) const CJK_COMPAT_VARIANTS_DECOMPOSED_CHARS: &[char] = &[ + '\u{349E}', + '\u{FE00}', + '\u{34B9}', + '\u{FE00}', + '\u{34BB}', + '\u{FE00}', + '\u{34DF}', + '\u{FE00}', + '\u{3515}', + '\u{FE00}', + '\u{36EE}', + '\u{FE00}', + '\u{36FC}', + '\u{FE00}', + '\u{3781}', + '\u{FE00}', + '\u{382F}', + '\u{FE00}', + '\u{3862}', + '\u{FE00}', + '\u{387C}', + '\u{FE00}', + '\u{38C7}', + '\u{FE00}', + '\u{38E3}', + '\u{FE00}', + '\u{391C}', + '\u{FE00}', + '\u{393A}', + '\u{FE00}', + '\u{3A2E}', + '\u{FE00}', + '\u{3A6C}', + '\u{FE00}', + '\u{3AE4}', + '\u{FE00}', + '\u{3B08}', + '\u{FE00}', + '\u{3B19}', + '\u{FE00}', + '\u{3B49}', + '\u{FE00}', + '\u{3B9D}', + '\u{FE00}', + '\u{3B9D}', + '\u{FE01}', + '\u{3C18}', + '\u{FE00}', + '\u{3C4E}', + '\u{FE00}', + '\u{3D33}', + '\u{FE00}', + '\u{3D96}', + '\u{FE00}', + '\u{3EAC}', + '\u{FE00}', + '\u{3EB8}', + '\u{FE00}', + '\u{3EB8}', + '\u{FE01}', + '\u{3F1B}', + '\u{FE00}', + '\u{3FFC}', + '\u{FE00}', + '\u{4008}', + '\u{FE00}', + '\u{4018}', + '\u{FE00}', + '\u{4039}', + '\u{FE00}', + '\u{4039}', + '\u{FE01}', + '\u{4046}', + '\u{FE00}', + '\u{4096}', + '\u{FE00}', + '\u{40E3}', + '\u{FE00}', + '\u{412F}', + '\u{FE00}', + '\u{4202}', + '\u{FE00}', + '\u{4227}', + '\u{FE00}', + '\u{42A0}', + '\u{FE00}', + '\u{4301}', + '\u{FE00}', + '\u{4334}', + '\u{FE00}', + '\u{4359}', + '\u{FE00}', + '\u{43D5}', + '\u{FE00}', + '\u{43D9}', + '\u{FE00}', + '\u{440B}', + '\u{FE00}', + '\u{446B}', + '\u{FE00}', + '\u{452B}', + '\u{FE00}', + '\u{455D}', + '\u{FE00}', + '\u{4561}', + '\u{FE00}', + '\u{456B}', + '\u{FE00}', + '\u{45D7}', + '\u{FE00}', + '\u{45F9}', + '\u{FE00}', + '\u{4635}', + '\u{FE00}', + '\u{46BE}', + '\u{FE00}', + '\u{46C7}', + '\u{FE00}', + '\u{4995}', + '\u{FE00}', + '\u{49E6}', + '\u{FE00}', + '\u{4A6E}', + '\u{FE00}', + '\u{4A76}', + '\u{FE00}', + '\u{4AB2}', + '\u{FE00}', + '\u{4B33}', + '\u{FE00}', + '\u{4BCE}', + '\u{FE00}', + '\u{4CCE}', + '\u{FE00}', + '\u{4CED}', + '\u{FE00}', + '\u{4CF8}', + '\u{FE00}', + '\u{4D56}', + '\u{FE00}', + '\u{4E0D}', + '\u{FE00}', + '\u{4E26}', + '\u{FE00}', + '\u{4E32}', + '\u{FE00}', + '\u{4E38}', + '\u{FE00}', + '\u{4E39}', + '\u{FE00}', + '\u{4E3D}', + '\u{FE00}', + '\u{4E41}', + '\u{FE00}', + '\u{4E82}', + '\u{FE00}', + '\u{4E86}', + '\u{FE00}', + '\u{4EAE}', + '\u{FE00}', + '\u{4EC0}', + '\u{FE00}', + '\u{4ECC}', + '\u{FE00}', + '\u{4EE4}', + '\u{FE00}', + '\u{4F60}', + '\u{FE00}', + '\u{4F80}', + '\u{FE00}', + '\u{4F86}', + '\u{FE00}', + '\u{4F8B}', + '\u{FE00}', + '\u{4FAE}', + '\u{FE00}', + '\u{4FAE}', + '\u{FE01}', + '\u{4FBB}', + '\u{FE00}', + '\u{4FBF}', + '\u{FE00}', + '\u{5002}', + '\u{FE00}', + '\u{502B}', + '\u{FE00}', + '\u{507A}', + '\u{FE00}', + '\u{5099}', + '\u{FE00}', + '\u{50CF}', + '\u{FE00}', + '\u{50DA}', + '\u{FE00}', + '\u{50E7}', + '\u{FE00}', + '\u{50E7}', + '\u{FE01}', + '\u{5140}', + '\u{FE00}', + '\u{5145}', + '\u{FE00}', + '\u{514D}', + '\u{FE00}', + '\u{514D}', + '\u{FE01}', + '\u{5154}', + '\u{FE00}', + '\u{5164}', + '\u{FE00}', + '\u{5167}', + '\u{FE00}', + '\u{5168}', + '\u{FE00}', + '\u{5169}', + '\u{FE00}', + '\u{516D}', + '\u{FE00}', + '\u{5177}', + '\u{FE00}', + '\u{5180}', + '\u{FE00}', + '\u{518D}', + '\u{FE00}', + '\u{5192}', + '\u{FE00}', + '\u{5195}', + '\u{FE00}', + '\u{5197}', + '\u{FE00}', + '\u{51A4}', + '\u{FE00}', + '\u{51AC}', + '\u{FE00}', + '\u{51B5}', + '\u{FE00}', + '\u{51B5}', + '\u{FE01}', + '\u{51B7}', + '\u{FE00}', + '\u{51C9}', + '\u{FE00}', + '\u{51CC}', + '\u{FE00}', + '\u{51DC}', + '\u{FE00}', + '\u{51DE}', + '\u{FE00}', + '\u{51F5}', + '\u{FE00}', + '\u{5203}', + '\u{FE00}', + '\u{5207}', + '\u{FE00}', + '\u{5207}', + '\u{FE01}', + '\u{5217}', + '\u{FE00}', + '\u{5229}', + '\u{FE00}', + '\u{523A}', + '\u{FE00}', + '\u{523B}', + '\u{FE00}', + '\u{5246}', + '\u{FE00}', + '\u{5272}', + '\u{FE00}', + '\u{5277}', + '\u{FE00}', + '\u{5289}', + '\u{FE00}', + '\u{529B}', + '\u{FE00}', + '\u{52A3}', + '\u{FE00}', + '\u{52B3}', + '\u{FE00}', + '\u{52C7}', + '\u{FE00}', + '\u{52C7}', + '\u{FE01}', + '\u{52C9}', + '\u{FE00}', + '\u{52C9}', + '\u{FE01}', + '\u{52D2}', + '\u{FE00}', + '\u{52DE}', + '\u{FE00}', + '\u{52E4}', + '\u{FE00}', + '\u{52E4}', + '\u{FE01}', + '\u{52F5}', + '\u{FE00}', + '\u{52FA}', + '\u{FE00}', + '\u{52FA}', + '\u{FE01}', + '\u{5305}', + '\u{FE00}', + '\u{5306}', + '\u{FE00}', + '\u{5317}', + '\u{FE00}', + '\u{5317}', + '\u{FE01}', + '\u{533F}', + '\u{FE00}', + '\u{5349}', + '\u{FE00}', + '\u{5351}', + '\u{FE00}', + '\u{5351}', + '\u{FE01}', + '\u{535A}', + '\u{FE00}', + '\u{5373}', + '\u{FE00}', + '\u{5375}', + '\u{FE00}', + '\u{537D}', + '\u{FE00}', + '\u{537F}', + '\u{FE00}', + '\u{537F}', + '\u{FE01}', + '\u{537F}', + '\u{FE02}', + '\u{53C3}', + '\u{FE00}', + '\u{53CA}', + '\u{FE00}', + '\u{53DF}', + '\u{FE00}', + '\u{53E5}', + '\u{FE00}', + '\u{53EB}', + '\u{FE00}', + '\u{53F1}', + '\u{FE00}', + '\u{5406}', + '\u{FE00}', + '\u{540F}', + '\u{FE00}', + '\u{541D}', + '\u{FE00}', + '\u{5438}', + '\u{FE00}', + '\u{5442}', + '\u{FE00}', + '\u{5448}', + '\u{FE00}', + '\u{5468}', + '\u{FE00}', + '\u{549E}', + '\u{FE00}', + '\u{54A2}', + '\u{FE00}', + '\u{54BD}', + '\u{FE00}', + '\u{54F6}', + '\u{FE00}', + '\u{5510}', + '\u{FE00}', + '\u{5553}', + '\u{FE00}', + '\u{5555}', + '\u{FE00}', + '\u{5563}', + '\u{FE00}', + '\u{5584}', + '\u{FE00}', + '\u{5584}', + '\u{FE01}', + '\u{5587}', + '\u{FE00}', + '\u{5599}', + '\u{FE00}', + '\u{5599}', + '\u{FE01}', + '\u{559D}', + '\u{FE00}', + '\u{559D}', + '\u{FE01}', + '\u{55AB}', + '\u{FE00}', + '\u{55B3}', + '\u{FE00}', + '\u{55C0}', + '\u{FE00}', + '\u{55C2}', + '\u{FE00}', + '\u{55E2}', + '\u{FE00}', + '\u{5606}', + '\u{FE00}', + '\u{5606}', + '\u{FE01}', + '\u{5651}', + '\u{FE00}', + '\u{5668}', + '\u{FE00}', + '\u{5674}', + '\u{FE00}', + '\u{56F9}', + '\u{FE00}', + '\u{5716}', + '\u{FE00}', + '\u{5717}', + '\u{FE00}', + '\u{578B}', + '\u{FE00}', + '\u{57CE}', + '\u{FE00}', + '\u{57F4}', + '\u{FE00}', + '\u{580D}', + '\u{FE00}', + '\u{5831}', + '\u{FE00}', + '\u{5832}', + '\u{FE00}', + '\u{5840}', + '\u{FE00}', + '\u{585A}', + '\u{FE00}', + '\u{585A}', + '\u{FE01}', + '\u{585E}', + '\u{FE00}', + '\u{58A8}', + '\u{FE00}', + '\u{58AC}', + '\u{FE00}', + '\u{58B3}', + '\u{FE00}', + '\u{58D8}', + '\u{FE00}', + '\u{58DF}', + '\u{FE00}', + '\u{58EE}', + '\u{FE00}', + '\u{58F2}', + '\u{FE00}', + '\u{58F7}', + '\u{FE00}', + '\u{5906}', + '\u{FE00}', + '\u{591A}', + '\u{FE00}', + '\u{5922}', + '\u{FE00}', + '\u{5944}', + '\u{FE00}', + '\u{5948}', + '\u{FE00}', + '\u{5951}', + '\u{FE00}', + '\u{5954}', + '\u{FE00}', + '\u{5962}', + '\u{FE00}', + '\u{5973}', + '\u{FE00}', + '\u{59D8}', + '\u{FE00}', + '\u{59EC}', + '\u{FE00}', + '\u{5A1B}', + '\u{FE00}', + '\u{5A27}', + '\u{FE00}', + '\u{5A62}', + '\u{FE00}', + '\u{5A66}', + '\u{FE00}', + '\u{5AB5}', + '\u{FE00}', + '\u{5B08}', + '\u{FE00}', + '\u{5B28}', + '\u{FE00}', + '\u{5B3E}', + '\u{FE00}', + '\u{5B3E}', + '\u{FE01}', + '\u{5B85}', + '\u{FE00}', + '\u{5BC3}', + '\u{FE00}', + '\u{5BD8}', + '\u{FE00}', + '\u{5BE7}', + '\u{FE00}', + '\u{5BE7}', + '\u{FE01}', + '\u{5BE7}', + '\u{FE02}', + '\u{5BEE}', + '\u{FE00}', + '\u{5BF3}', + '\u{FE00}', + '\u{5BFF}', + '\u{FE00}', + '\u{5C06}', + '\u{FE00}', + '\u{5C22}', + '\u{FE00}', + '\u{5C3F}', + '\u{FE00}', + '\u{5C60}', + '\u{FE00}', + '\u{5C62}', + '\u{FE00}', + '\u{5C64}', + '\u{FE00}', + '\u{5C65}', + '\u{FE00}', + '\u{5C6E}', + '\u{FE00}', + '\u{5C6E}', + '\u{FE01}', + '\u{5C8D}', + '\u{FE00}', + '\u{5CC0}', + '\u{FE00}', + '\u{5D19}', + '\u{FE00}', + '\u{5D43}', + '\u{FE00}', + '\u{5D50}', + '\u{FE00}', + '\u{5D6B}', + '\u{FE00}', + '\u{5D6E}', + '\u{FE00}', + '\u{5D7C}', + '\u{FE00}', + '\u{5DB2}', + '\u{FE00}', + '\u{5DBA}', + '\u{FE00}', + '\u{5DE1}', + '\u{FE00}', + '\u{5DE2}', + '\u{FE00}', + '\u{5DFD}', + '\u{FE00}', + '\u{5E28}', + '\u{FE00}', + '\u{5E3D}', + '\u{FE00}', + '\u{5E69}', + '\u{FE00}', + '\u{5E74}', + '\u{FE00}', + '\u{5EA6}', + '\u{FE00}', + '\u{5EB0}', + '\u{FE00}', + '\u{5EB3}', + '\u{FE00}', + '\u{5EB6}', + '\u{FE00}', + '\u{5EC9}', + '\u{FE00}', + '\u{5ECA}', + '\u{FE00}', + '\u{5ECA}', + '\u{FE01}', + '\u{5ED2}', + '\u{FE00}', + '\u{5ED3}', + '\u{FE00}', + '\u{5ED9}', + '\u{FE00}', + '\u{5EEC}', + '\u{FE00}', + '\u{5EFE}', + '\u{FE00}', + '\u{5F04}', + '\u{FE00}', + '\u{5F22}', + '\u{FE00}', + '\u{5F22}', + '\u{FE01}', + '\u{5F53}', + '\u{FE00}', + '\u{5F62}', + '\u{FE00}', + '\u{5F69}', + '\u{FE00}', + '\u{5F6B}', + '\u{FE00}', + '\u{5F8B}', + '\u{FE00}', + '\u{5F9A}', + '\u{FE00}', + '\u{5FA9}', + '\u{FE00}', + '\u{5FAD}', + '\u{FE00}', + '\u{5FCD}', + '\u{FE00}', + '\u{5FD7}', + '\u{FE00}', + '\u{5FF5}', + '\u{FE00}', + '\u{5FF9}', + '\u{FE00}', + '\u{6012}', + '\u{FE00}', + '\u{601C}', + '\u{FE00}', + '\u{6075}', + '\u{FE00}', + '\u{6081}', + '\u{FE00}', + '\u{6094}', + '\u{FE00}', + '\u{6094}', + '\u{FE01}', + '\u{60C7}', + '\u{FE00}', + '\u{60D8}', + '\u{FE00}', + '\u{60E1}', + '\u{FE00}', + '\u{6108}', + '\u{FE00}', + '\u{6144}', + '\u{FE00}', + '\u{6148}', + '\u{FE00}', + '\u{614C}', + '\u{FE00}', + '\u{614C}', + '\u{FE01}', + '\u{614E}', + '\u{FE00}', + '\u{614E}', + '\u{FE01}', + '\u{6160}', + '\u{FE00}', + '\u{6168}', + '\u{FE00}', + '\u{617A}', + '\u{FE00}', + '\u{618E}', + '\u{FE00}', + '\u{618E}', + '\u{FE01}', + '\u{618E}', + '\u{FE02}', + '\u{6190}', + '\u{FE00}', + '\u{61A4}', + '\u{FE00}', + '\u{61AF}', + '\u{FE00}', + '\u{61B2}', + '\u{FE00}', + '\u{61DE}', + '\u{FE00}', + '\u{61F2}', + '\u{FE00}', + '\u{61F2}', + '\u{FE01}', + '\u{61F2}', + '\u{FE02}', + '\u{61F6}', + '\u{FE00}', + '\u{61F6}', + '\u{FE01}', + '\u{6200}', + '\u{FE00}', + '\u{6210}', + '\u{FE00}', + '\u{621B}', + '\u{FE00}', + '\u{622E}', + '\u{FE00}', + '\u{6234}', + '\u{FE00}', + '\u{625D}', + '\u{FE00}', + '\u{62B1}', + '\u{FE00}', + '\u{62C9}', + '\u{FE00}', + '\u{62CF}', + '\u{FE00}', + '\u{62D3}', + '\u{FE00}', + '\u{62D4}', + '\u{FE00}', + '\u{62FC}', + '\u{FE00}', + '\u{62FE}', + '\u{FE00}', + '\u{633D}', + '\u{FE00}', + '\u{6350}', + '\u{FE00}', + '\u{6368}', + '\u{FE00}', + '\u{637B}', + '\u{FE00}', + '\u{6383}', + '\u{FE00}', + '\u{63A0}', + '\u{FE00}', + '\u{63A9}', + '\u{FE00}', + '\u{63C4}', + '\u{FE00}', + '\u{63C5}', + '\u{FE00}', + '\u{63E4}', + '\u{FE00}', + '\u{641C}', + '\u{FE00}', + '\u{6422}', + '\u{FE00}', + '\u{6452}', + '\u{FE00}', + '\u{6469}', + '\u{FE00}', + '\u{6477}', + '\u{FE00}', + '\u{647E}', + '\u{FE00}', + '\u{649A}', + '\u{FE00}', + '\u{649D}', + '\u{FE00}', + '\u{64C4}', + '\u{FE00}', + '\u{654F}', + '\u{FE00}', + '\u{654F}', + '\u{FE01}', + '\u{6556}', + '\u{FE00}', + '\u{656C}', + '\u{FE00}', + '\u{6578}', + '\u{FE00}', + '\u{6599}', + '\u{FE00}', + '\u{65C5}', + '\u{FE00}', + '\u{65E2}', + '\u{FE00}', + '\u{65E3}', + '\u{FE00}', + '\u{6613}', + '\u{FE00}', + '\u{6649}', + '\u{FE00}', + '\u{6674}', + '\u{FE00}', + '\u{6674}', + '\u{FE01}', + '\u{6688}', + '\u{FE00}', + '\u{6691}', + '\u{FE00}', + '\u{6691}', + '\u{FE01}', + '\u{669C}', + '\u{FE00}', + '\u{66B4}', + '\u{FE00}', + '\u{66C6}', + '\u{FE00}', + '\u{66F4}', + '\u{FE00}', + '\u{66F8}', + '\u{FE00}', + '\u{6700}', + '\u{FE00}', + '\u{6717}', + '\u{FE00}', + '\u{6717}', + '\u{FE01}', + '\u{6717}', + '\u{FE02}', + '\u{671B}', + '\u{FE00}', + '\u{671B}', + '\u{FE01}', + '\u{6721}', + '\u{FE00}', + '\u{674E}', + '\u{FE00}', + '\u{6753}', + '\u{FE00}', + '\u{6756}', + '\u{FE00}', + '\u{675E}', + '\u{FE00}', + '\u{677B}', + '\u{FE00}', + '\u{6785}', + '\u{FE00}', + '\u{6797}', + '\u{FE00}', + '\u{67F3}', + '\u{FE00}', + '\u{67FA}', + '\u{FE00}', + '\u{6817}', + '\u{FE00}', + '\u{681F}', + '\u{FE00}', + '\u{6852}', + '\u{FE00}', + '\u{6881}', + '\u{FE00}', + '\u{6885}', + '\u{FE00}', + '\u{6885}', + '\u{FE01}', + '\u{688E}', + '\u{FE00}', + '\u{68A8}', + '\u{FE00}', + '\u{6914}', + '\u{FE00}', + '\u{6942}', + '\u{FE00}', + '\u{69A3}', + '\u{FE00}', + '\u{69EA}', + '\u{FE00}', + '\u{6A02}', + '\u{FE00}', + '\u{6A02}', + '\u{FE01}', + '\u{6A02}', + '\u{FE02}', + '\u{6A13}', + '\u{FE00}', + '\u{6AA8}', + '\u{FE00}', + '\u{6AD3}', + '\u{FE00}', + '\u{6ADB}', + '\u{FE00}', + '\u{6B04}', + '\u{FE00}', + '\u{6B21}', + '\u{FE00}', + '\u{6B54}', + '\u{FE00}', + '\u{6B72}', + '\u{FE00}', + '\u{6B77}', + '\u{FE00}', + '\u{6B79}', + '\u{FE00}', + '\u{6B9F}', + '\u{FE00}', + '\u{6BAE}', + '\u{FE00}', + '\u{6BBA}', + '\u{FE00}', + '\u{6BBA}', + '\u{FE01}', + '\u{6BBA}', + '\u{FE02}', + '\u{6BBB}', + '\u{FE00}', + '\u{6C4E}', + '\u{FE00}', + '\u{6C67}', + '\u{FE00}', + '\u{6C88}', + '\u{FE00}', + '\u{6CBF}', + '\u{FE00}', + '\u{6CCC}', + '\u{FE00}', + '\u{6CCD}', + '\u{FE00}', + '\u{6CE5}', + '\u{FE00}', + '\u{6D16}', + '\u{FE00}', + '\u{6D1B}', + '\u{FE00}', + '\u{6D1E}', + '\u{FE00}', + '\u{6D34}', + '\u{FE00}', + '\u{6D3E}', + '\u{FE00}', + '\u{6D41}', + '\u{FE00}', + '\u{6D41}', + '\u{FE01}', + '\u{6D41}', + '\u{FE02}', + '\u{6D69}', + '\u{FE00}', + '\u{6D6A}', + '\u{FE00}', + '\u{6D77}', + '\u{FE00}', + '\u{6D77}', + '\u{FE01}', + '\u{6D78}', + '\u{FE00}', + '\u{6D85}', + '\u{FE00}', + '\u{6DCB}', + '\u{FE00}', + '\u{6DDA}', + '\u{FE00}', + '\u{6DEA}', + '\u{FE00}', + '\u{6DF9}', + '\u{FE00}', + '\u{6E1A}', + '\u{FE00}', + '\u{6E2F}', + '\u{FE00}', + '\u{6E6E}', + '\u{FE00}', + '\u{6E9C}', + '\u{FE00}', + '\u{6EBA}', + '\u{FE00}', + '\u{6EC7}', + '\u{FE00}', + '\u{6ECB}', + '\u{FE00}', + '\u{6ECB}', + '\u{FE01}', + '\u{6ED1}', + '\u{FE00}', + '\u{6EDB}', + '\u{FE00}', + '\u{6F0F}', + '\u{FE00}', + '\u{6F22}', + '\u{FE00}', + '\u{6F22}', + '\u{FE01}', + '\u{6F23}', + '\u{FE00}', + '\u{6F6E}', + '\u{FE00}', + '\u{6FC6}', + '\u{FE00}', + '\u{6FEB}', + '\u{FE00}', + '\u{6FFE}', + '\u{FE00}', + '\u{701B}', + '\u{FE00}', + '\u{701E}', + '\u{FE00}', + '\u{701E}', + '\u{FE01}', + '\u{7039}', + '\u{FE00}', + '\u{704A}', + '\u{FE00}', + '\u{7070}', + '\u{FE00}', + '\u{7077}', + '\u{FE00}', + '\u{707D}', + '\u{FE00}', + '\u{7099}', + '\u{FE00}', + '\u{70AD}', + '\u{FE00}', + '\u{70C8}', + '\u{FE00}', + '\u{70D9}', + '\u{FE00}', + '\u{7145}', + '\u{FE00}', + '\u{7149}', + '\u{FE00}', + '\u{716E}', + '\u{FE00}', + '\u{716E}', + '\u{FE01}', + '\u{719C}', + '\u{FE00}', + '\u{71CE}', + '\u{FE00}', + '\u{71D0}', + '\u{FE00}', + '\u{7210}', + '\u{FE00}', + '\u{721B}', + '\u{FE00}', + '\u{7228}', + '\u{FE00}', + '\u{722B}', + '\u{FE00}', + '\u{7235}', + '\u{FE00}', + '\u{7235}', + '\u{FE01}', + '\u{7250}', + '\u{FE00}', + '\u{7262}', + '\u{FE00}', + '\u{7280}', + '\u{FE00}', + '\u{7295}', + '\u{FE00}', + '\u{72AF}', + '\u{FE00}', + '\u{72C0}', + '\u{FE00}', + '\u{72FC}', + '\u{FE00}', + '\u{732A}', + '\u{FE00}', + '\u{732A}', + '\u{FE01}', + '\u{7375}', + '\u{FE00}', + '\u{737A}', + '\u{FE00}', + '\u{7387}', + '\u{FE00}', + '\u{7387}', + '\u{FE01}', + '\u{738B}', + '\u{FE00}', + '\u{73A5}', + '\u{FE00}', + '\u{73B2}', + '\u{FE00}', + '\u{73DE}', + '\u{FE00}', + '\u{7406}', + '\u{FE00}', + '\u{7409}', + '\u{FE00}', + '\u{7422}', + '\u{FE00}', + '\u{7447}', + '\u{FE00}', + '\u{745C}', + '\u{FE00}', + '\u{7469}', + '\u{FE00}', + '\u{7471}', + '\u{FE00}', + '\u{7471}', + '\u{FE01}', + '\u{7485}', + '\u{FE00}', + '\u{7489}', + '\u{FE00}', + '\u{7498}', + '\u{FE00}', + '\u{74CA}', + '\u{FE00}', + '\u{7506}', + '\u{FE00}', + '\u{7524}', + '\u{FE00}', + '\u{753B}', + '\u{FE00}', + '\u{753E}', + '\u{FE00}', + '\u{7559}', + '\u{FE00}', + '\u{7565}', + '\u{FE00}', + '\u{7570}', + '\u{FE00}', + '\u{7570}', + '\u{FE01}', + '\u{75E2}', + '\u{FE00}', + '\u{7610}', + '\u{FE00}', + '\u{761D}', + '\u{FE00}', + '\u{761F}', + '\u{FE00}', + '\u{7642}', + '\u{FE00}', + '\u{7669}', + '\u{FE00}', + '\u{76CA}', + '\u{FE00}', + '\u{76CA}', + '\u{FE01}', + '\u{76DB}', + '\u{FE00}', + '\u{76E7}', + '\u{FE00}', + '\u{76F4}', + '\u{FE00}', + '\u{76F4}', + '\u{FE01}', + '\u{7701}', + '\u{FE00}', + '\u{771E}', + '\u{FE00}', + '\u{771F}', + '\u{FE00}', + '\u{771F}', + '\u{FE01}', + '\u{7740}', + '\u{FE00}', + '\u{774A}', + '\u{FE00}', + '\u{774A}', + '\u{FE01}', + '\u{778B}', + '\u{FE00}', + '\u{77A7}', + '\u{FE00}', + '\u{784E}', + '\u{FE00}', + '\u{786B}', + '\u{FE00}', + '\u{788C}', + '\u{FE00}', + '\u{788C}', + '\u{FE01}', + '\u{7891}', + '\u{FE00}', + '\u{78CA}', + '\u{FE00}', + '\u{78CC}', + '\u{FE00}', + '\u{78CC}', + '\u{FE01}', + '\u{78FB}', + '\u{FE00}', + '\u{792A}', + '\u{FE00}', + '\u{793C}', + '\u{FE00}', + '\u{793E}', + '\u{FE00}', + '\u{7948}', + '\u{FE00}', + '\u{7949}', + '\u{FE00}', + '\u{7950}', + '\u{FE00}', + '\u{7956}', + '\u{FE00}', + '\u{7956}', + '\u{FE01}', + '\u{795D}', + '\u{FE00}', + '\u{795E}', + '\u{FE00}', + '\u{7965}', + '\u{FE00}', + '\u{797F}', + '\u{FE00}', + '\u{798D}', + '\u{FE00}', + '\u{798E}', + '\u{FE00}', + '\u{798F}', + '\u{FE00}', + '\u{798F}', + '\u{FE01}', + '\u{79AE}', + '\u{FE00}', + '\u{79CA}', + '\u{FE00}', + '\u{79EB}', + '\u{FE00}', + '\u{7A1C}', + '\u{FE00}', + '\u{7A40}', + '\u{FE00}', + '\u{7A40}', + '\u{FE01}', + '\u{7A4A}', + '\u{FE00}', + '\u{7A4F}', + '\u{FE00}', + '\u{7A81}', + '\u{FE00}', + '\u{7AB1}', + '\u{FE00}', + '\u{7ACB}', + '\u{FE00}', + '\u{7AEE}', + '\u{FE00}', + '\u{7B20}', + '\u{FE00}', + '\u{7BC0}', + '\u{FE00}', + '\u{7BC0}', + '\u{FE01}', + '\u{7BC6}', + '\u{FE00}', + '\u{7BC9}', + '\u{FE00}', + '\u{7C3E}', + '\u{FE00}', + '\u{7C60}', + '\u{FE00}', + '\u{7C7B}', + '\u{FE00}', + '\u{7C92}', + '\u{FE00}', + '\u{7CBE}', + '\u{FE00}', + '\u{7CD2}', + '\u{FE00}', + '\u{7CD6}', + '\u{FE00}', + '\u{7CE3}', + '\u{FE00}', + '\u{7CE7}', + '\u{FE00}', + '\u{7CE8}', + '\u{FE00}', + '\u{7D00}', + '\u{FE00}', + '\u{7D10}', + '\u{FE00}', + '\u{7D22}', + '\u{FE00}', + '\u{7D2F}', + '\u{FE00}', + '\u{7D5B}', + '\u{FE00}', + '\u{7D63}', + '\u{FE00}', + '\u{7DA0}', + '\u{FE00}', + '\u{7DBE}', + '\u{FE00}', + '\u{7DC7}', + '\u{FE00}', + '\u{7DF4}', + '\u{FE00}', + '\u{7DF4}', + '\u{FE01}', + '\u{7DF4}', + '\u{FE02}', + '\u{7E02}', + '\u{FE00}', + '\u{7E09}', + '\u{FE00}', + '\u{7E37}', + '\u{FE00}', + '\u{7E41}', + '\u{FE00}', + '\u{7E45}', + '\u{FE00}', + '\u{7F3E}', + '\u{FE00}', + '\u{7F72}', + '\u{FE00}', + '\u{7F79}', + '\u{FE00}', + '\u{7F7A}', + '\u{FE00}', + '\u{7F85}', + '\u{FE00}', + '\u{7F95}', + '\u{FE00}', + '\u{7F9A}', + '\u{FE00}', + '\u{7FBD}', + '\u{FE00}', + '\u{7FFA}', + '\u{FE00}', + '\u{8001}', + '\u{FE00}', + '\u{8005}', + '\u{FE00}', + '\u{8005}', + '\u{FE01}', + '\u{8005}', + '\u{FE02}', + '\u{8046}', + '\u{FE00}', + '\u{8060}', + '\u{FE00}', + '\u{806F}', + '\u{FE00}', + '\u{8070}', + '\u{FE00}', + '\u{807E}', + '\u{FE00}', + '\u{808B}', + '\u{FE00}', + '\u{80AD}', + '\u{FE00}', + '\u{80B2}', + '\u{FE00}', + '\u{8103}', + '\u{FE00}', + '\u{813E}', + '\u{FE00}', + '\u{81D8}', + '\u{FE00}', + '\u{81E8}', + '\u{FE00}', + '\u{81ED}', + '\u{FE00}', + '\u{8201}', + '\u{FE00}', + '\u{8201}', + '\u{FE01}', + '\u{8204}', + '\u{FE00}', + '\u{8218}', + '\u{FE00}', + '\u{826F}', + '\u{FE00}', + '\u{8279}', + '\u{FE00}', + '\u{8279}', + '\u{FE01}', + '\u{828B}', + '\u{FE00}', + '\u{8291}', + '\u{FE00}', + '\u{829D}', + '\u{FE00}', + '\u{82B1}', + '\u{FE00}', + '\u{82B3}', + '\u{FE00}', + '\u{82BD}', + '\u{FE00}', + '\u{82E5}', + '\u{FE00}', + '\u{82E5}', + '\u{FE01}', + '\u{82E6}', + '\u{FE00}', + '\u{831D}', + '\u{FE00}', + '\u{8323}', + '\u{FE00}', + '\u{8336}', + '\u{FE00}', + '\u{8352}', + '\u{FE00}', + '\u{8353}', + '\u{FE00}', + '\u{8363}', + '\u{FE00}', + '\u{83AD}', + '\u{FE00}', + '\u{83BD}', + '\u{FE00}', + '\u{83C9}', + '\u{FE00}', + '\u{83CA}', + '\u{FE00}', + '\u{83CC}', + '\u{FE00}', + '\u{83DC}', + '\u{FE00}', + '\u{83E7}', + '\u{FE00}', + '\u{83EF}', + '\u{FE00}', + '\u{83F1}', + '\u{FE00}', + '\u{843D}', + '\u{FE00}', + '\u{8449}', + '\u{FE00}', + '\u{8457}', + '\u{FE00}', + '\u{8457}', + '\u{FE01}', + '\u{84EE}', + '\u{FE00}', + '\u{84F1}', + '\u{FE00}', + '\u{84F3}', + '\u{FE00}', + '\u{84FC}', + '\u{FE00}', + '\u{8516}', + '\u{FE00}', + '\u{8564}', + '\u{FE00}', + '\u{85CD}', + '\u{FE00}', + '\u{85FA}', + '\u{FE00}', + '\u{8606}', + '\u{FE00}', + '\u{8612}', + '\u{FE00}', + '\u{862D}', + '\u{FE00}', + '\u{863F}', + '\u{FE00}', + '\u{8650}', + '\u{FE00}', + '\u{865C}', + '\u{FE00}', + '\u{865C}', + '\u{FE01}', + '\u{8667}', + '\u{FE00}', + '\u{8669}', + '\u{FE00}', + '\u{8688}', + '\u{FE00}', + '\u{86A9}', + '\u{FE00}', + '\u{86E2}', + '\u{FE00}', + '\u{870E}', + '\u{FE00}', + '\u{8728}', + '\u{FE00}', + '\u{876B}', + '\u{FE00}', + '\u{8779}', + '\u{FE00}', + '\u{8779}', + '\u{FE01}', + '\u{8786}', + '\u{FE00}', + '\u{87BA}', + '\u{FE00}', + '\u{87E1}', + '\u{FE00}', + '\u{8801}', + '\u{FE00}', + '\u{881F}', + '\u{FE00}', + '\u{884C}', + '\u{FE00}', + '\u{8860}', + '\u{FE00}', + '\u{8863}', + '\u{FE00}', + '\u{88C2}', + '\u{FE00}', + '\u{88CF}', + '\u{FE00}', + '\u{88D7}', + '\u{FE00}', + '\u{88DE}', + '\u{FE00}', + '\u{88E1}', + '\u{FE00}', + '\u{88F8}', + '\u{FE00}', + '\u{88FA}', + '\u{FE00}', + '\u{8910}', + '\u{FE00}', + '\u{8941}', + '\u{FE00}', + '\u{8964}', + '\u{FE00}', + '\u{8986}', + '\u{FE00}', + '\u{898B}', + '\u{FE00}', + '\u{8996}', + '\u{FE00}', + '\u{8996}', + '\u{FE01}', + '\u{8AA0}', + '\u{FE00}', + '\u{8AAA}', + '\u{FE00}', + '\u{8AAA}', + '\u{FE01}', + '\u{8ABF}', + '\u{FE00}', + '\u{8ACB}', + '\u{FE00}', + '\u{8AD2}', + '\u{FE00}', + '\u{8AD6}', + '\u{FE00}', + '\u{8AED}', + '\u{FE00}', + '\u{8AED}', + '\u{FE01}', + '\u{8AF8}', + '\u{FE00}', + '\u{8AF8}', + '\u{FE01}', + '\u{8AFE}', + '\u{FE00}', + '\u{8AFE}', + '\u{FE01}', + '\u{8B01}', + '\u{FE00}', + '\u{8B01}', + '\u{FE01}', + '\u{8B39}', + '\u{FE00}', + '\u{8B39}', + '\u{FE01}', + '\u{8B58}', + '\u{FE00}', + '\u{8B80}', + '\u{FE00}', + '\u{8B8A}', + '\u{FE00}', + '\u{8B8A}', + '\u{FE01}', + '\u{8C48}', + '\u{FE00}', + '\u{8C55}', + '\u{FE00}', + '\u{8CAB}', + '\u{FE00}', + '\u{8CC1}', + '\u{FE00}', + '\u{8CC2}', + '\u{FE00}', + '\u{8CC8}', + '\u{FE00}', + '\u{8CD3}', + '\u{FE00}', + '\u{8D08}', + '\u{FE00}', + '\u{8D08}', + '\u{FE01}', + '\u{8D1B}', + '\u{FE00}', + '\u{8D77}', + '\u{FE00}', + '\u{8DBC}', + '\u{FE00}', + '\u{8DCB}', + '\u{FE00}', + '\u{8DEF}', + '\u{FE00}', + '\u{8DF0}', + '\u{FE00}', + '\u{8ECA}', + '\u{FE00}', + '\u{8ED4}', + '\u{FE00}', + '\u{8F26}', + '\u{FE00}', + '\u{8F2A}', + '\u{FE00}', + '\u{8F38}', + '\u{FE00}', + '\u{8F38}', + '\u{FE01}', + '\u{8F3B}', + '\u{FE00}', + '\u{8F62}', + '\u{FE00}', + '\u{8F9E}', + '\u{FE00}', + '\u{8FB0}', + '\u{FE00}', + '\u{8FB6}', + '\u{FE00}', + '\u{9023}', + '\u{FE00}', + '\u{9038}', + '\u{FE00}', + '\u{9038}', + '\u{FE01}', + '\u{9072}', + '\u{FE00}', + '\u{907C}', + '\u{FE00}', + '\u{908F}', + '\u{FE00}', + '\u{9094}', + '\u{FE00}', + '\u{90CE}', + '\u{FE00}', + '\u{90DE}', + '\u{FE00}', + '\u{90F1}', + '\u{FE00}', + '\u{90FD}', + '\u{FE00}', + '\u{9111}', + '\u{FE00}', + '\u{911B}', + '\u{FE00}', + '\u{916A}', + '\u{FE00}', + '\u{9199}', + '\u{FE00}', + '\u{91B4}', + '\u{FE00}', + '\u{91CC}', + '\u{FE00}', + '\u{91CF}', + '\u{FE00}', + '\u{91D1}', + '\u{FE00}', + '\u{9234}', + '\u{FE00}', + '\u{9238}', + '\u{FE00}', + '\u{9276}', + '\u{FE00}', + '\u{927C}', + '\u{FE00}', + '\u{92D7}', + '\u{FE00}', + '\u{92D8}', + '\u{FE00}', + '\u{9304}', + '\u{FE00}', + '\u{934A}', + '\u{FE00}', + '\u{93F9}', + '\u{FE00}', + '\u{9415}', + '\u{FE00}', + '\u{958B}', + '\u{FE00}', + '\u{95AD}', + '\u{FE00}', + '\u{95B7}', + '\u{FE00}', + '\u{962E}', + '\u{FE00}', + '\u{964B}', + '\u{FE00}', + '\u{964D}', + '\u{FE00}', + '\u{9675}', + '\u{FE00}', + '\u{9678}', + '\u{FE00}', + '\u{967C}', + '\u{FE00}', + '\u{9686}', + '\u{FE00}', + '\u{96A3}', + '\u{FE00}', + '\u{96B7}', + '\u{FE00}', + '\u{96B8}', + '\u{FE00}', + '\u{96C3}', + '\u{FE00}', + '\u{96E2}', + '\u{FE00}', + '\u{96E3}', + '\u{FE00}', + '\u{96E3}', + '\u{FE01}', + '\u{96F6}', + '\u{FE00}', + '\u{96F7}', + '\u{FE00}', + '\u{9723}', + '\u{FE00}', + '\u{9732}', + '\u{FE00}', + '\u{9748}', + '\u{FE00}', + '\u{9756}', + '\u{FE00}', + '\u{9756}', + '\u{FE01}', + '\u{97DB}', + '\u{FE00}', + '\u{97E0}', + '\u{FE00}', + '\u{97FF}', + '\u{FE00}', + '\u{97FF}', + '\u{FE01}', + '\u{980B}', + '\u{FE00}', + '\u{980B}', + '\u{FE01}', + '\u{980B}', + '\u{FE02}', + '\u{9818}', + '\u{FE00}', + '\u{9829}', + '\u{FE00}', + '\u{983B}', + '\u{FE00}', + '\u{983B}', + '\u{FE01}', + '\u{985E}', + '\u{FE00}', + '\u{98E2}', + '\u{FE00}', + '\u{98EF}', + '\u{FE00}', + '\u{98FC}', + '\u{FE00}', + '\u{9928}', + '\u{FE00}', + '\u{9929}', + '\u{FE00}', + '\u{99A7}', + '\u{FE00}', + '\u{99C2}', + '\u{FE00}', + '\u{99F1}', + '\u{FE00}', + '\u{99FE}', + '\u{FE00}', + '\u{9A6A}', + '\u{FE00}', + '\u{9B12}', + '\u{FE00}', + '\u{9B12}', + '\u{FE01}', + '\u{9B6F}', + '\u{FE00}', + '\u{9C40}', + '\u{FE00}', + '\u{9C57}', + '\u{FE00}', + '\u{9CFD}', + '\u{FE00}', + '\u{9D67}', + '\u{FE00}', + '\u{9DB4}', + '\u{FE00}', + '\u{9DFA}', + '\u{FE00}', + '\u{9E1E}', + '\u{FE00}', + '\u{9E7F}', + '\u{FE00}', + '\u{9E97}', + '\u{FE00}', + '\u{9E9F}', + '\u{FE00}', + '\u{9EBB}', + '\u{FE00}', + '\u{9ECE}', + '\u{FE00}', + '\u{9EF9}', + '\u{FE00}', + '\u{9EFE}', + '\u{FE00}', + '\u{9F05}', + '\u{FE00}', + '\u{9F0F}', + '\u{FE00}', + '\u{9F16}', + '\u{FE00}', + '\u{9F3B}', + '\u{FE00}', + '\u{9F43}', + '\u{FE00}', + '\u{9F8D}', + '\u{FE00}', + '\u{9F8E}', + '\u{FE00}', + '\u{9F9C}', + '\u{FE00}', + '\u{9F9C}', + '\u{FE01}', + '\u{9F9C}', + '\u{FE02}', + '\u{20122}', + '\u{FE00}', + '\u{2051C}', + '\u{FE00}', + '\u{20525}', + '\u{FE00}', + '\u{2054B}', + '\u{FE00}', + '\u{2063A}', + '\u{FE00}', + '\u{20804}', + '\u{FE00}', + '\u{208DE}', + '\u{FE00}', + '\u{20A2C}', + '\u{FE00}', + '\u{20B63}', + '\u{FE00}', + '\u{214E4}', + '\u{FE00}', + '\u{216A8}', + '\u{FE00}', + '\u{216EA}', + '\u{FE00}', + '\u{219C8}', + '\u{FE00}', + '\u{21B18}', + '\u{FE00}', + '\u{21D0B}', + '\u{FE00}', + '\u{21DE4}', + '\u{FE00}', + '\u{21DE6}', + '\u{FE00}', + '\u{22183}', + '\u{FE00}', + '\u{2219F}', + '\u{FE00}', + '\u{22331}', + '\u{FE00}', + '\u{22331}', + '\u{FE01}', + '\u{226D4}', + '\u{FE00}', + '\u{22844}', + '\u{FE00}', + '\u{2284A}', + '\u{FE00}', + '\u{22B0C}', + '\u{FE00}', + '\u{22BF1}', + '\u{FE00}', + '\u{2300A}', + '\u{FE00}', + '\u{232B8}', + '\u{FE00}', + '\u{2335F}', + '\u{FE00}', + '\u{23393}', + '\u{FE00}', + '\u{2339C}', + '\u{FE00}', + '\u{233C3}', + '\u{FE00}', + '\u{233D5}', + '\u{FE00}', + '\u{2346D}', + '\u{FE00}', + '\u{236A3}', + '\u{FE00}', + '\u{238A7}', + '\u{FE00}', + '\u{23A8D}', + '\u{FE00}', + '\u{23AFA}', + '\u{FE00}', + '\u{23CBC}', + '\u{FE00}', + '\u{23D1E}', + '\u{FE00}', + '\u{23ED1}', + '\u{FE00}', + '\u{23F5E}', + '\u{FE00}', + '\u{23F8E}', + '\u{FE00}', + '\u{24263}', + '\u{FE00}', + '\u{242EE}', + '\u{FE00}', + '\u{243AB}', + '\u{FE00}', + '\u{24608}', + '\u{FE00}', + '\u{24735}', + '\u{FE00}', + '\u{24814}', + '\u{FE00}', + '\u{24C36}', + '\u{FE00}', + '\u{24C92}', + '\u{FE00}', + '\u{24FA1}', + '\u{FE00}', + '\u{24FB8}', + '\u{FE00}', + '\u{25044}', + '\u{FE00}', + '\u{250F2}', + '\u{FE00}', + '\u{250F3}', + '\u{FE00}', + '\u{25119}', + '\u{FE00}', + '\u{25133}', + '\u{FE00}', + '\u{25249}', + '\u{FE00}', + '\u{2541D}', + '\u{FE00}', + '\u{25626}', + '\u{FE00}', + '\u{2569A}', + '\u{FE00}', + '\u{256C5}', + '\u{FE00}', + '\u{2597C}', + '\u{FE00}', + '\u{25AA7}', + '\u{FE00}', + '\u{25AA7}', + '\u{FE01}', + '\u{25BAB}', + '\u{FE00}', + '\u{25C80}', + '\u{FE00}', + '\u{25CD0}', + '\u{FE00}', + '\u{25F86}', + '\u{FE00}', + '\u{261DA}', + '\u{FE00}', + '\u{26228}', + '\u{FE00}', + '\u{26247}', + '\u{FE00}', + '\u{262D9}', + '\u{FE00}', + '\u{2633E}', + '\u{FE00}', + '\u{264DA}', + '\u{FE00}', + '\u{26523}', + '\u{FE00}', + '\u{265A8}', + '\u{FE00}', + '\u{267A7}', + '\u{FE00}', + '\u{267B5}', + '\u{FE00}', + '\u{26B3C}', + '\u{FE00}', + '\u{26C36}', + '\u{FE00}', + '\u{26CD5}', + '\u{FE00}', + '\u{26D6B}', + '\u{FE00}', + '\u{26F2C}', + '\u{FE00}', + '\u{26FB1}', + '\u{FE00}', + '\u{270D2}', + '\u{FE00}', + '\u{273CA}', + '\u{FE00}', + '\u{27667}', + '\u{FE00}', + '\u{278AE}', + '\u{FE00}', + '\u{27966}', + '\u{FE00}', + '\u{27CA8}', + '\u{FE00}', + '\u{27ED3}', + '\u{FE00}', + '\u{27F2F}', + '\u{FE00}', + '\u{285D2}', + '\u{FE00}', + '\u{285ED}', + '\u{FE00}', + '\u{2872E}', + '\u{FE00}', + '\u{28BFA}', + '\u{FE00}', + '\u{28D77}', + '\u{FE00}', + '\u{29145}', + '\u{FE00}', + '\u{291DF}', + '\u{FE00}', + '\u{2921A}', + '\u{FE00}', + '\u{2940A}', + '\u{FE00}', + '\u{29496}', + '\u{FE00}', + '\u{295B6}', + '\u{FE00}', + '\u{29B30}', + '\u{FE00}', + '\u{2A0CE}', + '\u{FE00}', + '\u{2A105}', + '\u{FE00}', + '\u{2A20E}', + '\u{FE00}', + '\u{2A291}', + '\u{FE00}', + '\u{2A392}', + '\u{FE00}', + '\u{2A600}', + '\u{FE00}', +]; + +pub(crate) const CJK_COMPAT_VARIANTS_DECOMPOSED_SALT: &[u16] = &[ + 0x005, 0x000, 0x000, 0x000, 0x162, 0x014, 0x0B6, 0x000, 0x183, 0x00D, 0x000, 0x000, 0x035, + 0x011, 0x007, 0x000, 0x01C, 0x000, 0x001, 0x000, 0x0D3, 0x00B, 0x00A, 0x0E1, 0x000, 0x000, + 0x000, 0x048, 0x072, 0x0C7, 0x002, 0x021, 0x015, 0x02C, 0x000, 0x000, 0x000, 0x005, 0x01F, + 0x008, 0x007, 0x000, 0x004, 0x000, 0x007, 0x010, 0x000, 0x000, 0x000, 0x04E, 0x000, 0x006, + 0x000, 0x011, 0x014, 0x004, 0x01A, 0x002, 0x058, 0x000, 0x017, 0x000, 0x000, 0x000, 0x004, + 0x000, 0x001, 0x000, 0x001, 0x000, 0x004, 0x006, 0x016, 0x020, 0x004, 0x000, 0x01E, 0x030, + 0x000, 0x024, 0x01A, 0x017, 0x000, 0x0A0, 0x029, 0x034, 0x002, 0x000, 0x004, 0x000, 0x023, + 0x029, 0x021, 0x000, 0x000, 0x00B, 0x000, 0x020, 0x001, 0x007, 0x008, 0x009, 0x008, 0x000, + 0x001, 0x000, 0x001, 0x004, 0x003, 0x01D, 0x000, 0x000, 0x000, 0x001, 0x029, 0x00D, 0x007, + 0x000, 0x000, 0x002, 0x00E, 0x009, 0x004, 0x00C, 0x001, 0x013, 0x005, 0x006, 0x005, 0x001, + 0x009, 0x001, 0x00A, 0x002, 0x000, 0x008, 0x029, 0x000, 0x008, 0x002, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x00D, 0x000, 0x009, 0x010, 0x00F, 0x000, 0x011, 0x00F, 0x000, + 0x008, 0x001, 0x001, 0x005, 0x000, 0x001, 0x026, 0x005, 0x039, 0x008, 0x001, 0x017, 0x00D, + 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00E, 0x000, 0x005, 0x000, + 0x000, 0x000, 0x000, 0x004, 0x000, 0x001, 0x002, 0x004, 0x003, 0x035, 0x001, 0x002, 0x001, + 0x007, 0x000, 0x000, 0x003, 0x002, 0x011, 0x000, 0x00D, 0x003, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x004, 0x005, 0x000, 0x00E, 0x000, 0x000, 0x003, 0x006, 0x002, + 0x00B, 0x002, 0x001, 0x003, 0x012, 0x00B, 0x000, 0x000, 0x000, 0x002, 0x00B, 0x001, 0x004, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x02F, 0x001, + 0x013, 0x00B, 0x004, 0x002, 0x004, 0x004, 0x000, 0x00B, 0x004, 0x000, 0x00B, 0x004, 0x00D, + 0x00C, 0x000, 0x01E, 0x000, 0x021, 0x00D, 0x002, 0x007, 0x000, 0x000, 0x000, 0x001, 0x002, + 0x000, 0x020, 0x000, 0x000, 0x000, 0x000, 0x000, 0x01F, 0x001, 0x002, 0x000, 0x000, 0x005, + 0x000, 0x000, 0x004, 0x000, 0x011, 0x002, 0x008, 0x007, 0x000, 0x000, 0x00C, 0x003, 0x000, + 0x004, 0x00E, 0x023, 0x004, 0x001, 0x000, 0x002, 0x000, 0x004, 0x008, 0x010, 0x002, 0x000, + 0x013, 0x00D, 0x000, 0x00B, 0x009, 0x006, 0x000, 0x000, 0x009, 0x00C, 0x00A, 0x004, 0x01A, + 0x003, 0x001, 0x003, 0x000, 0x001, 0x000, 0x006, 0x003, 0x00A, 0x000, 0x00A, 0x006, 0x008, + 0x008, 0x003, 0x019, 0x000, 0x000, 0x000, 0x000, 0x00C, 0x005, 0x000, 0x005, 0x001, 0x000, + 0x002, 0x000, 0x008, 0x000, 0x00C, 0x000, 0x002, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, + 0x004, 0x002, 0x015, 0x000, 0x004, 0x001, 0x012, 0x004, 0x003, 0x00C, 0x004, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, 0x005, 0x002, 0x000, 0x001, 0x002, 0x001, + 0x010, 0x004, 0x000, 0x005, 0x002, 0x001, 0x006, 0x000, 0x000, 0x000, 0x000, 0x00A, 0x008, + 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x004, 0x00C, 0x002, + 0x000, 0x006, 0x003, 0x003, 0x00F, 0x000, 0x003, 0x005, 0x001, 0x000, 0x000, 0x008, 0x000, + 0x002, 0x004, 0x002, 0x013, 0x000, 0x000, 0x000, 0x00A, 0x006, 0x001, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x00A, 0x000, 0x005, 0x000, 0x005, 0x000, 0x006, 0x000, 0x001, + 0x001, 0x005, 0x001, 0x00A, 0x009, 0x005, 0x001, 0x000, 0x007, 0x001, 0x001, 0x007, 0x001, + 0x01F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, + 0x011, 0x005, 0x003, 0x005, 0x003, 0x001, 0x001, 0x000, 0x004, 0x001, 0x004, 0x001, 0x008, + 0x000, 0x019, 0x000, 0x004, 0x003, 0x005, 0x006, 0x000, 0x011, 0x00E, 0x005, 0x001, 0x000, + 0x01A, 0x004, 0x000, 0x003, 0x000, 0x000, 0x005, 0x000, 0x000, 0x001, 0x017, 0x000, 0x006, + 0x003, 0x00F, 0x001, 0x006, 0x009, 0x000, 0x005, 0x000, 0x003, 0x001, 0x017, 0x007, 0x000, + 0x002, 0x005, 0x003, 0x002, 0x000, 0x007, 0x001, 0x000, 0x004, 0x000, 0x000, 0x005, 0x015, + 0x004, 0x000, 0x003, 0x001, 0x003, 0x007, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, + 0x009, 0x000, 0x000, 0x000, 0x000, 0x000, 0x009, 0x000, 0x000, 0x000, 0x001, 0x003, 0x000, + 0x000, 0x003, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x003, 0x008, 0x000, + 0x002, 0x002, 0x003, 0x005, 0x000, 0x000, 0x000, 0x008, 0x003, 0x002, 0x000, 0x009, 0x004, + 0x000, 0x006, 0x00F, 0x001, 0x000, 0x000, 0x004, 0x002, 0x002, 0x004, 0x004, 0x00D, 0x000, + 0x000, 0x000, 0x001, 0x000, 0x002, 0x005, 0x000, 0x000, 0x00C, 0x004, 0x009, 0x002, 0x008, + 0x001, 0x000, 0x005, 0x004, 0x001, 0x002, 0x001, 0x005, 0x002, 0x00B, 0x004, 0x00D, 0x004, + 0x000, 0x001, 0x018, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x003, + 0x000, 0x002, 0x00A, 0x002, 0x004, 0x004, 0x000, 0x000, 0x000, 0x001, 0x000, 0x00C, 0x001, + 0x00C, 0x001, 0x009, 0x00B, 0x000, 0x001, 0x000, 0x002, 0x000, 0x005, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x007, 0x002, 0x000, 0x006, 0x004, 0x00A, 0x001, 0x001, + 0x005, 0x002, 0x006, 0x004, 0x003, 0x00D, 0x002, 0x002, 0x000, 0x001, 0x002, 0x003, 0x002, + 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x001, + 0x000, 0x000, 0x003, 0x002, 0x000, 0x005, 0x002, 0x005, 0x002, 0x001, 0x004, 0x001, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x007, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x002, 0x000, 0x000, 0x004, 0x008, 0x000, + 0x003, 0x002, 0x002, 0x002, 0x002, 0x004, 0x001, 0x004, 0x002, 0x000, 0x001, 0x004, 0x001, + 0x001, 0x002, 0x000, 0x000, 0x00C, 0x000, 0x001, 0x002, 0x000, 0x006, 0x002, 0x000, 0x000, + 0x008, 0x001, 0x009, 0x001, 0x003, 0x000, 0x004, 0x001, 0x000, 0x006, 0x000, 0x003, 0x007, + 0x000, 0x000, 0x002, 0x001, 0x000, 0x003, 0x002, 0x000, 0x002, 0x007, 0x000, 0x000, 0x000, + 0x000, 0x005, 0x003, 0x001, 0x003, 0x000, 0x005, 0x000, 0x001, 0x000, 0x003, 0x001, 0x001, + 0x002, 0x003, 0x000, 0x002, 0x003, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x001, + 0x000, 0x004, 0x003, 0x002, 0x004, 0x003, 0x005, 0x002, 0x000, 0x000, 0x001, 0x003, 0x002, + 0x000, 0x000, 0x004, 0x003, 0x000, 0x001, 0x006, 0x001, 0x004, 0x000, 0x002, 0x002, 0x001, + 0x000, 0x00D, 0x001, 0x000, 0x000, 0x001, 0x000, 0x002, 0x003, 0x008, 0x005, 0x007, 0x006, + 0x000, 0x001, 0x006, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x002, 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x002, 0x004, 0x002, 0x001, 0x001, + 0x002, 0x000, 0x000, 0x000, 0x001, 0x005, 0x001, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x004, 0x000, 0x002, 0x000, 0x001, 0x003, + 0x003, 0x001, 0x000, 0x004, 0x000, 0x001, 0x001, 0x001, 0x001, 0x001, 0x004, 0x000, 0x000, + 0x003, 0x001, 0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, + 0x000, 0x000, 0x001, 0x003, 0x002, 0x001, 0x002, 0x001, 0x009, 0x001, 0x000, 0x001, 0x003, + 0x004, 0x000, 0x000, 0x000, 0x002, 0x000, 0x003, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x004, 0x001, 0x001, 0x001, 0x002, + 0x001, 0x006, 0x001, 0x001, 0x002, 0x001, 0x000, 0x000, 0x000, 0x003, 0x001, 0x000, 0x005, + 0x001, +]; +pub(crate) const CJK_COMPAT_VARIANTS_DECOMPOSED_KV: &[(u32, (u16, u16))] = &[ + (0x0FA08, (0x5A8, 0x2)), + (0x2F825, (0x118, 0x2)), + (0x2F838, (0x704, 0x2)), + (0x2F95B, (0x4A8, 0x2)), + (0x2F8FB, (0x740, 0x2)), + (0x2F83A, (0x154, 0x2)), + (0x2F8A7, (0x27C, 0x2)), + (0x2F856, (0x1A6, 0x2)), + (0x2F810, (0x0D0, 0x2)), + (0x0FA8B, (0x29C, 0x2)), + (0x0FA7A, (0x17A, 0x2)), + (0x2F9EF, (0x076, 0x2)), + (0x2F959, (0x4A4, 0x2)), + (0x0F9C8, (0x324, 0x2)), + (0x0F9C4, (0x6EA, 0x2)), + (0x2F833, (0x148, 0x2)), + (0x0F96C, (0x1AE, 0x2)), + (0x0F9A1, (0x5CE, 0x2)), + (0x0F906, (0x150, 0x2)), + (0x2FA01, (0x7C4, 0x2)), + (0x0F94C, (0x34C, 0x2)), + (0x0F90F, (0x4FA, 0x2)), + (0x2F8DD, (0x732, 0x2)), + (0x0FA55, (0x4AA, 0x2)), + (0x2F860, (0x708, 0x2)), + (0x2F999, (0x546, 0x2)), + (0x0FABC, (0x5E6, 0x2)), + (0x2F9B9, (0x594, 0x2)), + (0x0F943, (0x246, 0x2)), + (0x2F952, (0x76C, 0x2)), + (0x2F8F1, (0x358, 0x2)), + (0x0F99C, (0x100, 0x2)), + (0x0F969, (0x2EC, 0x2)), + (0x0F98D, (0x620, 0x2)), + (0x0FA7F, (0x1CC, 0x2)), + (0x2F9D6, (0x606, 0x2)), + (0x2F81B, (0x0EC, 0x2)), + (0x0FA9D, (0x466, 0x2)), + (0x2F8E4, (0x33A, 0x2)), + (0x0FA94, (0x320, 0x2)), + (0x2F890, (0x244, 0x2)), + (0x0F93D, (0x4DC, 0x2)), + (0x2F924, (0x3F8, 0x2)), + (0x2F983, (0x51C, 0x2)), + (0x0FA2F, (0x678, 0x2)), + (0x2F891, (0x71A, 0x2)), + (0x2F934, (0x430, 0x2)), + (0x2F835, (0x3CC, 0x2)), + (0x2F899, (0x24E, 0x2)), + (0x2F8AE, (0x294, 0x2)), + (0x0F9D6, (0x39A, 0x2)), + (0x2F9A0, (0x54E, 0x2)), + (0x0FAC2, (0x61A, 0x2)), + (0x2F851, (0x1BA, 0x2)), + (0x2F804, (0x0A6, 0x2)), + (0x2F90D, (0x744, 0x2)), + (0x0F95E, (0x094, 0x2)), + (0x2F8DA, (0x31A, 0x2)), + (0x2F885, (0x226, 0x2)), + (0x2F96A, (0x4D0, 0x2)), + (0x0F907, (0x6EE, 0x2)), + (0x0F9F9, (0x4C2, 0x2)), + (0x0F94B, (0x202, 0x2)), + (0x2F915, (0x3C2, 0x2)), + (0x0F9F1, (0x676, 0x2)), + (0x2F86D, (0x1EA, 0x2)), + (0x2F921, (0x3F2, 0x2)), + (0x0FA96, (0x366, 0x2)), + (0x0F9E0, (0x2F6, 0x2)), + (0x0F921, (0x214, 0x2)), + (0x2F99F, (0x56A, 0x2)), + (0x2F8B2, (0x2A6, 0x2)), + (0x0FAB1, (0x4F2, 0x2)), + (0x0FA6C, (0x74C, 0x2)), + (0x2F819, (0x0A2, 0x2)), + (0x2F910, (0x746, 0x2)), + (0x2F8DC, (0x31E, 0x2)), + (0x2F9D3, (0x7AA, 0x2)), + (0x2F8A3, (0x26E, 0x2)), + (0x0F915, (0x37C, 0x2)), + (0x2F88A, (0x014, 0x2)), + (0x0F9F6, (0x522, 0x2)), + (0x2F9F1, (0x7B8, 0x2)), + (0x0F98E, (0x22C, 0x2)), + (0x0FAD5, (0x768, 0x2)), + (0x0F93B, (0x46C, 0x2)), + (0x2F91E, (0x3E2, 0x2)), + (0x0F9EB, (0x134, 0x2)), + (0x0FA42, (0x2F2, 0x2)), + (0x2F958, (0x04E, 0x2)), + (0x0FA19, (0x48C, 0x2)), + (0x0FAAA, (0x45E, 0x2)), + (0x2F949, (0x046, 0x2)), + (0x2F978, (0x4FC, 0x2)), + (0x2F8A9, (0x27E, 0x2)), + (0x2F90A, (0x032, 0x2)), + (0x2F89A, (0x252, 0x2)), + (0x2F8B5, (0x2B0, 0x2)), + (0x2F94C, (0x04A, 0x2)), + (0x0FA43, (0x300, 0x2)), + (0x0F997, (0x510, 0x2)), + (0x2F8BA, (0x2BA, 0x2)), + (0x0FA00, (0x0FC, 0x2)), + (0x0FAC3, (0x62E, 0x2)), + (0x2F948, (0x462, 0x2)), + (0x2F9F4, (0x21C, 0x2)), + (0x0FA99, (0x3AA, 0x2)), + (0x2F976, (0x4F8, 0x2)), + (0x0F978, (0x0D6, 0x2)), + (0x2F8FE, (0x36E, 0x2)), + (0x2F8E3, (0x736, 0x2)), + (0x0F919, (0x642, 0x2)), + (0x2F8EF, (0x356, 0x2)), + (0x0F939, (0x6C2, 0x2)), + (0x2F8C9, (0x2EA, 0x2)), + (0x2F844, (0x172, 0x2)), + (0x0FABB, (0x5D2, 0x2)), + (0x2F9C4, (0x5AC, 0x2)), + (0x2F984, (0x060, 0x2)), + (0x2F802, (0x098, 0x2)), + (0x0FA15, (0x0F6, 0x2)), + (0x0F9BE, (0x2EE, 0x2)), + (0x0F942, (0x1B8, 0x2)), + (0x2F852, (0x19E, 0x2)), + (0x0FAAE, (0x4C0, 0x2)), + (0x2FA17, (0x6DC, 0x2)), + (0x2F92D, (0x03A, 0x2)), + (0x2F83F, (0x162, 0x2)), + (0x0F90C, (0x1C8, 0x2)), + (0x0F931, (0x350, 0x2)), + (0x0F9C1, (0x446, 0x2)), + (0x2F873, (0x1FA, 0x2)), + (0x2F965, (0x77A, 0x2)), + (0x0F902, (0x612, 0x2)), + (0x2F805, (0x0B0, 0x2)), + (0x2F8CA, (0x728, 0x2)), + (0x0F9C7, (0x10E, 0x2)), + (0x2F8F4, (0x360, 0x2)), + (0x0FA0D, (0x186, 0x2)), + (0x0FA5C, (0x524, 0x2)), + (0x0FA4C, (0x47E, 0x2)), + (0x2F865, (0x1D2, 0x2)), + (0x2F876, (0x00E, 0x2)), + (0x2F9D7, (0x608, 0x2)), + (0x0F975, (0x2C8, 0x2)), + (0x2F9BB, (0x59C, 0x2)), + (0x2F9D2, (0x5F6, 0x2)), + (0x0F9ED, (0x15A, 0x2)), + (0x2F9B4, (0x588, 0x2)), + (0x0FA6D, (0x52C, 0x2)), + (0x0F9E5, (0x43E, 0x2)), + (0x2F8D8, (0x314, 0x2)), + (0x2F93D, (0x75E, 0x2)), + (0x0FA03, (0x4C8, 0x2)), + (0x0F9A0, (0x5AE, 0x2)), + (0x2FA12, (0x7CA, 0x2)), + (0x0FA63, (0x5E8, 0x2)), + (0x0F920, (0x6D0, 0x2)), + (0x0F91F, (0x580, 0x2)), + (0x2F97D, (0x50E, 0x2)), + (0x0F990, (0x2A4, 0x2)), + (0x0FA57, (0x4E4, 0x2)), + (0x2F975, (0x786, 0x2)), + (0x0FAD8, (0x6E8, 0x2)), + (0x0FAB3, (0x54C, 0x2)), + (0x2F9F3, (0x67C, 0x2)), + (0x0F9FB, (0x3D2, 0x2)), + (0x0F918, (0x564, 0x2)), + (0x2F8C3, (0x2D8, 0x2)), + (0x0F9CA, (0x384, 0x2)), + (0x0F952, (0x11E, 0x2)), + (0x2FA0B, (0x6C4, 0x2)), + (0x2F941, (0x762, 0x2)), + (0x2F862, (0x1D4, 0x2)), + (0x2F8FF, (0x37A, 0x2)), + (0x2F85D, (0x1C2, 0x2)), + (0x0F9D9, (0x278, 0x2)), + (0x2F855, (0x19C, 0x2)), + (0x2F98F, (0x536, 0x2)), + (0x0F9D4, (0x0B8, 0x2)), + (0x0F99E, (0x168, 0x2)), + (0x2F850, (0x0FE, 0x2)), + (0x0FA22, (0x5DC, 0x2)), + (0x2F94F, (0x46E, 0x2)), + (0x0FAA9, (0x460, 0x2)), + (0x0FA71, (0x0EA, 0x2)), + (0x0F95D, (0x5E0, 0x2)), + (0x2F8BD, (0x2D0, 0x2)), + (0x2FA02, (0x6AA, 0x2)), + (0x2F93F, (0x040, 0x2)), + (0x2F808, (0x0BA, 0x2)), + (0x2F950, (0x476, 0x2)), + (0x2F933, (0x03C, 0x2)), + (0x2F853, (0x1A0, 0x2)), + (0x2F8F0, (0x73A, 0x2)), + (0x0F967, (0x08C, 0x2)), + (0x0FA16, (0x402, 0x2)), + (0x0FAA6, (0x44C, 0x2)), + (0x2F8B3, (0x2A8, 0x2)), + (0x2F9F7, (0x7BE, 0x2)), + (0x0F986, (0x664, 0x2)), + (0x2F99D, (0x554, 0x2)), + (0x2F9B8, (0x58E, 0x2)), + (0x0F998, (0x616, 0x2)), + (0x2F82B, (0x132, 0x2)), + (0x2F872, (0x1F8, 0x2)), + (0x0FAB9, (0x5D0, 0x2)), + (0x0FA9B, (0x3C4, 0x2)), + (0x0F9B0, (0x50C, 0x2)), + (0x0F98B, (0x308, 0x2)), + (0x0FAD1, (0x734, 0x2)), + (0x0F917, (0x414, 0x2)), + (0x2F989, (0x72E, 0x2)), + (0x2F866, (0x1DC, 0x2)), + (0x0F932, (0x3E8, 0x2)), + (0x2FA0E, (0x086, 0x2)), + (0x0FA07, (0x61E, 0x2)), + (0x0F9BD, (0x1FE, 0x2)), + (0x2F88C, (0x232, 0x2)), + (0x0FA56, (0x4B4, 0x2)), + (0x0FA64, (0x600, 0x2)), + (0x0FA04, (0x1E8, 0x2)), + (0x0FA9E, (0x3F0, 0x2)), + (0x2F9E0, (0x7B0, 0x2)), + (0x2F89D, (0x25C, 0x2)), + (0x2F9EE, (0x662, 0x2)), + (0x0F9DB, (0x40C, 0x2)), + (0x0F923, (0x578, 0x2)), + (0x2F841, (0x16A, 0x2)), + (0x2F81A, (0x0E8, 0x2)), + (0x0F911, (0x5A0, 0x2)), + (0x0FAAD, (0x4B6, 0x2)), + (0x0FAC1, (0x604, 0x2)), + (0x2F928, (0x408, 0x2)), + (0x2F935, (0x756, 0x2)), + (0x2F8D5, (0x304, 0x2)), + (0x0F92E, (0x0EE, 0x2)), + (0x0FA59, (0x4EE, 0x2)), + (0x2F96B, (0x77E, 0x2)), + (0x2F8B9, (0x2BE, 0x2)), + (0x2F877, (0x200, 0x2)), + (0x2FA00, (0x6A2, 0x2)), + (0x0FA05, (0x37E, 0x2)), + (0x0F9E8, (0x5B6, 0x2)), + (0x2F8C6, (0x2DA, 0x2)), + (0x0F97A, (0x334, 0x2)), + (0x2F9EA, (0x654, 0x2)), + (0x0F944, (0x4BE, 0x2)), + (0x2F8C4, (0x2DC, 0x2)), + (0x2F9CD, (0x072, 0x2)), + (0x2F8E5, (0x330, 0x2)), + (0x2F9D9, (0x6FE, 0x2)), + (0x2F980, (0x72C, 0x2)), + (0x2F9A8, (0x56E, 0x2)), + (0x2F92F, (0x41E, 0x2)), + (0x2F951, (0x04C, 0x2)), + (0x2F9F9, (0x07C, 0x2)), + (0x0FAB4, (0x560, 0x2)), + (0x0F985, (0x47A, 0x2)), + (0x2F829, (0x12C, 0x2)), + (0x2F8A2, (0x01A, 0x2)), + (0x2F9C3, (0x5AA, 0x2)), + (0x2F936, (0x434, 0x2)), + (0x2F9AF, (0x068, 0x2)), + (0x0FA77, (0x128, 0x2)), + (0x0F956, (0x4A0, 0x2)), + (0x0FA5F, (0x568, 0x2)), + (0x2F93B, (0x75A, 0x2)), + (0x0F914, (0x346, 0x2)), + (0x2F994, (0x53C, 0x2)), + (0x2F91B, (0x6F8, 0x2)), + (0x2F880, (0x21A, 0x2)), + (0x2F956, (0x498, 0x2)), + (0x0F958, (0x562, 0x2)), + (0x2F99B, (0x552, 0x2)), + (0x2FA06, (0x6B6, 0x2)), + (0x0FABF, (0x5EA, 0x2)), + (0x2F8B6, (0x2B8, 0x2)), + (0x2F8A0, (0x26A, 0x2)), + (0x0FA87, (0x280, 0x2)), + (0x2F8EA, (0x344, 0x2)), + (0x2F867, (0x00A, 0x2)), + (0x0F97D, (0x5D4, 0x2)), + (0x0F968, (0x374, 0x2)), + (0x0FA5A, (0x4F4, 0x2)), + (0x0F97B, (0x4CC, 0x2)), + (0x2FA10, (0x7C8, 0x2)), + (0x0FA2B, (0x6AE, 0x2)), + (0x0FA75, (0x0DC, 0x2)), + (0x0F94D, (0x398, 0x2)), + (0x0FAD4, (0x044, 0x2)), + (0x2F8CC, (0x30C, 0x2)), + (0x0FA8A, (0x284, 0x2)), + (0x0F9F4, (0x328, 0x2)), + (0x0FAC6, (0x672, 0x2)), + (0x0FA9C, (0x3E0, 0x2)), + (0x0FA10, (0x1AA, 0x2)), + (0x0F9E2, (0x33C, 0x2)), + (0x0F947, (0x472, 0x2)), + (0x0F941, (0x5D6, 0x2)), + (0x0FA4E, (0x480, 0x2)), + (0x2F9DA, (0x60C, 0x2)), + (0x2F893, (0x526, 0x2)), + (0x0F96F, (0x5CC, 0x2)), + (0x0F983, (0x2F0, 0x2)), + (0x0F9F5, (0x396, 0x2)), + (0x0F962, (0x43A, 0x2)), + (0x2F968, (0x4CE, 0x2)), + (0x2F923, (0x750, 0x2)), + (0x2FA18, (0x6DE, 0x2)), + (0x2F930, (0x424, 0x2)), + (0x0FA90, (0x2E8, 0x2)), + (0x0FA54, (0x4A2, 0x2)), + (0x0F9D8, (0x254, 0x2)), + (0x2F9E4, (0x63E, 0x2)), + (0x2FA05, (0x6B4, 0x2)), + (0x2F964, (0x052, 0x2)), + (0x0F99F, (0x3D6, 0x2)), + (0x2F94B, (0x048, 0x2)), + (0x2F9A9, (0x570, 0x2)), + (0x0FA0C, (0x0C6, 0x2)), + (0x2F986, (0x1DE, 0x2)), + (0x0FA85, (0x25A, 0x2)), + (0x2F95F, (0x4B0, 0x2)), + (0x0F9F8, (0x4B2, 0x2)), + (0x0F9B4, (0x6A0, 0x2)), + (0x2F82E, (0x13C, 0x2)), + (0x0FAD9, (0x6EC, 0x2)), + (0x2F937, (0x758, 0x2)), + (0x0F9CF, (0x4D2, 0x2)), + (0x0FAA1, (0x422, 0x2)), + (0x2F917, (0x3CA, 0x2)), + (0x0FAA5, (0x444, 0x2)), + (0x0FA3B, (0x204, 0x2)), + (0x2F88D, (0x234, 0x2)), + (0x2F906, (0x742, 0x2)), + (0x2F901, (0x390, 0x2)), + (0x2F97A, (0x50A, 0x2)), + (0x0FA60, (0x5BC, 0x2)), + (0x2F92C, (0x038, 0x2)), + (0x2F80A, (0x0C4, 0x2)), + (0x2F99A, (0x550, 0x2)), + (0x2FA13, (0x7CC, 0x2)), + (0x2F938, (0x43C, 0x2)), + (0x2F813, (0x002, 0x2)), + (0x2F831, (0x144, 0x2)), + (0x0FA1C, (0x68E, 0x2)), + (0x0FACC, (0x6A6, 0x2)), + (0x0FA5E, (0x532, 0x2)), + (0x2F995, (0x53E, 0x2)), + (0x2F8D3, (0x0E2, 0x2)), + (0x0FACD, (0x6BE, 0x2)), + (0x2F81D, (0x0F8, 0x2)), + (0x2F97B, (0x78A, 0x2)), + (0x0FA3A, (0x1B0, 0x2)), + (0x0F9C6, (0x668, 0x2)), + (0x0FABD, (0x5E2, 0x2)), + (0x0F92D, (0x0AA, 0x2)), + (0x0F99B, (0x65C, 0x2)), + (0x0F91D, (0x354, 0x2)), + (0x2F84D, (0x19A, 0x2)), + (0x2F8AD, (0x292, 0x2)), + (0x0F9D3, (0x670, 0x2)), + (0x2F843, (0x16E, 0x2)), + (0x0F97C, (0x52E, 0x2)), + (0x0FA30, (0x0AE, 0x2)), + (0x2F858, (0x1B2, 0x2)), + (0x2F8A5, (0x270, 0x2)), + (0x2F988, (0x792, 0x2)), + (0x2F9E1, (0x7B2, 0x2)), + (0x0FA74, (0x0C8, 0x2)), + (0x2F882, (0x222, 0x2)), + (0x2F879, (0x20E, 0x2)), + (0x2F8B7, (0x2C0, 0x2)), + (0x0F940, (0x6D2, 0x2)), + (0x2F9E5, (0x7B4, 0x2)), + (0x2F9CF, (0x5CA, 0x2)), + (0x0FA8E, (0x2D2, 0x2)), + (0x2F90C, (0x3A8, 0x2)), + (0x2F985, (0x51E, 0x2)), + (0x2F849, (0x184, 0x2)), + (0x2F960, (0x050, 0x2)), + (0x2F8C2, (0x01E, 0x2)), + (0x2F85F, (0x1CE, 0x2)), + (0x2F916, (0x034, 0x2)), + (0x0F9FA, (0x3FE, 0x2)), + (0x2F824, (0x008, 0x2)), + (0x0F936, (0x586, 0x2)), + (0x2F94A, (0x464, 0x2)), + (0x2F80E, (0x0CC, 0x2)), + (0x2F913, (0x3C8, 0x2)), + (0x2F94D, (0x76A, 0x2)), + (0x0F999, (0x56C, 0x2)), + (0x2F979, (0x502, 0x2)), + (0x2F926, (0x752, 0x2)), + (0x0F9EA, (0x67E, 0x2)), + (0x0FA3F, (0x28A, 0x2)), + (0x2F83B, (0x156, 0x2)), + (0x0FA5B, (0x506, 0x2)), + (0x0FA93, (0x316, 0x2)), + (0x0F913, (0x632, 0x2)), + (0x0F98C, (0x35C, 0x2)), + (0x2F8C0, (0x2CE, 0x2)), + (0x0FAD7, (0x7AC, 0x2)), + (0x0F98A, (0x110, 0x2)), + (0x0FA26, (0x63C, 0x2)), + (0x0FABE, (0x5D8, 0x2)), + (0x2F977, (0x788, 0x2)), + (0x0F954, (0x0F4, 0x2)), + (0x0F91A, (0x6B8, 0x2)), + (0x2F8CD, (0x2F8, 0x2)), + (0x2F8A4, (0x71E, 0x2)), + (0x0FA84, (0x250, 0x2)), + (0x2F85E, (0x1C4, 0x2)), + (0x0FA9F, (0x3FC, 0x2)), + (0x0F9B1, (0x64E, 0x2)), + (0x2F9CA, (0x004, 0x2)), + (0x0FAC4, (0x644, 0x2)), + (0x0F927, (0x5A6, 0x2)), + (0x0FA01, (0x22E, 0x2)), + (0x0F929, (0x310, 0x2)), + (0x0F9F3, (0x6D6, 0x2)), + (0x2F9E6, (0x640, 0x2)), + (0x0FA70, (0x08E, 0x2)), + (0x2F820, (0x106, 0x2)), + (0x0F9A9, (0x196, 0x2)), + (0x2F9BF, (0x06C, 0x2)), + (0x2F922, (0x3F4, 0x2)), + (0x2F9DE, (0x614, 0x2)), + (0x2F8EC, (0x738, 0x2)), + (0x0F9B5, (0x0AC, 0x2)), + (0x2F9B7, (0x590, 0x2)), + (0x2F981, (0x05C, 0x2)), + (0x0FA31, (0x0C2, 0x2)), + (0x2F9C1, (0x5A4, 0x2)), + (0x2F874, (0x24C, 0x2)), + (0x0F9D0, (0x6A8, 0x2)), + (0x0F94A, (0x1B6, 0x2)), + (0x2F998, (0x542, 0x2)), + (0x2F91C, (0x3DA, 0x2)), + (0x2F9DF, (0x61C, 0x2)), + (0x2F859, (0x706, 0x2)), + (0x2F883, (0x010, 0x2)), + (0x0F9CC, (0x418, 0x2)), + (0x2F9B5, (0x58A, 0x2)), + (0x2F970, (0x4F0, 0x2)), + (0x2F814, (0x0D2, 0x2)), + (0x2F9FF, (0x69E, 0x2)), + (0x2F84C, (0x18E, 0x2)), + (0x2F9A4, (0x796, 0x2)), + (0x2F966, (0x4C6, 0x2)), + (0x0FA1E, (0x500, 0x2)), + (0x2FA0C, (0x6C8, 0x2)), + (0x2F863, (0x1D6, 0x2)), + (0x0FAA2, (0x42E, 0x2)), + (0x2F91A, (0x3D4, 0x2)), + (0x2F8F8, (0x710, 0x2)), + (0x2F8A6, (0x27A, 0x2)), + (0x2F895, (0x24A, 0x2)), + (0x0F90B, (0x178, 0x2)), + (0x2F993, (0x53A, 0x2)), + (0x2F8BE, (0x726, 0x2)), + (0x0F948, (0x5FC, 0x2)), + (0x2F80D, (0x6FC, 0x2)), + (0x2F81F, (0x006, 0x2)), + (0x0F9E4, (0x416, 0x2)), + (0x2F823, (0x10C, 0x2)), + (0x2F9FA, (0x694, 0x2)), + (0x2F8FA, (0x36C, 0x2)), + (0x0FA6A, (0x6A4, 0x2)), + (0x2F9F0, (0x666, 0x2)), + (0x2F967, (0x054, 0x2)), + (0x0FA8F, (0x2D6, 0x2)), + (0x0FA06, (0x306, 0x2)), + (0x0F982, (0x242, 0x2)), + (0x0F989, (0x6DA, 0x2)), + (0x2F990, (0x534, 0x2)), + (0x0FAC9, (0x692, 0x2)), + (0x2F8ED, (0x352, 0x2)), + (0x2F822, (0x10A, 0x2)), + (0x0F9CB, (0x3A4, 0x2)), + (0x0FA4D, (0x482, 0x2)), + (0x2F944, (0x766, 0x2)), + (0x2F9E8, (0x656, 0x2)), + (0x2F8D2, (0x0E0, 0x2)), + (0x2F97C, (0x78C, 0x2)), + (0x0FA68, (0x680, 0x2)), + (0x0FA53, (0x494, 0x2)), + (0x2F8F5, (0x368, 0x2)), + (0x2F945, (0x458, 0x2)), + (0x0FA95, (0x35E, 0x2)), + (0x0FA2E, (0x638, 0x2)), + (0x0F91B, (0x09A, 0x2)), + (0x2F837, (0x14E, 0x2)), + (0x2F894, (0x248, 0x2)), + (0x2FA09, (0x7C6, 0x2)), + (0x2F974, (0x05A, 0x2)), + (0x0F9BA, (0x09C, 0x2)), + (0x2F80B, (0x0BE, 0x2)), + (0x0FACA, (0x698, 0x2)), + (0x2F969, (0x4CA, 0x2)), + (0x2F8B1, (0x2A2, 0x2)), + (0x2F8D1, (0x022, 0x2)), + (0x2F91D, (0x74A, 0x2)), + (0x2F9D4, (0x5F8, 0x2)), + (0x2FA15, (0x6D8, 0x2)), + (0x2F954, (0x76E, 0x2)), + (0x0FA81, (0x1E2, 0x2)), + (0x2F9A5, (0x79A, 0x2)), + (0x2F90F, (0x3BA, 0x2)), + (0x0F92A, (0x38C, 0x2)), + (0x2FA19, (0x6E0, 0x2)), + (0x2F943, (0x764, 0x2)), + (0x2F947, (0x45C, 0x2)), + (0x2FA0A, (0x6C0, 0x2)), + (0x2F963, (0x4BA, 0x2)), + (0x0F9BB, (0x0C0, 0x2)), + (0x2F8AC, (0x296, 0x2)), + (0x0F9C5, (0x2FE, 0x2)), + (0x2F97E, (0x78E, 0x2)), + (0x2F889, (0x716, 0x2)), + (0x2F8E9, (0x342, 0x2)), + (0x0F9DA, (0x32E, 0x2)), + (0x0FACE, (0x6F2, 0x2)), + (0x2F920, (0x3EC, 0x2)), + (0x0F951, (0x66A, 0x2)), + (0x0F9BC, (0x1F4, 0x2)), + (0x2F940, (0x454, 0x2)), + (0x2F84E, (0x190, 0x2)), + (0x0FA48, (0x3DE, 0x2)), + (0x2FA08, (0x082, 0x2)), + (0x0F9E6, (0x4F6, 0x2)), + (0x2F8C8, (0x2E6, 0x2)), + (0x0F912, (0x5B8, 0x2)), + (0x2F8F7, (0x73C, 0x2)), + (0x2F904, (0x392, 0x2)), + (0x0FA76, (0x116, 0x2)), + (0x2F8E8, (0x340, 0x2)), + (0x2F9E2, (0x634, 0x2)), + (0x0F903, (0x5FE, 0x2)), + (0x0FA9A, (0x3B6, 0x2)), + (0x0F996, (0x4E2, 0x2)), + (0x2F8DB, (0x322, 0x2)), + (0x0FA4A, (0x41A, 0x2)), + (0x0FA6B, (0x268, 0x2)), + (0x2F8FD, (0x376, 0x2)), + (0x0FA79, (0x170, 0x2)), + (0x0F987, (0x6BC, 0x2)), + (0x2F8F2, (0x030, 0x2)), + (0x0F90D, (0x2A0, 0x2)), + (0x0F922, (0x3BE, 0x2)), + (0x0FA88, (0x276, 0x2)), + (0x0F91C, (0x140, 0x2)), + (0x2F870, (0x1F6, 0x2)), + (0x2F9AC, (0x576, 0x2)), + (0x2F839, (0x152, 0x2)), + (0x2FA03, (0x080, 0x2)), + (0x2F854, (0x1A2, 0x2)), + (0x2F92A, (0x036, 0x2)), + (0x0FA35, (0x138, 0x2)), + (0x2F9E7, (0x650, 0x2)), + (0x2F9A6, (0x798, 0x2)), + (0x0FAAF, (0x4D8, 0x2)), + (0x2F911, (0x748, 0x2)), + (0x2F95D, (0x774, 0x2)), + (0x2F89C, (0x256, 0x2)), + (0x0FA45, (0x38E, 0x2)), + (0x0FA1B, (0x496, 0x2)), + (0x0FA3D, (0x26C, 0x2)), + (0x0F980, (0x15E, 0x2)), + (0x0FA8C, (0x2AC, 0x2)), + (0x2F9E9, (0x658, 0x2)), + (0x2F9F8, (0x07A, 0x2)), + (0x2F902, (0x388, 0x2)), + (0x2FA1D, (0x7D2, 0x2)), + (0x0FAB6, (0x5BE, 0x2)), + (0x0F995, (0x49C, 0x2)), + (0x2F832, (0x146, 0x2)), + (0x2F955, (0x770, 0x2)), + (0x2F8FC, (0x372, 0x2)), + (0x2F875, (0x1FC, 0x2)), + (0x2F82A, (0x12E, 0x2)), + (0x2F811, (0x0DA, 0x2)), + (0x2F868, (0x00C, 0x2)), + (0x2F925, (0x3FA, 0x2)), + (0x0FA20, (0x57E, 0x2)), + (0x2F83E, (0x160, 0x2)), + (0x0F9AF, (0x4FE, 0x2)), + (0x2F997, (0x794, 0x2)), + (0x2F9EC, (0x660, 0x2)), + (0x0F9AB, (0x21E, 0x2)), + (0x0F935, (0x57C, 0x2)), + (0x0FA80, (0x1DA, 0x2)), + (0x2F95C, (0x772, 0x2)), + (0x0FA92, (0x312, 0x2)), + (0x0F95B, (0x2B4, 0x2)), + (0x0F93E, (0x556, 0x2)), + (0x0F9DE, (0x158, 0x2)), + (0x0F9F0, (0x57A, 0x2)), + (0x2F847, (0x17C, 0x2)), + (0x0FA98, (0x3B0, 0x2)), + (0x0F90E, (0x448, 0x2)), + (0x0FA4F, (0x484, 0x2)), + (0x0FAA4, (0x442, 0x2)), + (0x2F9C0, (0x5A2, 0x2)), + (0x2F8BF, (0x2D4, 0x2)), + (0x0FA62, (0x5E4, 0x2)), + (0x0F9B6, (0x49A, 0x2)), + (0x2F826, (0x11C, 0x2)), + (0x0F9C9, (0x32A, 0x2)), + (0x2F992, (0x114, 0x2)), + (0x2F8E1, (0x332, 0x2)), + (0x0F959, (0x66E, 0x2)), + (0x2F892, (0x71C, 0x2)), + (0x0FA18, (0x47C, 0x2)), + (0x2F87D, (0x714, 0x2)), + (0x0F970, (0x364, 0x2)), + (0x2F92B, (0x410, 0x2)), + (0x2FA04, (0x6B2, 0x2)), + (0x0FA89, (0x28C, 0x2)), + (0x2F9E3, (0x63A, 0x2)), + (0x2F9C2, (0x06E, 0x2)), + (0x0FACB, (0x69A, 0x2)), + (0x2F9C8, (0x070, 0x2)), + (0x2F908, (0x3A0, 0x2)), + (0x2F86F, (0x1F2, 0x2)), + (0x2F98A, (0x730, 0x2)), + (0x0F9A8, (0x0A4, 0x2)), + (0x2F8C7, (0x020, 0x2)), + (0x2FA16, (0x08A, 0x2)), + (0x0FA4B, (0x470, 0x2)), + (0x2F878, (0x20A, 0x2)), + (0x2F8BB, (0x2C2, 0x2)), + (0x2F816, (0x6FA, 0x2)), + (0x2F86A, (0x1E4, 0x2)), + (0x0F9C3, (0x630, 0x2)), + (0x0F945, (0x514, 0x2)), + (0x2F9FE, (0x69C, 0x2)), + (0x0FA86, (0x272, 0x2)), + (0x2F82C, (0x136, 0x2)), + (0x0F988, (0x6D4, 0x2)), + (0x0FAC5, (0x652, 0x2)), + (0x0FA66, (0x626, 0x2)), + (0x2F840, (0x166, 0x2)), + (0x0F9EE, (0x3E6, 0x2)), + (0x2F830, (0x142, 0x2)), + (0x2F914, (0x3C6, 0x2)), + (0x2F942, (0x760, 0x2)), + (0x0FAA3, (0x432, 0x2)), + (0x0F974, (0x540, 0x2)), + (0x2F807, (0x0B6, 0x2)), + (0x2F905, (0x394, 0x2)), + (0x2F9B2, (0x06A, 0x2)), + (0x2F887, (0x22A, 0x2)), + (0x2F912, (0x3BC, 0x2)), + (0x0F9AE, (0x420, 0x2)), + (0x0F96A, (0x4D4, 0x2)), + (0x0F9B7, (0x646, 0x2)), + (0x2F932, (0x42C, 0x2)), + (0x2F98D, (0x622, 0x2)), + (0x0FA25, (0x62A, 0x2)), + (0x0F993, (0x3DC, 0x2)), + (0x2F9F5, (0x688, 0x2)), + (0x0F9DF, (0x206, 0x2)), + (0x2F9C7, (0x5B4, 0x2)), + (0x2F996, (0x544, 0x2)), + (0x2F842, (0x16C, 0x2)), + (0x2F869, (0x1E0, 0x2)), + (0x2F861, (0x70A, 0x2)), + (0x2F8AF, (0x298, 0x2)), + (0x2F8C5, (0x2E0, 0x2)), + (0x2F962, (0x4B8, 0x2)), + (0x2F98B, (0x528, 0x2)), + (0x2F9A1, (0x558, 0x2)), + (0x0FAD2, (0x02A, 0x2)), + (0x2F9AE, (0x066, 0x2)), + (0x2F8BC, (0x2C6, 0x2)), + (0x0F9B3, (0x68C, 0x2)), + (0x2F88F, (0x7D0, 0x2)), + (0x0F965, (0x0B4, 0x2)), + (0x2F953, (0x488, 0x2)), + (0x2F84B, (0x198, 0x2)), + (0x2F90B, (0x3AC, 0x2)), + (0x2F834, (0x702, 0x2)), + (0x0FA2D, (0x6CC, 0x2)), + (0x2F8E6, (0x33E, 0x2)), + (0x0F971, (0x624, 0x2)), + (0x2FA1C, (0x6E6, 0x2)), + (0x0FA61, (0x5C6, 0x2)), + (0x2F98E, (0x062, 0x2)), + (0x2F9C9, (0x5BA, 0x2)), + (0x0FA0B, (0x23E, 0x2)), + (0x2F86B, (0x1E6, 0x2)), + (0x0F949, (0x686, 0x2)), + (0x0FAC7, (0x682, 0x2)), + (0x0F96E, (0x566, 0x2)), + (0x0F966, (0x258, 0x2)), + (0x0F955, (0x0F2, 0x2)), + (0x2F8D0, (0x024, 0x2)), + (0x2F93A, (0x440, 0x2)), + (0x0F9FF, (0x104, 0x2)), + (0x0FAC8, (0x690, 0x2)), + (0x0F93C, (0x490, 0x2)), + (0x2F845, (0x174, 0x2)), + (0x2F9CE, (0x074, 0x2)), + (0x0FAD6, (0x77C, 0x2)), + (0x2F95A, (0x4A6, 0x2)), + (0x0F9E9, (0x648, 0x2)), + (0x2F91F, (0x74E, 0x2)), + (0x0F950, (0x4EC, 0x2)), + (0x2F8C1, (0x2CA, 0x2)), + (0x2F9AD, (0x79C, 0x2)), + (0x2F97F, (0x512, 0x2)), + (0x0FA83, (0x240, 0x2)), + (0x2F82D, (0x13A, 0x2)), + (0x2F8DF, (0x32C, 0x2)), + (0x2F87C, (0x212, 0x2)), + (0x0FA58, (0x4EA, 0x2)), + (0x2F846, (0x176, 0x2)), + (0x0FA37, (0x18C, 0x2)), + (0x0FA78, (0x180, 0x2)), + (0x2F9F6, (0x7BA, 0x2)), + (0x2F99E, (0x55E, 0x2)), + (0x0FAD3, (0x042, 0x2)), + (0x0FAD0, (0x720, 0x2)), + (0x0F9D5, (0x210, 0x2)), + (0x0FAB7, (0x5C2, 0x2)), + (0x0FA09, (0x66C, 0x2)), + (0x2F8CE, (0x026, 0x2)), + (0x0F957, (0x4DE, 0x2)), + (0x0F991, (0x2DE, 0x2)), + (0x0FAB8, (0x5C8, 0x2)), + (0x2F8EB, (0x34E, 0x2)), + (0x2F9B1, (0x7A0, 0x2)), + (0x0FA2A, (0x6AC, 0x2)), + (0x2F93C, (0x75C, 0x2)), + (0x0FA72, (0x0D4, 0x2)), + (0x2F96F, (0x4E8, 0x2)), + (0x2F8D6, (0x518, 0x2)), + (0x2F886, (0x228, 0x2)), + (0x0F9FD, (0x0A0, 0x2)), + (0x0F9C0, (0x3E4, 0x2)), + (0x2F9BE, (0x59E, 0x2)), + (0x0F9B8, (0x67A, 0x2)), + (0x2F81E, (0x0FA, 0x2)), + (0x0F900, (0x5F4, 0x2)), + (0x2F98C, (0x52A, 0x2)), + (0x2F93E, (0x03E, 0x2)), + (0x0FAA0, (0x404, 0x2)), + (0x2F8F3, (0x35A, 0x2)), + (0x0F961, (0x40A, 0x2)), + (0x2F83D, (0x15C, 0x2)), + (0x2F8F6, (0x36A, 0x2)), + (0x0F9D2, (0x2AA, 0x2)), + (0x2F84A, (0x188, 0x2)), + (0x0F9E1, (0x31C, 0x2)), + (0x0FA7C, (0x1AC, 0x2)), + (0x2F9AA, (0x574, 0x2)), + (0x0FA51, (0x48A, 0x2)), + (0x2F8B8, (0x724, 0x2)), + (0x2F931, (0x426, 0x2)), + (0x0FA7E, (0x1C6, 0x2)), + (0x0F9A6, (0x4BC, 0x2)), + (0x0F976, (0x438, 0x2)), + (0x0FA97, (0x386, 0x2)), + (0x2F8E7, (0x02C, 0x2)), + (0x2F88B, (0x230, 0x2)), + (0x2F9C6, (0x5B2, 0x2)), + (0x2F8D9, (0x318, 0x2)), + (0x0FA52, (0x492, 0x2)), + (0x2FA0D, (0x084, 0x2)), + (0x2F900, (0x382, 0x2)), + (0x2F836, (0x14C, 0x2)), + (0x0F9AD, (0x412, 0x2)), + (0x0F934, (0x504, 0x2)), + (0x0FAB0, (0x4E6, 0x2)), + (0x2F809, (0x0BC, 0x2)), + (0x2F9F2, (0x078, 0x2)), + (0x2F86C, (0x70C, 0x2)), + (0x0F9FC, (0x5EC, 0x2)), + (0x2F95E, (0x776, 0x2)), + (0x0F9A3, (0x260, 0x2)), + (0x2F971, (0x058, 0x2)), + (0x2F89B, (0x018, 0x2)), + (0x0F977, (0x09E, 0x2)), + (0x0FA1A, (0x48E, 0x2)), + (0x0FA3C, (0x208, 0x2)), + (0x2F9BD, (0x598, 0x2)), + (0x0F928, (0x238, 0x2)), + (0x2F864, (0x1D8, 0x2)), + (0x2F9D1, (0x5F2, 0x2)), + (0x2F982, (0x51A, 0x2)), + (0x0F9DC, (0x674, 0x2)), + (0x2F972, (0x782, 0x2)), + (0x2F8CB, (0x2F4, 0x2)), + (0x0F960, (0x264, 0x2)), + (0x0F992, (0x3B8, 0x2)), + (0x2F8B4, (0x2AE, 0x2)), + (0x2F803, (0x6F4, 0x2)), + (0x2F818, (0x0E6, 0x2)), + (0x0F9F7, (0x4AE, 0x2)), + (0x2F827, (0x124, 0x2)), + (0x2F9FB, (0x7C0, 0x2)), + (0x2F987, (0x790, 0x2)), + (0x0FAAB, (0x474, 0x2)), + (0x0FA39, (0x1A8, 0x2)), + (0x2FA07, (0x6BA, 0x2)), + (0x0F9B9, (0x274, 0x2)), + (0x2F86E, (0x1EC, 0x2)), + (0x2F8E0, (0x326, 0x2)), + (0x0FAA7, (0x44E, 0x2)), + (0x2F8A8, (0x282, 0x2)), + (0x0FA0A, (0x5C4, 0x2)), + (0x2FA14, (0x7CE, 0x2)), + (0x2F888, (0x012, 0x2)), + (0x2F9A2, (0x55A, 0x2)), + (0x2F848, (0x182, 0x2)), + (0x0FAA8, (0x452, 0x2)), + (0x0FA67, (0x62C, 0x2)), + (0x0F946, (0x3F6, 0x2)), + (0x2F946, (0x45A, 0x2)), + (0x0FA7D, (0x1B4, 0x2)), + (0x0FA1D, (0x4C4, 0x2)), + (0x2FA11, (0x088, 0x2)), + (0x0FA2C, (0x6B0, 0x2)), + (0x0F924, (0x5C0, 0x2)), + (0x2F96E, (0x4E0, 0x2)), + (0x0F96D, (0x456, 0x2)), + (0x0F95A, (0x5EE, 0x2)), + (0x2F85C, (0x1C0, 0x2)), + (0x0F92B, (0x400, 0x2)), + (0x0FAC0, (0x5F0, 0x2)), + (0x0FA8D, (0x2CC, 0x2)), + (0x2F9D8, (0x7AE, 0x2)), + (0x0F938, (0x68A, 0x2)), + (0x2F821, (0x108, 0x2)), + (0x0F9AA, (0x1F0, 0x2)), + (0x0F9CE, (0x46A, 0x2)), + (0x0FA47, (0x3B4, 0x2)), + (0x2F8AA, (0x288, 0x2)), + (0x2F918, (0x3D0, 0x2)), + (0x2F8EE, (0x02E, 0x2)), + (0x0F96B, (0x14A, 0x2)), + (0x0F909, (0x1CA, 0x2)), + (0x2F87F, (0x216, 0x2)), + (0x0F908, (0x6F0, 0x2)), + (0x0FA5D, (0x530, 0x2)), + (0x0F9AC, (0x266, 0x2)), + (0x2F896, (0x016, 0x2)), + (0x2F9B0, (0x79E, 0x2)), + (0x0F9A7, (0x406, 0x2)), + (0x0F99D, (0x112, 0x2)), + (0x2F957, (0x49E, 0x2)), + (0x0F905, (0x090, 0x2)), + (0x2F9BC, (0x596, 0x2)), + (0x2F8F9, (0x73E, 0x2)), + (0x2F8B0, (0x29E, 0x2)), + (0x2F881, (0x220, 0x2)), + (0x2FA1B, (0x6E4, 0x2)), + (0x2F9DD, (0x700, 0x2)), + (0x2F9ED, (0x7B6, 0x2)), + (0x2F871, (0x70E, 0x2)), + (0x2F8AB, (0x28E, 0x2)), + (0x2F812, (0x6F6, 0x2)), + (0x0F933, (0x450, 0x2)), + (0x0F9F2, (0x6C6, 0x2)), + (0x0F984, (0x3C0, 0x2)), + (0x2F90E, (0x39C, 0x2)), + (0x0FAB2, (0x508, 0x2)), + (0x0FA32, (0x0CA, 0x2)), + (0x2F96D, (0x056, 0x2)), + (0x2F9A7, (0x064, 0x2)), + (0x0F94F, (0x4D6, 0x2)), + (0x2FA0F, (0x6CA, 0x2)), + (0x0F925, (0x2B2, 0x2)), + (0x0FA91, (0x2FC, 0x2)), + (0x0F972, (0x370, 0x2)), + (0x0F90A, (0x64C, 0x2)), + (0x0FA02, (0x2B6, 0x2)), + (0x0F92F, (0x120, 0x2)), + (0x0F9DD, (0x102, 0x2)), + (0x0FA17, (0x44A, 0x2)), + (0x0F93F, (0x65A, 0x2)), + (0x2F898, (0x780, 0x2)), + (0x2F907, (0x380, 0x2)), + (0x0F9EC, (0x3A6, 0x2)), + (0x0F9E3, (0x378, 0x2)), + (0x0FAB5, (0x59A, 0x2)), + (0x0FA40, (0x29A, 0x2)), + (0x2F815, (0x0DE, 0x2)), + (0x2F9DB, (0x60A, 0x2)), + (0x0F91E, (0x3EA, 0x2)), + (0x0F92C, (0x636, 0x2)), + (0x2F884, (0x224, 0x2)), + (0x0FA46, (0x39E, 0x2)), + (0x2F9B3, (0x584, 0x2)), + (0x2F85B, (0x1BE, 0x2)), + (0x0F9CD, (0x436, 0x2)), + (0x0F93A, (0x6CE, 0x2)), + (0x0F97E, (0x64A, 0x2)), + (0x0FA3E, (0x286, 0x2)), + (0x2F9EB, (0x65E, 0x2)), + (0x2F8E2, (0x338, 0x2)), + (0x2F9B6, (0x58C, 0x2)), + (0x0F916, (0x3D8, 0x2)), + (0x2F8DE, (0x028, 0x2)), + (0x0F98F, (0x290, 0x2)), + (0x0FA12, (0x2FA, 0x2)), + (0x0FA44, (0x336, 0x2)), + (0x0F981, (0x1D0, 0x2)), + (0x2F9DC, (0x610, 0x2)), + (0x0F95C, (0x348, 0x2)), + (0x0F937, (0x60E, 0x2)), + (0x2F87A, (0x20C, 0x2)), + (0x2F903, (0x38A, 0x2)), + (0x2F9C5, (0x7A4, 0x2)), + (0x2F8CF, (0x302, 0x2)), + (0x2F909, (0x3A2, 0x2)), + (0x2F991, (0x538, 0x2)), + (0x0FA65, (0x602, 0x2)), + (0x0FA73, (0x0A8, 0x2)), + (0x2F88E, (0x23A, 0x2)), + (0x0F9EF, (0x42A, 0x2)), + (0x2F9CB, (0x7A6, 0x2)), + (0x2F9A3, (0x55C, 0x2)), + (0x2F99C, (0x548, 0x2)), + (0x2F919, (0x3CE, 0x2)), + (0x2F857, (0x1A4, 0x2)), + (0x2F96C, (0x4DA, 0x2)), + (0x2F800, (0x096, 0x2)), + (0x2FA1A, (0x6E2, 0x2)), + (0x0F97F, (0x126, 0x2)), + (0x0FABA, (0x5DE, 0x2)), + (0x0FA82, (0x23C, 0x2)), + (0x2F92E, (0x41C, 0x2)), + (0x0F9FE, (0x54A, 0x2)), + (0x0F994, (0x428, 0x2)), + (0x2F83C, (0x164, 0x2)), + (0x0FA50, (0x486, 0x2)), + (0x2F817, (0x0E4, 0x2)), + (0x0FA38, (0x192, 0x2)), + (0x0FA69, (0x696, 0x2)), + (0x0FAAC, (0x4AC, 0x2)), + (0x0F901, (0x30A, 0x2)), + (0x0FA33, (0x11A, 0x2)), + (0x0F9BF, (0x34A, 0x2)), + (0x0F9D1, (0x0D8, 0x2)), + (0x0F95F, (0x1EE, 0x2)), + (0x2F82F, (0x13E, 0x2)), + (0x0F9A4, (0x2C4, 0x2)), + (0x2F89E, (0x25E, 0x2)), + (0x2F801, (0x092, 0x2)), + (0x2F84F, (0x194, 0x2)), + (0x2F961, (0x778, 0x2)), + (0x2F87E, (0x218, 0x2)), + (0x2F9D5, (0x5FA, 0x2)), + (0x0F9E7, (0x5B0, 0x2)), + (0x0F973, (0x2BC, 0x2)), + (0x0F9C2, (0x572, 0x2)), + (0x2F9D0, (0x5DA, 0x2)), + (0x0F9A5, (0x362, 0x2)), + (0x2F80C, (0x000, 0x2)), + (0x0F930, (0x2E2, 0x2)), + (0x2F8A1, (0x01C, 0x2)), + (0x2F828, (0x12A, 0x2)), + (0x2F89F, (0x262, 0x2)), + (0x0F964, (0x478, 0x2)), + (0x0F94E, (0x3B2, 0x2)), + (0x2F8D7, (0x05E, 0x2)), + (0x2F806, (0x0B2, 0x2)), + (0x2F9CC, (0x7A8, 0x2)), + (0x2F94E, (0x468, 0x2)), + (0x2F929, (0x40E, 0x2)), + (0x0FA34, (0x122, 0x2)), + (0x2F939, (0x718, 0x2)), + (0x0F910, (0x582, 0x2)), + (0x0F926, (0x520, 0x2)), + (0x0F9A2, (0x236, 0x2)), + (0x0FA49, (0x3EE, 0x2)), + (0x0F953, (0x516, 0x2)), + (0x2F80F, (0x0CE, 0x2)), + (0x0F963, (0x130, 0x2)), + (0x2F8D4, (0x30E, 0x2)), + (0x0F9B2, (0x684, 0x2)), + (0x2F973, (0x784, 0x2)), + (0x2F897, (0x72A, 0x2)), + (0x2F9FC, (0x07E, 0x2)), + (0x0F99A, (0x628, 0x2)), + (0x2F85A, (0x1BC, 0x2)), + (0x0FACF, (0x722, 0x2)), + (0x2F9AB, (0x7A2, 0x2)), + (0x2F927, (0x754, 0x2)), + (0x2F9FD, (0x7C2, 0x2)), + (0x0FA36, (0x17E, 0x2)), + (0x0F904, (0x3AE, 0x2)), + (0x2F81C, (0x7BC, 0x2)), + (0x0FA7B, (0x18A, 0x2)), + (0x0FA41, (0x2E4, 0x2)), + (0x2F87B, (0x712, 0x2)), + (0x2F9BA, (0x592, 0x2)), + (0x0F979, (0x0F0, 0x2)), + (0x0F9D7, (0x618, 0x2)), +]; + +pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ + 0x000, 0x000, 0x002, 0x001, 0x008, 0x005, 0x969, 0x1EE, 0x007, 0x0CD, 0x2D9, 0x012, 0x003, + 0x000, 0x000, 0x2D4, 0x000, 0x0C7, 0x14A, 0x000, 0x001, 0x38A, 0x000, 0x000, 0x007, 0x083, + 0x00A, 0x000, 0x000, 0x000, 0x001, 0x02B, 0x05D, 0x000, 0x000, 0x000, 0x0A0, 0x000, 0x005, + 0x000, 0x04B, 0x15D, 0x000, 0x023, 0x0BA, 0x000, 0x000, 0x000, 0x000, 0x058, 0x005, 0x002, + 0x005, 0x000, 0x064, 0x002, 0x000, 0x002, 0x019, 0x000, 0x001, 0x0EC, 0x001, 0x103, 0x026, + 0x011, 0x000, 0x001, 0x000, 0x000, 0x040, 0x003, 0x01C, 0x001, 0x023, 0x000, 0x002, 0x001, + 0x014, 0x000, 0x0B4, 0x000, 0x0A0, 0x0D8, 0x000, 0x003, 0x003, 0x08C, 0x02E, 0x000, 0x000, + 0x00E, 0x009, 0x000, 0x000, 0x02E, 0x001, 0x001, 0x000, 0x000, 0x000, 0x079, 0x001, 0x000, + 0x000, 0x036, 0x000, 0x001, 0x000, 0x000, 0x004, 0x03A, 0x000, 0x001, 0x01C, 0x180, 0x002, + 0x006, 0x0CA, 0x002, 0x000, 0x000, 0x000, 0x000, 0x076, 0x083, 0x000, 0x007, 0x07A, 0x000, + 0x018, 0x009, 0x070, 0x0AA, 0x000, 0x00F, 0x03C, 0x002, 0x000, 0x008, 0x000, 0x021, 0x008, + 0x03D, 0x019, 0x017, 0x003, 0x003, 0x017, 0x003, 0x018, 0x000, 0x000, 0x006, 0x001, 0x002, + 0x000, 0x004, 0x000, 0x004, 0x011, 0x034, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x013, + 0x002, 0x000, 0x003, 0x016, 0x000, 0x007, 0x033, 0x006, 0x021, 0x007, 0x008, 0x024, 0x000, + 0x000, 0x003, 0x00B, 0x003, 0x006, 0x000, 0x0CB, 0x001, 0x000, 0x012, 0x000, 0x000, 0x000, + 0x01F, 0x00A, 0x024, 0x014, 0x054, 0x000, 0x000, 0x000, 0x000, 0x00D, 0x001, 0x029, 0x000, + 0x00B, 0x000, 0x001, 0x000, 0x017, 0x001, 0x012, 0x01B, 0x003, 0x000, 0x005, 0x000, 0x001, + 0x003, 0x001, 0x047, 0x000, 0x02C, 0x006, 0x000, 0x05B, 0x01F, 0x000, 0x000, 0x000, 0x004, + 0x001, 0x000, 0x003, 0x000, 0x008, 0x001, 0x028, 0x001, 0x001, 0x000, 0x000, 0x000, 0x005, + 0x003, 0x005, 0x02A, 0x001, 0x002, 0x000, 0x016, 0x015, 0x022, 0x000, 0x000, 0x01A, 0x009, + 0x00A, 0x000, 0x000, 0x001, 0x00D, 0x000, 0x005, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x005, 0x03A, 0x000, 0x010, 0x002, 0x004, 0x000, 0x000, 0x03A, 0x000, 0x015, + 0x002, 0x004, 0x000, 0x000, 0x01A, 0x00A, 0x000, 0x00B, 0x000, 0x000, 0x006, 0x002, 0x000, + 0x012, 0x000, 0x012, 0x000, 0x003, 0x01F, 0x006, 0x00C, 0x000, 0x000, 0x022, 0x000, 0x002, + 0x0A0, 0x00C, 0x003, 0x001, 0x039, 0x004, 0x003, 0x00B, 0x008, 0x009, 0x002, 0x000, 0x000, + 0x000, 0x000, 0x003, 0x002, 0x000, 0x004, 0x00B, 0x003, 0x000, 0x000, 0x005, 0x000, 0x005, + 0x000, 0x01B, 0x000, 0x000, 0x02A, 0x01E, 0x001, 0x001, 0x000, 0x003, 0x031, 0x001, 0x004, + 0x010, 0x000, 0x005, 0x001, 0x00D, 0x000, 0x00F, 0x002, 0x000, 0x000, 0x002, 0x000, 0x008, + 0x00C, 0x000, 0x00E, 0x003, 0x000, 0x000, 0x017, 0x000, 0x001, 0x000, 0x001, 0x001, 0x000, + 0x000, 0x002, 0x008, 0x007, 0x002, 0x037, 0x000, 0x01C, 0x00D, 0x000, 0x00A, 0x000, 0x000, + 0x007, 0x023, 0x000, 0x004, 0x000, 0x000, 0x000, 0x019, 0x006, 0x000, 0x002, 0x000, 0x048, + 0x005, 0x000, 0x000, 0x020, 0x000, 0x000, 0x00A, 0x002, 0x000, 0x01C, 0x008, 0x031, 0x000, + 0x000, 0x000, 0x00C, 0x00B, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x000, 0x01E, + 0x000, 0x016, 0x000, 0x000, 0x016, 0x028, 0x000, 0x000, 0x000, 0x03A, 0x000, 0x001, 0x000, + 0x004, 0x000, 0x000, 0x000, 0x006, 0x002, 0x000, 0x011, 0x00B, 0x000, 0x007, 0x004, 0x000, + 0x00C, 0x000, 0x026, 0x036, 0x007, 0x002, 0x007, 0x00E, 0x002, 0x001, 0x00A, 0x000, 0x00E, + 0x002, 0x005, 0x008, 0x002, 0x002, 0x000, 0x000, 0x023, 0x005, 0x005, 0x00E, 0x005, 0x009, + 0x000, 0x00A, 0x004, 0x001, 0x006, 0x000, 0x000, 0x011, 0x000, 0x002, 0x000, 0x00E, 0x005, + 0x001, 0x000, 0x002, 0x00F, 0x001, 0x005, 0x000, 0x002, 0x00F, 0x001, 0x000, 0x002, 0x006, + 0x000, 0x03F, 0x009, 0x000, 0x000, 0x003, 0x003, 0x007, 0x000, 0x000, 0x000, 0x031, 0x00E, + 0x001, 0x000, 0x000, 0x001, 0x000, 0x002, 0x017, 0x003, 0x026, 0x000, 0x027, 0x000, 0x000, + 0x00C, 0x001, 0x006, 0x000, 0x003, 0x001, 0x000, 0x000, 0x002, 0x002, 0x000, 0x003, 0x000, + 0x008, 0x000, 0x01B, 0x000, 0x000, 0x00B, 0x013, 0x002, 0x001, 0x000, 0x002, 0x008, 0x000, + 0x001, 0x009, 0x000, 0x00D, 0x000, 0x004, 0x01B, 0x000, 0x000, 0x000, 0x003, 0x002, 0x000, + 0x001, 0x008, 0x00B, 0x015, 0x006, 0x001, 0x00B, 0x000, 0x008, 0x00A, 0x000, 0x000, 0x02B, + 0x000, 0x002, 0x000, 0x003, 0x005, 0x00B, 0x000, 0x00C, 0x000, 0x004, 0x004, 0x000, 0x000, + 0x001, 0x000, 0x000, 0x000, 0x007, 0x00A, 0x008, 0x002, 0x000, 0x001, 0x006, 0x014, 0x000, + 0x000, 0x003, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x003, 0x000, 0x000, 0x006, 0x003, + 0x000, 0x003, 0x000, 0x002, 0x000, 0x000, 0x000, 0x006, 0x000, 0x000, 0x004, 0x001, 0x004, + 0x000, 0x003, 0x001, 0x001, 0x004, 0x001, 0x000, 0x000, 0x003, 0x000, 0x000, 0x001, 0x002, + 0x001, 0x003, 0x002, 0x002, 0x000, 0x004, 0x00A, 0x008, 0x01E, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x006, 0x004, 0x000, 0x000, 0x004, 0x000, 0x000, 0x002, 0x00F, 0x00B, 0x014, 0x000, + 0x002, 0x001, 0x000, 0x000, 0x000, 0x004, 0x000, 0x004, 0x002, 0x000, 0x006, 0x00B, 0x000, + 0x009, 0x018, 0x006, 0x006, 0x005, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x006, 0x000, + 0x000, 0x00E, 0x001, 0x001, 0x000, 0x003, 0x000, 0x016, 0x003, 0x015, 0x000, 0x000, 0x006, + 0x006, 0x002, 0x000, 0x003, 0x001, 0x000, 0x00B, 0x005, 0x005, 0x001, 0x000, 0x000, 0x003, + 0x000, 0x004, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x001, 0x003, 0x000, 0x000, 0x002, + 0x002, 0x000, 0x00B, 0x000, 0x001, 0x005, 0x002, 0x000, 0x000, 0x011, 0x00F, 0x000, 0x001, + 0x00D, 0x00C, 0x001, 0x00B, 0x002, 0x010, 0x008, 0x001, 0x001, 0x004, 0x005, 0x011, 0x001, + 0x00B, 0x010, 0x000, 0x001, 0x006, 0x000, 0x00C, 0x000, 0x00E, 0x00B, 0x001, 0x000, 0x003, + 0x022, 0x004, 0x000, 0x001, 0x000, 0x007, 0x001, 0x004, 0x006, 0x001, 0x001, 0x000, 0x001, + 0x007, 0x003, 0x004, 0x007, 0x006, 0x001, 0x010, 0x00D, 0x000, 0x000, 0x000, 0x007, 0x003, + 0x000, 0x008, 0x001, 0x007, 0x003, 0x003, 0x000, 0x000, 0x010, 0x003, 0x002, 0x000, 0x000, + 0x000, 0x000, 0x005, 0x001, 0x000, 0x002, 0x000, 0x003, 0x000, 0x001, 0x010, 0x001, 0x000, + 0x015, 0x003, 0x007, 0x001, 0x00D, 0x005, 0x002, 0x015, 0x000, 0x001, 0x009, 0x000, 0x006, + 0x000, 0x003, 0x001, 0x000, 0x000, 0x002, 0x000, 0x002, 0x000, 0x000, 0x00F, 0x000, 0x001, + 0x015, 0x004, 0x002, 0x002, 0x001, 0x008, 0x000, 0x000, 0x000, 0x00C, 0x000, 0x004, 0x000, + 0x005, 0x007, 0x00F, 0x001, 0x003, 0x006, 0x001, 0x000, 0x004, 0x000, 0x00C, 0x004, 0x012, + 0x002, 0x002, 0x000, 0x001, 0x018, 0x004, 0x000, 0x000, 0x001, 0x00C, 0x000, 0x000, 0x00E, + 0x001, 0x000, 0x007, 0x002, 0x000, 0x000, 0x001, 0x017, 0x002, 0x002, 0x000, 0x000, 0x004, + 0x001, 0x000, 0x002, 0x006, 0x002, 0x003, 0x00A, 0x000, 0x005, 0x000, 0x003, 0x001, 0x002, + 0x002, 0x000, 0x001, 0x005, 0x003, 0x000, 0x00D, 0x00C, 0x001, 0x000, 0x001, 0x004, 0x000, + 0x002, 0x000, 0x001, 0x000, 0x000, 0x001, 0x005, 0x000, 0x000, 0x000, 0x000, 0x001, 0x01D, + 0x003, 0x002, 0x00C, 0x000, 0x000, 0x003, 0x009, 0x000, 0x000, 0x005, 0x003, 0x000, 0x001, + 0x002, 0x006, 0x001, 0x008, 0x001, 0x001, 0x00D, 0x004, 0x006, 0x008, 0x001, 0x00B, 0x007, + 0x00A, 0x006, 0x002, 0x00F, 0x005, 0x000, 0x00B, 0x006, 0x001, 0x001, 0x001, 0x004, 0x009, + 0x000, 0x001, 0x000, 0x003, 0x000, 0x009, 0x009, 0x004, 0x001, 0x001, 0x009, 0x006, 0x002, + 0x008, 0x007, 0x003, 0x000, 0x008, 0x007, 0x000, 0x014, 0x001, 0x001, 0x013, 0x003, 0x004, + 0x000, 0x000, 0x003, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x005, 0x00A, 0x000, 0x000, 0x000, 0x012, 0x000, 0x000, 0x000, 0x002, 0x000, 0x008, 0x000, + 0x016, 0x011, 0x007, 0x003, 0x000, 0x009, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x001, 0x000, 0x000, 0x009, 0x00C, 0x004, 0x000, 0x002, 0x000, 0x000, 0x002, 0x001, + 0x007, 0x000, 0x000, 0x001, 0x000, 0x003, 0x000, 0x000, 0x000, 0x000, 0x009, 0x003, 0x002, + 0x008, 0x002, 0x000, 0x001, 0x001, 0x00A, 0x013, 0x002, 0x003, 0x001, 0x003, 0x006, 0x000, + 0x003, 0x001, 0x004, 0x002, 0x000, 0x000, 0x004, 0x004, 0x000, 0x000, 0x000, 0x00D, 0x002, + 0x009, 0x002, 0x000, 0x007, 0x007, 0x001, 0x000, 0x002, 0x006, 0x002, 0x000, 0x001, 0x002, + 0x003, 0x000, 0x000, 0x009, 0x003, 0x007, 0x001, 0x000, 0x000, 0x00F, 0x001, 0x00C, 0x000, + 0x003, 0x000, 0x002, 0x000, 0x000, 0x009, 0x002, 0x002, 0x000, 0x001, 0x000, 0x006, 0x000, + 0x002, 0x002, 0x003, 0x002, 0x001, 0x00F, 0x001, 0x008, 0x002, 0x002, 0x009, 0x009, 0x00B, + 0x007, 0x002, 0x000, 0x000, 0x005, 0x00E, 0x001, 0x004, 0x007, 0x002, 0x001, 0x000, 0x003, + 0x00A, 0x000, 0x000, 0x00E, 0x000, 0x009, 0x003, 0x003, 0x001, 0x000, 0x000, 0x000, 0x007, + 0x000, 0x008, 0x00E, 0x000, 0x000, 0x000, 0x000, 0x002, 0x010, 0x002, 0x001, 0x002, 0x000, + 0x009, 0x000, 0x000, 0x002, 0x006, 0x000, 0x001, 0x000, 0x002, 0x000, 0x00D, 0x003, 0x001, + 0x00B, 0x001, 0x001, 0x000, 0x007, 0x000, 0x000, 0x003, 0x002, 0x004, 0x006, 0x004, 0x000, + 0x001, 0x008, 0x001, 0x005, 0x005, 0x00B, 0x011, 0x004, 0x002, 0x000, 0x02A, 0x000, 0x001, + 0x004, 0x008, 0x004, 0x000, 0x001, 0x001, 0x000, 0x000, 0x001, 0x007, 0x00B, 0x003, 0x000, + 0x002, 0x000, 0x005, 0x004, 0x002, 0x000, 0x001, 0x00A, 0x009, 0x001, 0x002, 0x000, 0x006, + 0x003, 0x001, 0x006, 0x003, 0x000, 0x001, 0x003, 0x000, 0x000, 0x005, 0x002, 0x006, 0x002, + 0x001, 0x000, 0x000, 0x000, 0x000, 0x003, 0x001, 0x000, 0x004, 0x000, 0x007, 0x001, 0x000, + 0x000, 0x002, 0x008, 0x000, 0x004, 0x001, 0x015, 0x000, 0x004, 0x000, 0x000, 0x005, 0x000, + 0x009, 0x002, 0x008, 0x006, 0x001, 0x000, 0x001, 0x001, 0x002, 0x000, 0x001, 0x003, 0x000, + 0x000, 0x003, 0x000, 0x003, 0x001, 0x000, 0x000, 0x000, 0x000, 0x001, 0x001, 0x001, 0x008, + 0x000, 0x001, 0x001, 0x001, 0x009, 0x003, 0x002, 0x000, 0x000, 0x001, 0x00C, 0x007, 0x003, + 0x002, 0x00A, 0x000, 0x005, 0x008, 0x00A, 0x006, 0x005, 0x006, 0x001, 0x000, 0x003, 0x000, + 0x006, 0x003, 0x000, 0x002, 0x002, 0x004, 0x005, 0x003, 0x002, 0x001, 0x000, 0x001, 0x005, + 0x001, 0x000, 0x003, 0x001, 0x007, 0x001, 0x001, 0x000, 0x000, 0x003, 0x003, 0x007, 0x001, + 0x000, 0x001, 0x001, 0x003, 0x00A, 0x003, 0x00A, 0x000, 0x000, 0x000, 0x001, 0x003, 0x001, + 0x000, 0x004, 0x000, 0x002, 0x003, 0x006, 0x000, 0x000, 0x005, 0x001, 0x000, 0x000, 0x003, + 0x005, 0x003, 0x001, 0x001, 0x003, 0x000, 0x000, 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, + 0x000, 0x001, 0x000, 0x001, 0x003, 0x001, 0x003, 0x004, 0x001, 0x009, 0x002, 0x002, 0x002, + 0x003, 0x006, 0x001, 0x000, 0x000, 0x001, 0x007, 0x000, 0x004, 0x000, 0x001, 0x000, 0x00B, + 0x000, 0x002, 0x001, 0x004, 0x000, 0x007, 0x002, 0x004, 0x008, 0x005, 0x001, 0x003, 0x001, + 0x000, 0x002, 0x000, 0x003, 0x000, 0x006, 0x003, 0x002, 0x000, 0x000, 0x008, 0x00D, 0x001, + 0x001, 0x000, 0x007, 0x001, 0x005, 0x008, 0x001, 0x009, 0x003, 0x000, 0x000, 0x003, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x004, 0x000, 0x000, 0x004, 0x003, 0x001, 0x004, + 0x000, 0x000, 0x000, 0x003, 0x003, 0x009, 0x003, 0x001, 0x000, 0x00A, 0x000, 0x001, 0x004, + 0x000, 0x001, 0x000, 0x000, 0x00C, 0x002, 0x000, 0x000, 0x007, 0x005, 0x000, 0x005, 0x000, + 0x000, 0x004, 0x000, 0x003, 0x000, 0x001, 0x006, 0x004, 0x004, 0x000, 0x002, 0x000, 0x003, + 0x001, 0x000, 0x005, 0x000, 0x002, 0x004, 0x000, 0x001, 0x000, 0x012, 0x001, 0x000, 0x008, + 0x003, 0x000, 0x002, 0x000, 0x005, 0x001, 0x001, 0x002, 0x001, 0x008, 0x003, 0x000, 0x006, + 0x001, 0x006, 0x001, 0x001, 0x002, 0x001, 0x000, 0x000, 0x000, 0x001, 0x003, 0x001, 0x004, + 0x000, 0x003, 0x008, 0x000, 0x005, 0x000, 0x000, 0x002, 0x000, 0x000, 0x001, 0x000, 0x000, + 0x00E, 0x001, 0x000, 0x000, 0x001, 0x003, 0x005, 0x000, 0x000, 0x001, 0x001, 0x003, 0x002, + 0x000, 0x002, 0x000, 0x007, 0x000, 0x000, 0x007, 0x001, 0x001, 0x000, 0x003, 0x000, 0x004, + 0x001, 0x002, 0x000, 0x000, 0x002, 0x003, 0x003, 0x000, 0x011, 0x000, 0x001, 0x001, 0x002, + 0x006, 0x003, 0x000, 0x002, 0x004, 0x002, 0x005, 0x000, 0x000, 0x000, 0x006, 0x000, 0x003, + 0x001, 0x007, 0x002, 0x000, 0x000, 0x000, 0x008, 0x000, 0x000, 0x001, 0x002, 0x000, 0x003, + 0x001, 0x001, 0x003, 0x000, 0x001, 0x001, 0x00E, 0x001, 0x000, 0x001, 0x008, 0x001, 0x001, + 0x001, 0x005, 0x008, 0x002, 0x003, 0x001, 0x000, 0x001, 0x003, 0x000, 0x001, 0x000, 0x003, + 0x001, 0x003, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x001, + 0x001, 0x002, 0x000, 0x004, 0x002, 0x001, 0x000, 0x007, 0x000, 0x003, 0x001, 0x000, 0x000, + 0x000, 0x008, 0x001, 0x001, 0x000, 0x003, 0x001, 0x000, 0x000, 0x001, 0x001, 0x000, 0x000, + 0x001, 0x005, 0x000, 0x001, 0x003, 0x002, 0x003, 0x001, 0x000, 0x00D, 0x001, 0x000, 0x003, + 0x002, 0x001, 0x004, 0x003, 0x001, 0x002, 0x002, 0x001, 0x002, 0x001, 0x003, 0x008, 0x000, + 0x003, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x003, 0x002, 0x006, 0x002, 0x008, 0x000, + 0x000, 0x000, 0x000, 0x003, 0x000, 0x001, 0x000, 0x001, 0x005, 0x002, 0x005, 0x000, 0x001, + 0x000, 0x000, 0x000, 0x002, 0x000, 0x001, 0x006, 0x000, 0x001, 0x003, 0x000, 0x000, 0x002, + 0x000, 0x000, 0x001, 0x003, 0x00A, 0x004, 0x009, 0x000, 0x002, 0x000, 0x003, 0x003, 0x001, + 0x001, 0x00A, 0x000, 0x006, 0x004, 0x003, 0x003, 0x002, 0x001, 0x004, 0x002, 0x002, 0x003, + 0x005, 0x003, 0x000, 0x002, 0x000, 0x001, 0x001, 0x000, 0x002, 0x002, 0x001, 0x000, 0x004, + 0x002, 0x004, 0x000, 0x000, 0x000, 0x001, 0x007, 0x000, 0x000, 0x002, 0x003, 0x002, 0x003, + 0x000, 0x002, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x003, 0x000, 0x004, 0x003, 0x008, + 0x008, 0x000, 0x001, 0x000, 0x000, 0x001, 0x000, 0x004, 0x000, 0x000, 0x001, 0x00C, 0x001, + 0x003, 0x000, 0x005, 0x001, 0x00A, 0x004, 0x001, 0x003, 0x001, 0x000, 0x001, 0x001, 0x000, + 0x003, 0x003, 0x003, 0x000, 0x000, 0x000, 0x007, 0x000, 0x005, 0x001, 0x000, 0x002, 0x000, + 0x003, 0x000, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x004, 0x001, 0x005, 0x001, 0x000, + 0x001, 0x002, 0x001, 0x002, 0x002, 0x000, 0x000, 0x002, 0x001, 0x001, 0x003, 0x000, 0x000, + 0x004, 0x000, 0x00E, 0x004, 0x001, 0x002, 0x003, 0x001, 0x000, 0x002, 0x003, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x00A, + 0x002, 0x000, 0x000, 0x000, 0x000, 0x012, 0x000, 0x000, 0x004, 0x003, 0x000, 0x003, 0x003, + 0x001, 0x001, 0x000, 0x000, 0x006, 0x005, 0x000, 0x001, 0x003, 0x002, 0x000, 0x001, 0x006, + 0x000, 0x000, 0x000, 0x001, 0x003, 0x002, 0x000, 0x002, 0x000, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x003, 0x000, 0x005, 0x001, 0x002, 0x000, 0x000, 0x004, 0x000, 0x006, 0x000, 0x000, + 0x003, 0x004, 0x002, 0x000, 0x002, 0x002, 0x001, 0x008, 0x000, 0x001, 0x001, 0x001, 0x000, + 0x000, 0x001, 0x003, 0x000, 0x001, 0x003, 0x001, 0x000, 0x002, 0x000, 0x001, 0x000, 0x003, + 0x005, 0x000, 0x004, 0x001, 0x005, 0x000, 0x000, 0x001, 0x004, 0x002, 0x000, 0x000, 0x000, + 0x000, 0x004, 0x000, 0x000, 0x000, 0x001, 0x000, 0x010, 0x000, 0x001, 0x001, 0x000, 0x000, + 0x000, 0x001, 0x000, 0x001, 0x001, 0x006, 0x003, 0x005, 0x001, 0x000, 0x001, 0x001, 0x002, + 0x00E, 0x005, 0x003, 0x001, 0x001, 0x001, 0x002, 0x000, 0x001, 0x000, 0x004, 0x005, 0x002, + 0x003, 0x005, 0x003, 0x004, 0x000, 0x005, 0x001, 0x002, 0x001, 0x001, 0x002, 0x000, 0x005, + 0x001, 0x001, 0x001, 0x000, 0x002, 0x000, 0x006, 0x000, 0x001, 0x000, 0x002, 0x003, 0x002, + 0x003, 0x001, 0x000, 0x007, 0x001, 0x002, 0x003, 0x002, 0x001, 0x003, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x005, 0x001, 0x000, 0x002, 0x001, 0x001, 0x001, 0x000, 0x000, 0x006, 0x000, + 0x001, 0x002, 0x001, 0x002, 0x001, 0x000, 0x000, 0x002, 0x001, 0x000, 0x002, 0x002, 0x001, + 0x002, 0x001, 0x003, 0x000, 0x002, 0x000, 0x000, 0x002, 0x000, 0x000, 0x002, 0x001, 0x001, + 0x005, 0x004, 0x004, 0x001, 0x003, 0x007, 0x001, 0x000, 0x000, 0x001, 0x002, 0x002, 0x003, + 0x001, 0x004, 0x005, 0x001, 0x001, 0x004, 0x001, 0x000, 0x008, 0x002, 0x000, 0x000, 0x003, + 0x002, 0x000, 0x001, 0x001, 0x001, 0x006, 0x002, 0x000, 0x004, 0x004, 0x001, 0x000, 0x004, + 0x002, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x001, 0x000, 0x004, 0x001, 0x009, 0x001, + 0x004, 0x000, 0x001, 0x000, 0x001, 0x005, 0x000, 0x000, 0x000, 0x005, 0x003, 0x002, 0x003, + 0x004, 0x008, 0x002, 0x002, 0x000, 0x006, 0x001, 0x001, 0x002, 0x001, 0x000, 0x000, 0x002, + 0x000, 0x002, 0x002, 0x000, 0x002, 0x000, 0x002, 0x003, 0x000, 0x004, 0x002, 0x001, 0x002, + 0x003, 0x005, 0x001, 0x002, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x002, 0x00B, + 0x000, 0x000, 0x000, 0x001, 0x006, 0x005, 0x000, 0x000, 0x000, 0x002, 0x002, 0x000, 0x003, + 0x003, 0x002, 0x001, 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x000, 0x000, 0x001, 0x001, + 0x004, 0x001, 0x000, 0x002, 0x002, 0x003, 0x003, 0x000, 0x000, 0x002, 0x004, 0x001, 0x002, + 0x005, 0x001, 0x001, 0x000, 0x001, 0x001, 0x001, 0x000, 0x004, 0x001, 0x000, 0x002, 0x000, + 0x001, 0x000, 0x003, 0x002, 0x002, 0x007, 0x003, 0x001, 0x001, 0x001, 0x002, 0x001, 0x001, + 0x003, 0x002, 0x000, 0x001, 0x002, 0x005, 0x001, 0x002, 0x001, 0x000, 0x003, 0x001, 0x000, + 0x003, 0x000, 0x000, 0x000, 0x003, 0x001, 0x000, 0x002, 0x000, 0x001, 0x000, 0x001, 0x000, + 0x001, 0x00A, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x003, 0x000, 0x000, 0x001, 0x005, 0x004, 0x000, + 0x000, 0x000, 0x007, 0x000, 0x001, 0x000, 0x003, 0x004, 0x003, 0x002, 0x000, 0x000, 0x001, + 0x000, 0x001, 0x001, 0x000, 0x000, 0x003, 0x001, 0x001, 0x000, 0x000, 0x000, 0x005, 0x001, + 0x000, 0x001, 0x001, 0x000, 0x003, 0x008, 0x000, 0x000, 0x003, 0x001, 0x000, 0x001, 0x004, + 0x001, 0x002, 0x001, 0x002, 0x002, 0x002, 0x000, 0x000, 0x000, 0x002, 0x000, 0x002, 0x000, + 0x001, 0x001, 0x001, 0x002, 0x003, 0x001, 0x004, 0x001, 0x001, 0x000, 0x001, 0x000, 0x003, + 0x000, 0x002, 0x002, 0x002, 0x002, 0x000, 0x002, 0x002, 0x001, 0x000, 0x000, 0x002, 0x003, + 0x000, 0x001, 0x000, 0x000, 0x003, 0x001, 0x001, 0x002, 0x002, 0x001, 0x003, 0x000, 0x009, + 0x001, 0x000, 0x001, 0x001, 0x002, 0x001, 0x002, 0x000, 0x001, 0x001, 0x000, 0x001, 0x001, + 0x001, 0x001, 0x001, 0x000, 0x001, 0x000, 0x008, 0x001, 0x001, 0x000, 0x001, 0x001, 0x004, + 0x000, 0x000, 0x003, 0x001, 0x001, 0x000, 0x001, 0x000, 0x002, 0x000, 0x000, 0x002, 0x001, + 0x002, 0x000, 0x001, 0x001, 0x000, +]; +pub(crate) const COMBINING_MARK_KV: &[u32] = &[ + 0x1D165, 0x01B71, 0x0093B, 0x00D57, 0x00328, 0x11CB1, 0x1CF11, 0x11A0A, 0x01B82, 0xE01DC, + 0x01ABD, 0x02DEB, 0x11CAF, 0x1D172, 0x1CF3E, 0x114B8, 0x1CF40, 0x0A950, 0x114BA, 0x00748, + 0x16F7F, 0x020F0, 0x0A981, 0x101FD, 0x00FB1, 0x0102F, 0x01CD6, 0x1DA08, 0x00FA2, 0x11A57, + 0x1612D, 0x00A41, 0x006E3, 0x00898, 0x01BA4, 0x112E7, 0x16F70, 0x01BF3, 0x16F6B, 0x0106B, + 0x0A675, 0x1DA5B, 0x10D6B, 0x11EF3, 0x1CF25, 0x02DF7, 0x11A97, 0x0A8EB, 0x1BC9E, 0x0FE2E, + 0x1133E, 0x00334, 0x111B7, 0x16F5F, 0x0105E, 0xE0112, 0x00656, 0x11C98, 0x10D6A, 0x11726, + 0x0A94B, 0x0FE2D, 0x1DA50, 0x00A4B, 0x119DD, 0x0032F, 0x00A3F, 0x00C02, 0x11835, 0xE0128, + 0x11300, 0x01ACB, 0x1DA19, 0x0A802, 0x01DD5, 0x11C3A, 0x112E0, 0x0A8B7, 0x00EB7, 0x017DD, + 0x01A7B, 0x02DE5, 0x00EB1, 0x1DA69, 0x00FA9, 0x0A8E6, 0x00C3F, 0x0A8EA, 0xE0156, 0x1DAAD, + 0x0109B, 0xE017F, 0x11A90, 0x017BF, 0x02DF1, 0x01A66, 0x006D6, 0x007AC, 0xE01E9, 0x01934, + 0x0A92A, 0x1DA04, 0xE01CE, 0x111BE, 0x10A01, 0x01DFD, 0xE0141, 0x11236, 0x00D3E, 0x0FE25, + 0x00741, 0x1E947, 0xE0191, 0x00311, 0x16F82, 0x01A75, 0x02DEC, 0x00F3E, 0x020D7, 0x1DA48, + 0x1D182, 0x00303, 0x01B37, 0x1DA9F, 0x11A8F, 0x01036, 0x00AC0, 0x01BA1, 0xE0120, 0x116B6, + 0x110B7, 0x01DEC, 0x00351, 0x00B02, 0x16F61, 0x01A7C, 0x114B5, 0x16F80, 0x11182, 0x00CF3, + 0x11CAA, 0xE0198, 0x00DD8, 0x0A9B7, 0x00ECA, 0x02DF8, 0x0A8C5, 0x0AA4C, 0x008DC, 0x01064, + 0x01C29, 0x0093E, 0x009BC, 0x01CD1, 0x1145E, 0x1DA42, 0x1143D, 0x110B1, 0x1E08F, 0x11A04, + 0x1CF26, 0x1CF13, 0x00ACC, 0x10F4D, 0xE0104, 0x00823, 0xE01D4, 0x005A6, 0x11442, 0x00AC7, + 0x11C9A, 0x0AABE, 0x11369, 0x16F72, 0xE01C7, 0x10A0F, 0x01A76, 0x11A03, 0x0061A, 0x11044, + 0x01733, 0x00318, 0x0A826, 0x1CF31, 0x11F41, 0x10F4A, 0x00315, 0x00F37, 0x017B6, 0x111CA, + 0x1171F, 0x10D69, 0x01CD7, 0x00364, 0x10F48, 0x00C81, 0x01A5A, 0x1DA11, 0x01CF4, 0x01DEF, + 0x11937, 0x11A53, 0x0103A, 0x1CF32, 0x01082, 0xE018C, 0x01AC5, 0x11CB6, 0x11635, 0xE010D, + 0xE0164, 0x1DA33, 0x0180D, 0x01AB1, 0x11370, 0x11C3E, 0x11CAE, 0x0ABE7, 0x11C95, 0x112E6, + 0x0033D, 0x0A8EE, 0x1DA0F, 0x01773, 0x0033C, 0x020D5, 0x0034A, 0x1DA34, 0x00819, 0x11362, + 0x00301, 0x01DFB, 0x00488, 0xE0165, 0x017B8, 0xE015B, 0x16122, 0x01DD4, 0x00F94, 0x00F7F, + 0x1DA58, 0x11A8B, 0x01DDA, 0xE017A, 0x01BE6, 0x1DA5E, 0x00E4B, 0x11720, 0x0A9B8, 0x10F82, + 0x0A9B6, 0x00744, 0x00C63, 0x11231, 0x00327, 0x00E38, 0x01939, 0x11F37, 0x00F18, 0x00340, + 0x116B3, 0x11002, 0x02DFF, 0xE0183, 0x1CF1D, 0x00FAD, 0x1DA2E, 0x115BF, 0x02DF0, 0x00337, + 0x1CF2D, 0x00B03, 0x1143B, 0x11373, 0x113C9, 0x16F92, 0x005BB, 0x00CCC, 0x01AC0, 0x01DF1, + 0xE01A4, 0x017CD, 0x13455, 0x11CA5, 0x007EF, 0x1DA28, 0x01073, 0x00F71, 0x11C9F, 0xE018F, + 0x1E001, 0x01ABA, 0x01933, 0x110B0, 0x1E948, 0xE01BB, 0x10378, 0x01ACD, 0x1E8D0, 0x11038, + 0x00BC7, 0x0093A, 0x01CE0, 0x00F77, 0x16F64, 0x02DEF, 0x1E2AE, 0xE0134, 0x01BEC, 0x11146, + 0x1DA64, 0x00D02, 0x114B2, 0x0FE2B, 0x0A928, 0x00AC9, 0x020DE, 0x01BEE, 0xE013D, 0xE0114, + 0x0A94D, 0x11A34, 0x1DA0D, 0xE01D7, 0x113B9, 0x0081F, 0x116B4, 0x0A8E4, 0x10AE6, 0x017B7, + 0xE0103, 0x00940, 0x11636, 0x00C62, 0x119D6, 0x16FF1, 0x01DE1, 0x01A68, 0x0065B, 0x00316, + 0xE0154, 0x0081C, 0x0A670, 0x1DA4B, 0x1E945, 0x1D17B, 0x01920, 0x16F5A, 0x0A80B, 0xE0148, + 0x0A8F1, 0x1DA4D, 0x009BE, 0x017C6, 0x1CF0A, 0x01A5E, 0x112E5, 0x00BBF, 0xE01E8, 0x114BF, + 0x01AC6, 0x00746, 0x1DA75, 0x1112B, 0x1E000, 0x00ECC, 0x00822, 0x1D1AA, 0x16F77, 0x11348, + 0x00FAC, 0x017BA, 0x00AC1, 0x01DE3, 0x0059F, 0xE01A8, 0x01AC3, 0x00FAE, 0x111B3, 0x11728, + 0x0AABF, 0xE012A, 0x116AC, 0x00F76, 0x119E0, 0xE0106, 0x0030B, 0x02DF9, 0x005B3, 0x00341, + 0x1DA62, 0x01A60, 0x1E8D1, 0x01CF8, 0x1E5EF, 0x112E4, 0x1DA32, 0x1163E, 0x00F84, 0xE017C, + 0x00611, 0x008FD, 0x01ABF, 0x1DA53, 0x00483, 0x1CF41, 0x0085A, 0x017C4, 0x1DA1D, 0xE01E7, + 0x00326, 0x1DA10, 0xE01D8, 0x11C9E, 0x11832, 0x01DC4, 0x00366, 0x11D8C, 0x16AF2, 0x11C3F, + 0x11A8A, 0x0ABEC, 0x11D47, 0x01DE0, 0x00597, 0xE014F, 0x006DF, 0x111BC, 0x0AA2F, 0x0ABEA, + 0x01B42, 0x00D62, 0x01087, 0xE01D0, 0x1DA06, 0x115C0, 0x0089B, 0x11933, 0x017C2, 0x0A69F, + 0x01926, 0x110B5, 0x017CA, 0x11073, 0x11102, 0x1D180, 0x01B6F, 0x0AAEB, 0x00ABE, 0x10EFD, + 0x02DFB, 0x00AE3, 0x00C4D, 0x01930, 0x01ACC, 0x00ABC, 0x01032, 0x00DF3, 0xE01EF, 0x00A03, + 0x1DA57, 0x0030F, 0x1DAA1, 0x008F9, 0x020E5, 0x1DA23, 0x10F83, 0x008F5, 0x00343, 0x005B2, + 0x02D7F, 0x11932, 0x020E2, 0x11F39, 0x1E018, 0x00D00, 0x0031A, 0x017BE, 0x10D27, 0x01753, + 0x020D3, 0x00FB5, 0x02DEE, 0x00D82, 0x0033F, 0x00734, 0x1CF35, 0x11235, 0x116AE, 0xE016E, + 0x0036A, 0x16F65, 0xE01BD, 0x0AA43, 0x11D35, 0xE0195, 0x01DF8, 0x00B3E, 0x00F86, 0x113BD, + 0xE018E, 0x11A8E, 0x0A8BA, 0xE016C, 0x01A71, 0x11F34, 0x01084, 0x01DC9, 0x1CF37, 0x1CF1A, + 0x113BA, 0xE0122, 0x11C3C, 0x00304, 0x008E6, 0x11A35, 0x01CE4, 0x017B9, 0x0FE2C, 0x0FE0F, + 0x1DA27, 0x11A51, 0x1DA1B, 0x16AF0, 0x11A07, 0x00DDB, 0x1DAA5, 0x10A02, 0x0FE0C, 0x01DCF, + 0xE01DE, 0x006EC, 0x1DA14, 0x112E1, 0x0A927, 0x11A38, 0x007AB, 0x005B5, 0x1D244, 0x0A9BE, + 0x1E002, 0x11831, 0x01886, 0xE0169, 0xE0184, 0x1DA4A, 0x10A3F, 0x11128, 0x00595, 0x008DF, + 0x16B31, 0x113BC, 0x0064C, 0x00658, 0x01DC2, 0x1E020, 0x113CC, 0x02DE6, 0x006DB, 0x007A8, + 0x00821, 0x11633, 0x0A8B4, 0x008CF, 0xE0102, 0x0A823, 0x017D3, 0x01AC4, 0x11836, 0xE0151, + 0x005BD, 0xE0117, 0x01BA2, 0x1CF3C, 0x00CBC, 0x16F81, 0x1D18B, 0x017BD, 0x00346, 0x1DA5D, + 0x11CA7, 0xE0171, 0x0AAC1, 0x00CBE, 0x0A953, 0x01C30, 0x00329, 0x0089F, 0x008FA, 0x11725, + 0x1136B, 0x01CDC, 0x11070, 0x008F6, 0x00308, 0x01BEB, 0x11233, 0xE0136, 0x00F3F, 0x1CF09, + 0xE0100, 0x01DF3, 0x01035, 0x0102D, 0x00314, 0x008E1, 0x01DCE, 0x00A02, 0xE0157, 0xE0193, + 0x13451, 0x11D3A, 0x00CC4, 0x0034E, 0x00733, 0x11C2F, 0x16F62, 0x111BB, 0x01B72, 0x007AF, + 0x0036B, 0x00731, 0x008D3, 0x13453, 0x16F60, 0x01CF9, 0xE012D, 0xE0197, 0x00CCA, 0x00616, + 0x0FE01, 0x01BE7, 0xE0177, 0x10A0D, 0x01B6E, 0x01DCD, 0x1E004, 0x008D8, 0x11723, 0xE0168, + 0x11130, 0x01C28, 0x11C3D, 0x0064F, 0x0AAEC, 0x1DA40, 0x11C31, 0x01DCB, 0x01923, 0x11D34, + 0x008FF, 0xE01D5, 0x0034F, 0x16121, 0x01B44, 0x0A948, 0xE01DA, 0x1612F, 0x00650, 0x0AA35, + 0x00305, 0x020E8, 0x01752, 0x00AC4, 0x0A827, 0x1172A, 0x005AF, 0x01DC1, 0x11F3E, 0x1D189, + 0x1DA49, 0x11D45, 0x01C2E, 0x01037, 0xE01BE, 0xE01A3, 0x0A672, 0x0A8E3, 0x115B4, 0x11CAD, + 0x01DD2, 0x10EFF, 0x0064E, 0x0082C, 0x1611E, 0x0FE29, 0x00323, 0x00899, 0x00CD6, 0x00489, + 0x008CC, 0x01922, 0x00A82, 0x0ABE8, 0x01B01, 0x16F63, 0x0064D, 0x1DAAB, 0x017D2, 0x0FE26, + 0x00D3C, 0xE010A, 0x119DF, 0x1D171, 0x0A881, 0x01A56, 0x114C2, 0xE0113, 0x1D186, 0x11CB4, + 0x10377, 0x11A3C, 0x1E015, 0x00F9F, 0x0A8C1, 0x00B57, 0x16127, 0x0AA7C, 0x115BA, 0xE0127, + 0x00332, 0x11145, 0xE0179, 0xE0135, 0x00C4C, 0x008CE, 0x01A7F, 0x0031C, 0x006E1, 0x1E8D6, + 0xE0145, 0x00F93, 0x00362, 0x00596, 0x00347, 0x00317, 0x00670, 0xE0160, 0x00735, 0x10F4F, + 0x111C9, 0x11041, 0x1DA0E, 0x01928, 0x0FE06, 0x005C2, 0x005C4, 0x113E2, 0x1CF0D, 0x1CF1C, + 0x020DF, 0x00B4D, 0x0A67C, 0x00C41, 0xE0125, 0x11234, 0x0032C, 0x11D8E, 0x0106A, 0x00D3B, + 0x115DD, 0x00946, 0x00AC2, 0x01BAD, 0xE0196, 0x01714, 0x1344D, 0x0A94F, 0x1CF01, 0x00599, + 0x01ABB, 0x1DA29, 0x00FBA, 0x11437, 0x020EA, 0x00B3C, 0x10A39, 0x113C7, 0x1CF43, 0x005AB, + 0x00EC8, 0x020E1, 0x008D0, 0x1D168, 0xE0176, 0xE0133, 0x0192A, 0x0082A, 0x1193D, 0x01772, + 0x1E949, 0x00DD1, 0xE01E5, 0x0A980, 0x111CE, 0x01DC0, 0x1E8D3, 0x1DA02, 0xE01CC, 0x00FB0, + 0x0094B, 0x0135F, 0xE01B3, 0x008D7, 0x00313, 0x16F5B, 0x00E4A, 0x00610, 0x114BB, 0x00CCB, + 0x1171D, 0x1DA2C, 0x01C37, 0x0180C, 0x00FAB, 0x0065A, 0x115B2, 0x01A74, 0x113CE, 0x00CD5, + 0x00BD7, 0x0105F, 0x00C43, 0x00947, 0x0FE2F, 0x0032E, 0x1E4ED, 0xE010C, 0x01DC7, 0x01A18, + 0x1612A, 0x0A951, 0x006E7, 0x111B9, 0x00F90, 0x0032A, 0x02DEA, 0x16124, 0x0A8F0, 0x00FA1, + 0xE01A9, 0x0036F, 0x00ECB, 0x0093C, 0x110B8, 0x00BBE, 0x11C99, 0x008E8, 0x0A8B5, 0x01B39, + 0x0035C, 0x1DA4F, 0x0036E, 0x00740, 0x01A70, 0x01062, 0x0033A, 0x1E5EE, 0x1122D, 0x00FB9, + 0x11D42, 0x017CC, 0x1D166, 0x11D91, 0x00CC8, 0x01A6B, 0x119D4, 0x112E9, 0x017C9, 0x1CF2C, + 0xE0126, 0x00AFD, 0x1DA15, 0x1E010, 0x01B04, 0x0A8BE, 0x00BC0, 0x017B4, 0x01071, 0x11C94, + 0x119DC, 0x11371, 0x005C5, 0x11363, 0x11A54, 0x01CD4, 0x008D4, 0x11301, 0x1E2EC, 0x01A5B, + 0x11134, 0x005BF, 0x00B4C, 0x01A65, 0xE0180, 0x1182C, 0x16F73, 0x11C35, 0x00FA4, 0x01DCC, + 0x115BD, 0xE016D, 0xE0159, 0xE010E, 0x00D40, 0x1CF19, 0xE015F, 0x00903, 0x00C48, 0x01734, + 0x1DA43, 0x00825, 0x0FE22, 0x00ECD, 0x00333, 0x01B3A, 0x0089D, 0x018A9, 0x00E4D, 0x00312, + 0x1172B, 0x119DE, 0x0034C, 0x1103C, 0x00829, 0x1CF42, 0x1DAA2, 0x009C7, 0x00957, 0x119D1, + 0x11CA3, 0x1CF08, 0x00AC3, 0xE0166, 0x00D81, 0xE01D3, 0x1DA09, 0x00BCC, 0x02DED, 0x11A8D, + 0x008E4, 0x00FA0, 0x1E135, 0x00F7E, 0x102E0, 0x00659, 0x00D63, 0x16F66, 0x008EA, 0x00A3E, + 0x00732, 0xE01AB, 0x01072, 0x020ED, 0x00E35, 0x11639, 0x00F7B, 0x110C2, 0x01CDE, 0x1E028, + 0x113E1, 0x113BE, 0x11368, 0x114B0, 0x1136A, 0x008E7, 0x1DA66, 0x01088, 0x1E4EC, 0x0A952, + 0x0073C, 0x11374, 0x0073F, 0x1171E, 0x00B3F, 0xE01B5, 0x1182F, 0x11082, 0xE0146, 0x005B6, + 0x1E2ED, 0x11D8D, 0x01063, 0x1DAA6, 0x01B3F, 0x115B1, 0x00A3C, 0x01A5C, 0x113D2, 0x1D1AC, + 0x0A8EF, 0x0FE21, 0x115BB, 0x11830, 0x00FBB, 0x0ABED, 0x00C04, 0x020D4, 0x0A6F0, 0x0089E, + 0x0059B, 0x16B32, 0xE018B, 0x00FAA, 0x0109C, 0x00827, 0x01DD9, 0x13440, 0x01925, 0x0031B, + 0x01712, 0xE014A, 0x020D2, 0x0A677, 0x114C1, 0x1E003, 0x00CC1, 0x1112F, 0x00DCA, 0x1143F, + 0x11C30, 0x00613, 0x0AAF5, 0x10F4C, 0x02DE9, 0x1E131, 0xE018A, 0x1037A, 0x01DFF, 0x00816, + 0x16123, 0x00747, 0x00B47, 0x1136C, 0x111B8, 0x00D03, 0x112EA, 0x01038, 0xE01B9, 0x11133, + 0x1CF23, 0x0AA4D, 0x11230, 0x00C83, 0x00743, 0xE0150, 0x11F36, 0x0193A, 0x017CE, 0x01C31, + 0x01AB5, 0x11D94, 0x0A983, 0x00CCD, 0x00AFC, 0x11931, 0x1CF07, 0x1134B, 0x13452, 0x00CC3, + 0x0089C, 0x00F87, 0x00AC8, 0xE016B, 0x0102C, 0x1DA00, 0x00486, 0x00EB6, 0x11D43, 0x01031, + 0x114B9, 0x11040, 0x0A8FF, 0x11935, 0x1CF3D, 0x119D2, 0x10EAC, 0x11A08, 0x00F8E, 0x00DD0, + 0x00730, 0x0A9E5, 0xE0194, 0x00DD4, 0x11940, 0x1CF04, 0x1344E, 0xE0190, 0x017C8, 0xE01CF, + 0x00820, 0x009C2, 0x02DFE, 0x11080, 0x0A671, 0x1E009, 0x1DA61, 0x00C3C, 0x00944, 0x0034D, + 0x00FB3, 0x119DA, 0x0A9BB, 0x008F2, 0x01DF6, 0x00A42, 0x116B0, 0x11729, 0x0302C, 0x01A58, + 0x16F76, 0x1E00E, 0x01AB4, 0x01DE7, 0x020EC, 0x10A38, 0x00A51, 0xE01C5, 0x10F47, 0x01938, + 0x00D44, 0x005A2, 0x1E01D, 0x01DCA, 0x007AD, 0x1DA59, 0x1163C, 0x16F7B, 0x01C34, 0x116B5, + 0x00306, 0xE01CD, 0x02DFD, 0x1DAAE, 0x00E4C, 0x1CF1F, 0x00BCA, 0x1133F, 0x11938, 0x11344, + 0x16125, 0x1E944, 0x01DDE, 0xE010B, 0xE011D, 0x10F4B, 0x00B48, 0x00DDD, 0x11727, 0x00592, + 0x16B30, 0x005B7, 0x00355, 0x00D4B, 0x1D1AD, 0xE012B, 0x13447, 0xE0101, 0x01DF2, 0x02DFA, + 0x01C2B, 0x01B40, 0x11357, 0x11100, 0x008ED, 0xE0109, 0x1DA03, 0x0FE28, 0x11722, 0x01CE6, + 0x005B0, 0x00615, 0x1DAA8, 0x00342, 0x00BCB, 0x11042, 0x01CD8, 0x01A17, 0x01C2A, 0x00F79, + 0x1112A, 0x11C3B, 0x01CE8, 0x1DA24, 0xE0189, 0xE01EE, 0x11D3D, 0x00FBC, 0x00367, 0x116B1, + 0x11074, 0x0A66F, 0x0031F, 0x11237, 0x01DF9, 0x01DE5, 0x01ABE, 0x0074A, 0x00F75, 0x10376, + 0x115B3, 0x0AA2C, 0x00DCF, 0xE013A, 0xE019F, 0x11C38, 0x1183A, 0x00A75, 0x00484, 0x119D7, + 0x00D46, 0x008DB, 0x0032B, 0x0FB1E, 0x1123E, 0x110B4, 0x11C9D, 0x1CF46, 0x1D16D, 0x00AE2, + 0x01058, 0x0106D, 0x1143C, 0x01DDF, 0x16120, 0xE015A, 0x00338, 0x01CDA, 0x00591, 0x00B56, + 0x1D187, 0x00737, 0x00F9A, 0x00CC2, 0x01B6C, 0x01DD0, 0x00CC0, 0x00A83, 0x11D97, 0x006D8, + 0x01B34, 0x00FA6, 0x116AD, 0x00DF2, 0x1163D, 0x0192B, 0x020E4, 0x10F84, 0xE0119, 0x008DD, + 0x006EB, 0x01059, 0x16F75, 0x00983, 0x00963, 0x02CF1, 0x1E130, 0x00300, 0x113CD, 0x0A6F1, + 0xE0143, 0x0FE0B, 0x02DF2, 0x006ED, 0x017C1, 0x01C2C, 0x005A7, 0x16F86, 0x00952, 0x01A62, + 0x01A19, 0x16FE4, 0x01DEE, 0x0180F, 0x1DA65, 0x0109D, 0x03099, 0x11A91, 0x006E8, 0x01AB7, + 0x01DD3, 0x1D16E, 0x007B0, 0xE0105, 0x00352, 0x0A9BF, 0x1E017, 0x00D41, 0x0059D, 0x01DF7, + 0x0A8BC, 0x005C1, 0x0A8ED, 0x11101, 0x11438, 0x11EF5, 0x007A7, 0x1DA35, 0x11A59, 0x00307, + 0x1E008, 0x10A05, 0xE01C8, 0x1CF14, 0x11444, 0x0033E, 0x008E9, 0x00ACB, 0x16F58, 0xE01C1, + 0x16F6D, 0x00B62, 0x01A73, 0x01CE7, 0x16F57, 0x01C36, 0x01060, 0x11D93, 0x11C96, 0x0035E, + 0x00F9C, 0x11A92, 0xE0181, 0x16AF4, 0x1DAA9, 0x00F7C, 0x1DA55, 0x1E01E, 0x01ACE, 0x11CA4, + 0x0135D, 0x00357, 0x0094E, 0x020D0, 0x11343, 0xE01AD, 0x1D1AB, 0x00EB9, 0xE0172, 0x00593, + 0x00D4A, 0x0AA31, 0xE01ED, 0x0089A, 0xE01A0, 0x11D96, 0x00948, 0x0A67A, 0x1E4EF, 0x01BEF, + 0x00F8F, 0x0A824, 0xE017E, 0x1DA4E, 0x00B82, 0x00CC7, 0x020DB, 0x13448, 0x00A40, 0x0A94E, + 0x11837, 0x10F49, 0x01083, 0xE0188, 0x1DA1F, 0x1D17C, 0x0A678, 0x00DDA, 0x006D7, 0x110B2, + 0x00826, 0x0A82C, 0x01CDF, 0x0AA2D, 0x009C4, 0x008E5, 0xE011C, 0x00E4E, 0x0A8E0, 0x1612B, + 0xE015C, 0x11F00, 0x01B02, 0x0A9BD, 0x11443, 0x1E026, 0x0A9B9, 0x0A94A, 0xE01D6, 0x01B73, + 0x1DA63, 0x13454, 0x11A96, 0x1D167, 0x11001, 0x1DA51, 0x113C5, 0x11F3A, 0x1D17E, 0x11D3F, + 0x00D01, 0x01A1A, 0x11439, 0x11A06, 0x01DF0, 0xE013B, 0x00F19, 0x00DD6, 0xE0167, 0x16F6F, + 0x00F72, 0x16F79, 0x00F81, 0x00A71, 0x119D5, 0x1103D, 0x1DA41, 0x01DDB, 0x0093F, 0x0FE00, + 0x008F7, 0x00B40, 0x00949, 0x0A9C0, 0x1103A, 0xE014E, 0x0A67B, 0xE0118, 0x01DEA, 0xE0107, + 0x1193C, 0x115BC, 0x01BA3, 0x00E34, 0x11366, 0x1CF3A, 0xE01DB, 0x0A929, 0xE01B1, 0xE0163, + 0x119E4, 0x00324, 0x01B6D, 0x017C0, 0x020DD, 0x01DD8, 0x0FE27, 0x11A93, 0x10D24, 0x114BD, + 0x0302A, 0x1CF1B, 0x1344F, 0x0081B, 0x1DA2A, 0x00309, 0x1CF29, 0x01DE4, 0x0A8BB, 0x113BB, + 0x00FC6, 0x11045, 0xE0147, 0x00FA8, 0x017CF, 0x00EBC, 0x00C55, 0x01A6A, 0x0A92C, 0x00941, + 0x11046, 0x01DE8, 0xE019C, 0x10D6C, 0x11EF4, 0x020E9, 0x0059A, 0x00D4C, 0x0031D, 0x01C33, + 0xE0140, 0x1107F, 0x00E39, 0x01CED, 0x1DA47, 0x005AD, 0xE01C9, 0x01AC8, 0x00901, 0x1D185, + 0x1DA1A, 0x1D181, 0x01ACA, 0x11CA9, 0x10A0C, 0x11A3B, 0x00953, 0xE01E0, 0x00ABF, 0xE011F, + 0x009E2, 0xE0111, 0x005A0, 0x11833, 0x1DA05, 0x115AF, 0x0302D, 0x113C2, 0xE012C, 0x0082D, + 0x1143E, 0xE01D2, 0x00B41, 0x01A55, 0x00302, 0x113CF, 0x00FB4, 0x0AAB0, 0x16F87, 0x01DC6, + 0x0AA32, 0xE0130, 0x020E7, 0x008DE, 0x007A9, 0x00739, 0x10F46, 0xE01AE, 0x114BC, 0x02CF0, + 0x11A47, 0x01A67, 0x1D170, 0x01A61, 0x00DDE, 0x1E012, 0x0135E, 0x0065E, 0x00DD9, 0xE0199, + 0xE013C, 0x1DA68, 0x11A05, 0x01929, 0x16F6C, 0x11F03, 0x16B35, 0x0A8C0, 0x005AA, 0x10AE5, + 0x00B01, 0x16AF3, 0x0FE07, 0x00FAF, 0x1DA26, 0x10D26, 0x1E00C, 0x0081E, 0x1DA3F, 0x01CD0, + 0x01BAC, 0xE0178, 0x01B36, 0x00C47, 0x0180B, 0x00654, 0x01DDC, 0x008EC, 0x1DA5F, 0x16F90, + 0x01DFC, 0x0103E, 0x11F38, 0x16FF0, 0x01DD7, 0xE015E, 0x00B55, 0x00614, 0x0030A, 0x1163B, + 0x11D95, 0x01074, 0xE0142, 0x00F99, 0xE01A6, 0x1163A, 0x1CF45, 0x1CF0F, 0xE0158, 0x0FE0E, + 0x0A825, 0x0108B, 0x00E49, 0x020D9, 0x1E00A, 0x1CF16, 0x0AAEE, 0x1E01B, 0x16F78, 0x10F4E, + 0xE019E, 0x16B34, 0x008EE, 0xE01C3, 0x00320, 0x11C33, 0x16F69, 0xE0132, 0x1103E, 0x0ABE3, + 0x00945, 0x00902, 0x1DA5A, 0x11446, 0x00C40, 0x1DA30, 0x0073E, 0xE012F, 0x11C9B, 0x11C36, + 0x007FD, 0x00360, 0x00E3A, 0x116AF, 0x01C32, 0x0A8E2, 0x005B1, 0x1122C, 0x0103B, 0xE013F, + 0x00BC2, 0x11C34, 0x11081, 0x02DF4, 0x119DB, 0x11631, 0x01A6D, 0x16F55, 0x00B44, 0x16B36, + 0x01DFE, 0x11A02, 0x1E8D4, 0x0AAEF, 0x00AFE, 0x020EB, 0x005A5, 0x1CF18, 0x00ACD, 0x11445, + 0x115B5, 0x16F53, 0x005A1, 0x00F95, 0x0FE09, 0xE01E3, 0x111B6, 0x00EB8, 0x1CF10, 0x1DA3E, + 0x1E00B, 0x0102E, 0x006EA, 0x11A95, 0x11435, 0x00D47, 0x00CE2, 0x00F74, 0x11043, 0xE0124, + 0x113BF, 0x008D6, 0x11A52, 0x11A8C, 0xE01CA, 0x00FA3, 0x1E00F, 0x11EF6, 0x16F7A, 0x111BA, + 0x1CF2B, 0x0A8E7, 0x1E00D, 0x1CF3F, 0x0ABE6, 0x005A3, 0x00A70, 0x01885, 0x0034B, 0x1E011, + 0x00FB8, 0x01A6F, 0x01CD2, 0xE011A, 0x01030, 0x16F7E, 0x16F5D, 0x11D90, 0x00349, 0x01AB9, + 0x1E02A, 0x007EE, 0x01B3D, 0x0106C, 0x11CA6, 0x0033B, 0x01039, 0x020E3, 0x11A55, 0x00736, + 0x01B6B, 0x1344C, 0x007AA, 0x00BCD, 0x008CD, 0x11039, 0x01AB3, 0x1DAAA, 0x0030D, 0x01089, + 0x0302B, 0x01A6C, 0x11131, 0x0A8E9, 0xE01EB, 0x1DA21, 0x1DA45, 0x00C4B, 0x02DF3, 0x1DAAF, + 0x020D6, 0x0A94C, 0x00C03, 0x01A78, 0x00EB5, 0xE011B, 0x02DE7, 0xE0138, 0x11232, 0x16F56, + 0x1CF0B, 0xE0144, 0x13449, 0x1DA0C, 0x01BED, 0x0A982, 0xE01A5, 0x1CF06, 0x16F85, 0x0A679, + 0x008CB, 0x0A8BF, 0x0064B, 0x1DA3D, 0x1E8D5, 0x00E47, 0x01069, 0x008D2, 0x113B8, 0x00335, + 0x01713, 0x01A5D, 0x00C82, 0x0A67D, 0x1CF33, 0x11CB0, 0xE0153, 0x00897, 0x16F8F, 0x11A5A, + 0x11724, 0x1E016, 0x0103D, 0x01B3E, 0x01DC8, 0x16B33, 0x01937, 0x01A6E, 0x10A3A, 0x01BAA, + 0x01B43, 0x0FE0A, 0x020D8, 0xE014C, 0x02DF6, 0x1CF15, 0x020EE, 0x00942, 0xE0162, 0x009C1, + 0x00653, 0x0FE08, 0x1D17F, 0x017C5, 0x008CA, 0x1DA9B, 0x005BA, 0x00BC6, 0x00C42, 0x00738, + 0x11632, 0x1DA18, 0x008F8, 0x005AE, 0x116B7, 0x1134C, 0x11834, 0x0085B, 0x005C7, 0x11943, + 0x0A9B4, 0x1E029, 0x11A01, 0x020E0, 0x1103F, 0x00612, 0x01BA7, 0x00365, 0x0073B, 0x009D7, + 0x0193B, 0x11838, 0x01067, 0x0FE04, 0x11D32, 0x01DD6, 0x1DA2B, 0x0FE24, 0x01A7A, 0xE016A, + 0x0FE02, 0x16F6A, 0x1344B, 0x113CA, 0x11241, 0x110BA, 0x00C3E, 0x007AE, 0x0030C, 0xE0185, + 0x01AC9, 0x01C26, 0x1DA6A, 0x11436, 0x00331, 0x1CF27, 0x11367, 0xE0139, 0x00859, 0x01927, + 0x1CF02, 0x1DA9C, 0xE01B0, 0x111BF, 0x16128, 0x01DEB, 0x0AA30, 0xE0174, 0x1DAA4, 0x01ABC, + 0x00CC6, 0x01B38, 0x1DA5C, 0x020DC, 0x00C4A, 0x1CF34, 0x11D8B, 0x16129, 0x00955, 0x0AAED, + 0x10EAB, 0x017C7, 0x01BA8, 0x0AA2E, 0x1D16F, 0xE0116, 0x017BC, 0x0AAB3, 0xE01B7, 0x01BE9, + 0x1E006, 0x1E4EE, 0x01B70, 0x00325, 0xE0186, 0x0A92D, 0x11930, 0x111B5, 0x01A72, 0x1DA44, + 0xE01E6, 0x1DA1C, 0x005AC, 0x01B41, 0x10A03, 0x00363, 0x114C0, 0xE0123, 0x008E0, 0x01936, + 0x00D4D, 0x00C56, 0x00DDC, 0x11A39, 0x1E2EF, 0x006DC, 0x017D0, 0x1D242, 0x00359, 0x0A8E1, + 0x1CF05, 0x0094C, 0x01BF1, 0x008EF, 0x16AF1, 0x11634, 0xE0161, 0x1DA12, 0x020DA, 0x008D1, + 0x0094A, 0x008FB, 0x01BA6, 0x00D48, 0xE0108, 0x1E946, 0x00319, 0x017B5, 0x00339, 0x01DE2, + 0x11638, 0x0073A, 0x01057, 0x01CF7, 0x11173, 0x0309A, 0x1133B, 0x020EF, 0x112E2, 0x1E133, + 0x1DA52, 0x005B8, 0x00E37, 0x1D18A, 0x16F67, 0x1133C, 0x00598, 0x11A37, 0x00EBA, 0x111CB, + 0x0AAF6, 0x005B4, 0x02DF5, 0x11441, 0x114B7, 0x00353, 0x1163F, 0x008E3, 0x00651, 0x007F1, + 0x113D0, 0x0032D, 0x008FE, 0x115BE, 0x0AA34, 0x02DE1, 0x01B00, 0x006E4, 0x01CDB, 0x1CF03, + 0x01C25, 0x115B8, 0x11129, 0x00330, 0x00C01, 0x00943, 0x0A926, 0x1DA0A, 0x10D25, 0x008D9, + 0x0A9BC, 0x00322, 0x11C9C, 0xE0110, 0x13450, 0x00A47, 0x11F40, 0x01DC3, 0x01B3C, 0x1CF0E, + 0x01924, 0x0A676, 0x0036C, 0x007EC, 0x1D169, 0xE01E4, 0x00F7A, 0x00DD2, 0x1CF20, 0x11630, + 0x11347, 0x112E3, 0x01A59, 0x11D41, 0x11A36, 0xE0192, 0x0035B, 0x0065D, 0x00619, 0x00954, + 0xE0137, 0xE0149, 0x11F42, 0x00749, 0x01DF4, 0x1112D, 0x01CE1, 0x1CF3B, 0x1103B, 0x007F0, + 0xE01C0, 0x11D33, 0x00AFB, 0xE0175, 0x0AA33, 0x1DA3C, 0x0ABE5, 0x0ABE4, 0x02DE3, 0x1134D, + 0x009CC, 0x1DA9D, 0x01AC2, 0xE01A2, 0x11D44, 0xE0129, 0x11127, 0x115DC, 0x01B3B, 0x1CF36, + 0x00F97, 0x01CD5, 0x11D31, 0x00EB4, 0x1DA22, 0xE01EC, 0x10EFE, 0x00B63, 0x111C0, 0x1E013, + 0x11A56, 0x116B2, 0x0A947, 0x00BC8, 0x1DA16, 0x1DA6C, 0x008F0, 0x01BF2, 0x009BF, 0x11CA1, + 0x01CE2, 0xE01B4, 0xE012E, 0x01C2D, 0xE019D, 0x00F39, 0xE01AF, 0x1D188, 0x00D42, 0x01DD1, + 0x00BC1, 0x112DF, 0x0108A, 0x1182D, 0x1E014, 0xE01D1, 0x115B9, 0x16F4F, 0xE01C2, 0x11180, + 0xE017D, 0x01A57, 0x1CF00, 0x11A3D, 0x01921, 0x113C0, 0x00F82, 0xE01CB, 0x01CDD, 0x1DA01, + 0x0ABE9, 0x11303, 0x1E005, 0x11341, 0x00B4B, 0x11C39, 0x01AB2, 0x16F74, 0x114C3, 0x0A949, + 0x00617, 0x1CF17, 0x008EB, 0x005B9, 0x00745, 0x11CAB, 0x1DA36, 0x006E2, 0x16F54, 0x00C00, + 0x114BE, 0x01B81, 0x0102B, 0x1CF1E, 0x0A806, 0x0A880, 0x020E6, 0x01DF5, 0xE01D9, 0x0FE23, + 0x00487, 0x00F73, 0x01CE5, 0x11D36, 0x0081D, 0x1CF28, 0x11D40, 0x020D1, 0x0AA36, 0x0A8E5, + 0x110B6, 0x0A8C2, 0x11F5A, 0x11181, 0x00F35, 0x00D43, 0x0094D, 0x1193E, 0x1143A, 0xE0115, + 0x017D1, 0x1CF38, 0x0082B, 0x119D3, 0x00F80, 0x16F52, 0x005A4, 0xE0121, 0x008F4, 0xE01B2, + 0x00F83, 0x10EFC, 0x00ECE, 0x16F5E, 0x10A06, 0x11A98, 0x0A9BA, 0xE01B6, 0x1DA0B, 0x00F96, + 0x16F68, 0x00361, 0x00900, 0x16F7D, 0x00A81, 0x1612C, 0x1CF44, 0x0108C, 0x1DA60, 0x01B03, + 0x0A69E, 0x0094F, 0x11F01, 0x1CF24, 0x00951, 0x02DE4, 0x11A94, 0x11A58, 0x02DE8, 0xE01BF, + 0x111BD, 0x00EC9, 0x017C3, 0x0AA2A, 0x01B35, 0x00817, 0x1112C, 0x006DA, 0x009E3, 0x11372, + 0x00D83, 0x11CAC, 0x01BA9, 0x16F71, 0x1DAAC, 0x0AAB8, 0x00CE3, 0x00652, 0x11340, 0x16F5C, + 0x11000, 0x00FA7, 0x007A6, 0x11640, 0x11637, 0x11A3E, 0x008F1, 0x009FE, 0x11CA2, 0x0A8B9, + 0x01A79, 0x0A8BD, 0x01C2F, 0x01068, 0x01DE9, 0x0AA7D, 0x00A48, 0x01A77, 0x11132, 0x00345, + 0x110B9, 0x01931, 0x10379, 0x0FE2A, 0x1DA6B, 0x01AC1, 0xE01BC, 0x00354, 0x01085, 0x11942, + 0x11F35, 0x009C0, 0x00344, 0xE01EA, 0x1DA20, 0x0302F, 0x0031E, 0x00FA5, 0x1CF0C, 0xE01A1, + 0xE01C6, 0x00350, 0x01CE3, 0x0103C, 0x02DFC, 0x11342, 0x01A63, 0xE0173, 0x1CF21, 0xE019B, + 0x00A01, 0xE014D, 0x00DDF, 0xE019A, 0x01AC7, 0x1D243, 0xE01DF, 0x0FE0D, 0x11302, 0xE01E1, + 0x1D17D, 0x1DA17, 0x111CC, 0x0035F, 0x00962, 0x11D8A, 0x113C8, 0x0A9B3, 0x00818, 0x00356, + 0x00B43, 0x1DAA7, 0x11721, 0x0AAB7, 0x111CF, 0x00956, 0xE01C4, 0xE013E, 0x008DA, 0x00B42, + 0x1CF12, 0x0FE03, 0x11A99, 0x01DFA, 0x01DC5, 0x11CB3, 0x1DA67, 0xE0155, 0xE0131, 0x16F51, + 0x1182E, 0x1DAA3, 0x00657, 0x16F84, 0x00982, 0x114B3, 0x005BC, 0x00594, 0x008FC, 0x01B80, + 0xE017B, 0x01BF0, 0x02CEF, 0x007F2, 0x00D3F, 0x009C8, 0x01BAB, 0x1CF39, 0x00F91, 0x00AFA, + 0xE016F, 0x0109A, 0x16F7C, 0x005A9, 0x00FB6, 0x00A4D, 0x0A8C3, 0x008F3, 0x10F85, 0x1193B, + 0x00A4C, 0x11CA0, 0x0A9B5, 0x1E01C, 0x0A8E8, 0x0108D, 0x1DA46, 0x006D9, 0xE0152, 0x00711, + 0x01DE6, 0x01A64, 0x01AB0, 0x01CD9, 0x00F9B, 0x00F9D, 0x00E31, 0x110B3, 0xE011E, 0x10F50, + 0x01932, 0x00742, 0x0108F, 0x0AA2B, 0x01BA5, 0x1BC9D, 0x00E36, 0x00310, 0x1E134, 0x0065F, + 0x16F59, 0x0FE20, 0x1CF22, 0xE01A7, 0x0059C, 0x0035A, 0x1611F, 0x1E027, 0xE0182, 0x00321, + 0x0302E, 0x1CF30, 0xE015D, 0x00FB7, 0x01056, 0x00E48, 0xE01AC, 0x114B1, 0x01AB8, 0x00F92, + 0x1DA31, 0x16F6E, 0x11C92, 0x16126, 0x00368, 0x00C46, 0x00FB2, 0x11A33, 0x00655, 0x01A69, + 0x11440, 0x02DE2, 0x00369, 0x1344A, 0x1DA2D, 0x1E024, 0x0FE05, 0x112E8, 0x0A8B8, 0x0A92B, + 0x11839, 0x0059E, 0x116AB, 0x0AA29, 0x017BB, 0x01C35, 0x00336, 0x1DA25, 0x16F91, 0x00618, + 0x00F78, 0x0035D, 0x1DA2F, 0x0073D, 0x01033, 0x111B4, 0x1612E, 0x01715, 0x1DA54, 0x11CB5, + 0x1122F, 0x1DA13, 0xE01DD, 0x11C32, 0x1DA1E, 0x1DA56, 0x0AAB4, 0x00358, 0x11C97, 0x01DDD, + 0x00981, 0x00F8D, 0xE0187, 0x008D5, 0x01A1B, 0x00EBB, 0x00485, 0x11934, 0x02DE0, 0x1112E, + 0x01034, 0x11C93, 0x007ED, 0x0A674, 0x0A8B6, 0x00C44, 0x1CF2A, 0x115B0, 0x11A5B, 0x11D3C, + 0xE014B, 0x00DD3, 0xE01AA, 0xE01E2, 0x0A8EC, 0xE0170, 0xE01B8, 0x1122E, 0x10A0E, 0xE01BA, + 0x006E0, 0x00CBF, 0x005A8, 0xE018D, 0xE010F, 0x1DA4C, 0x007F3, 0x00F9E, 0x1E136, 0x1DA84, + 0x1E8D2, 0x11F3F, 0x00348, 0x1E132, 0x009C3, 0x1E2EE, 0x0030E, 0x0065C, 0x0036D, 0x11CB2, + 0x01BEA, 0x01935, 0x0AA7B, 0x01732, 0x11A09, 0x00AC5, 0x0A8C4, 0x01C24, 0x01AB6, 0x007EB, + 0x017CB, 0x01DED, 0x1DA3B, 0x1E021, 0x00F7D, 0x1E01F, 0x01086, 0x009CD, 0x10D6D, 0x1DA07, + 0x114B4, 0x01BE8, 0x16F83, 0x009CB, 0x01C27, 0x1DA9E, 0x114B6, 0x00AFF, 0x0AAB2, 0x1E94A, + 0x1E023, +]; +#[inline] +pub fn is_public_assigned(c: char) -> bool { + match c { + '\u{0000}'..='\u{0377}' + | '\u{037A}'..='\u{037F}' + | '\u{0384}'..='\u{038A}' + | '\u{038C}' + | '\u{038E}'..='\u{03A1}' + | '\u{03A3}'..='\u{052F}' + | '\u{0531}'..='\u{0556}' + | '\u{0559}'..='\u{058A}' + | '\u{058D}'..='\u{058F}' + | '\u{0591}'..='\u{05C7}' + | '\u{05D0}'..='\u{05EA}' + | '\u{05EF}'..='\u{05F4}' + | '\u{0600}'..='\u{070D}' + | '\u{070F}'..='\u{074A}' + | '\u{074D}'..='\u{07B1}' + | '\u{07C0}'..='\u{07FA}' + | '\u{07FD}'..='\u{082D}' + | '\u{0830}'..='\u{083E}' + | '\u{0840}'..='\u{085B}' + | '\u{085E}' + | '\u{0860}'..='\u{086A}' + | '\u{0870}'..='\u{088E}' + | '\u{0890}'..='\u{0891}' + | '\u{0897}'..='\u{0983}' + | '\u{0985}'..='\u{098C}' + | '\u{098F}'..='\u{0990}' + | '\u{0993}'..='\u{09A8}' + | '\u{09AA}'..='\u{09B0}' + | '\u{09B2}' + | '\u{09B6}'..='\u{09B9}' + | '\u{09BC}'..='\u{09C4}' + | '\u{09C7}'..='\u{09C8}' + | '\u{09CB}'..='\u{09CE}' + | '\u{09D7}' + | '\u{09DC}'..='\u{09DD}' + | '\u{09DF}'..='\u{09E3}' + | '\u{09E6}'..='\u{09FE}' + | '\u{0A01}'..='\u{0A03}' + | '\u{0A05}'..='\u{0A0A}' + | '\u{0A0F}'..='\u{0A10}' + | '\u{0A13}'..='\u{0A28}' + | '\u{0A2A}'..='\u{0A30}' + | '\u{0A32}'..='\u{0A33}' + | '\u{0A35}'..='\u{0A36}' + | '\u{0A38}'..='\u{0A39}' + | '\u{0A3C}' + | '\u{0A3E}'..='\u{0A42}' + | '\u{0A47}'..='\u{0A48}' + | '\u{0A4B}'..='\u{0A4D}' + | '\u{0A51}' + | '\u{0A59}'..='\u{0A5C}' + | '\u{0A5E}' + | '\u{0A66}'..='\u{0A76}' + | '\u{0A81}'..='\u{0A83}' + | '\u{0A85}'..='\u{0A8D}' + | '\u{0A8F}'..='\u{0A91}' + | '\u{0A93}'..='\u{0AA8}' + | '\u{0AAA}'..='\u{0AB0}' + | '\u{0AB2}'..='\u{0AB3}' + | '\u{0AB5}'..='\u{0AB9}' + | '\u{0ABC}'..='\u{0AC5}' + | '\u{0AC7}'..='\u{0AC9}' + | '\u{0ACB}'..='\u{0ACD}' + | '\u{0AD0}' + | '\u{0AE0}'..='\u{0AE3}' + | '\u{0AE6}'..='\u{0AF1}' + | '\u{0AF9}'..='\u{0AFF}' + | '\u{0B01}'..='\u{0B03}' + | '\u{0B05}'..='\u{0B0C}' + | '\u{0B0F}'..='\u{0B10}' + | '\u{0B13}'..='\u{0B28}' + | '\u{0B2A}'..='\u{0B30}' + | '\u{0B32}'..='\u{0B33}' + | '\u{0B35}'..='\u{0B39}' + | '\u{0B3C}'..='\u{0B44}' + | '\u{0B47}'..='\u{0B48}' + | '\u{0B4B}'..='\u{0B4D}' + | '\u{0B55}'..='\u{0B57}' + | '\u{0B5C}'..='\u{0B5D}' + | '\u{0B5F}'..='\u{0B63}' + | '\u{0B66}'..='\u{0B77}' + | '\u{0B82}'..='\u{0B83}' + | '\u{0B85}'..='\u{0B8A}' + | '\u{0B8E}'..='\u{0B90}' + | '\u{0B92}'..='\u{0B95}' + | '\u{0B99}'..='\u{0B9A}' + | '\u{0B9C}' + | '\u{0B9E}'..='\u{0B9F}' + | '\u{0BA3}'..='\u{0BA4}' + | '\u{0BA8}'..='\u{0BAA}' + | '\u{0BAE}'..='\u{0BB9}' + | '\u{0BBE}'..='\u{0BC2}' + | '\u{0BC6}'..='\u{0BC8}' + | '\u{0BCA}'..='\u{0BCD}' + | '\u{0BD0}' + | '\u{0BD7}' + | '\u{0BE6}'..='\u{0BFA}' + | '\u{0C00}'..='\u{0C0C}' + | '\u{0C0E}'..='\u{0C10}' + | '\u{0C12}'..='\u{0C28}' + | '\u{0C2A}'..='\u{0C39}' + | '\u{0C3C}'..='\u{0C44}' + | '\u{0C46}'..='\u{0C48}' + | '\u{0C4A}'..='\u{0C4D}' + | '\u{0C55}'..='\u{0C56}' + | '\u{0C58}'..='\u{0C5A}' + | '\u{0C5D}' + | '\u{0C60}'..='\u{0C63}' + | '\u{0C66}'..='\u{0C6F}' + | '\u{0C77}'..='\u{0C8C}' + | '\u{0C8E}'..='\u{0C90}' + | '\u{0C92}'..='\u{0CA8}' + | '\u{0CAA}'..='\u{0CB3}' + | '\u{0CB5}'..='\u{0CB9}' + | '\u{0CBC}'..='\u{0CC4}' + | '\u{0CC6}'..='\u{0CC8}' + | '\u{0CCA}'..='\u{0CCD}' + | '\u{0CD5}'..='\u{0CD6}' + | '\u{0CDD}'..='\u{0CDE}' + | '\u{0CE0}'..='\u{0CE3}' + | '\u{0CE6}'..='\u{0CEF}' + | '\u{0CF1}'..='\u{0CF3}' + | '\u{0D00}'..='\u{0D0C}' + | '\u{0D0E}'..='\u{0D10}' + | '\u{0D12}'..='\u{0D44}' + | '\u{0D46}'..='\u{0D48}' + | '\u{0D4A}'..='\u{0D4F}' + | '\u{0D54}'..='\u{0D63}' + | '\u{0D66}'..='\u{0D7F}' + | '\u{0D81}'..='\u{0D83}' + | '\u{0D85}'..='\u{0D96}' + | '\u{0D9A}'..='\u{0DB1}' + | '\u{0DB3}'..='\u{0DBB}' + | '\u{0DBD}' + | '\u{0DC0}'..='\u{0DC6}' + | '\u{0DCA}' + | '\u{0DCF}'..='\u{0DD4}' + | '\u{0DD6}' + | '\u{0DD8}'..='\u{0DDF}' + | '\u{0DE6}'..='\u{0DEF}' + | '\u{0DF2}'..='\u{0DF4}' + | '\u{0E01}'..='\u{0E3A}' + | '\u{0E3F}'..='\u{0E5B}' + | '\u{0E81}'..='\u{0E82}' + | '\u{0E84}' + | '\u{0E86}'..='\u{0E8A}' + | '\u{0E8C}'..='\u{0EA3}' + | '\u{0EA5}' + | '\u{0EA7}'..='\u{0EBD}' + | '\u{0EC0}'..='\u{0EC4}' + | '\u{0EC6}' + | '\u{0EC8}'..='\u{0ECE}' + | '\u{0ED0}'..='\u{0ED9}' + | '\u{0EDC}'..='\u{0EDF}' + | '\u{0F00}'..='\u{0F47}' + | '\u{0F49}'..='\u{0F6C}' + | '\u{0F71}'..='\u{0F97}' + | '\u{0F99}'..='\u{0FBC}' + | '\u{0FBE}'..='\u{0FCC}' + | '\u{0FCE}'..='\u{0FDA}' + | '\u{1000}'..='\u{10C5}' + | '\u{10C7}' + | '\u{10CD}' + | '\u{10D0}'..='\u{1248}' + | '\u{124A}'..='\u{124D}' + | '\u{1250}'..='\u{1256}' + | '\u{1258}' + | '\u{125A}'..='\u{125D}' + | '\u{1260}'..='\u{1288}' + | '\u{128A}'..='\u{128D}' + | '\u{1290}'..='\u{12B0}' + | '\u{12B2}'..='\u{12B5}' + | '\u{12B8}'..='\u{12BE}' + | '\u{12C0}' + | '\u{12C2}'..='\u{12C5}' + | '\u{12C8}'..='\u{12D6}' + | '\u{12D8}'..='\u{1310}' + | '\u{1312}'..='\u{1315}' + | '\u{1318}'..='\u{135A}' + | '\u{135D}'..='\u{137C}' + | '\u{1380}'..='\u{1399}' + | '\u{13A0}'..='\u{13F5}' + | '\u{13F8}'..='\u{13FD}' + | '\u{1400}'..='\u{169C}' + | '\u{16A0}'..='\u{16F8}' + | '\u{1700}'..='\u{1715}' + | '\u{171F}'..='\u{1736}' + | '\u{1740}'..='\u{1753}' + | '\u{1760}'..='\u{176C}' + | '\u{176E}'..='\u{1770}' + | '\u{1772}'..='\u{1773}' + | '\u{1780}'..='\u{17DD}' + | '\u{17E0}'..='\u{17E9}' + | '\u{17F0}'..='\u{17F9}' + | '\u{1800}'..='\u{1819}' + | '\u{1820}'..='\u{1878}' + | '\u{1880}'..='\u{18AA}' + | '\u{18B0}'..='\u{18F5}' + | '\u{1900}'..='\u{191E}' + | '\u{1920}'..='\u{192B}' + | '\u{1930}'..='\u{193B}' + | '\u{1940}' + | '\u{1944}'..='\u{196D}' + | '\u{1970}'..='\u{1974}' + | '\u{1980}'..='\u{19AB}' + | '\u{19B0}'..='\u{19C9}' + | '\u{19D0}'..='\u{19DA}' + | '\u{19DE}'..='\u{1A1B}' + | '\u{1A1E}'..='\u{1A5E}' + | '\u{1A60}'..='\u{1A7C}' + | '\u{1A7F}'..='\u{1A89}' + | '\u{1A90}'..='\u{1A99}' + | '\u{1AA0}'..='\u{1AAD}' + | '\u{1AB0}'..='\u{1ACE}' + | '\u{1B00}'..='\u{1B4C}' + | '\u{1B4E}'..='\u{1BF3}' + | '\u{1BFC}'..='\u{1C37}' + | '\u{1C3B}'..='\u{1C49}' + | '\u{1C4D}'..='\u{1C8A}' + | '\u{1C90}'..='\u{1CBA}' + | '\u{1CBD}'..='\u{1CC7}' + | '\u{1CD0}'..='\u{1CFA}' + | '\u{1D00}'..='\u{1F15}' + | '\u{1F18}'..='\u{1F1D}' + | '\u{1F20}'..='\u{1F45}' + | '\u{1F48}'..='\u{1F4D}' + | '\u{1F50}'..='\u{1F57}' + | '\u{1F59}' + | '\u{1F5B}' + | '\u{1F5D}' + | '\u{1F5F}'..='\u{1F7D}' + | '\u{1F80}'..='\u{1FB4}' + | '\u{1FB6}'..='\u{1FC4}' + | '\u{1FC6}'..='\u{1FD3}' + | '\u{1FD6}'..='\u{1FDB}' + | '\u{1FDD}'..='\u{1FEF}' + | '\u{1FF2}'..='\u{1FF4}' + | '\u{1FF6}'..='\u{1FFE}' + | '\u{2000}'..='\u{2064}' + | '\u{2066}'..='\u{2071}' + | '\u{2074}'..='\u{208E}' + | '\u{2090}'..='\u{209C}' + | '\u{20A0}'..='\u{20C0}' + | '\u{20D0}'..='\u{20F0}' + | '\u{2100}'..='\u{218B}' + | '\u{2190}'..='\u{2429}' + | '\u{2440}'..='\u{244A}' + | '\u{2460}'..='\u{2B73}' + | '\u{2B76}'..='\u{2B95}' + | '\u{2B97}'..='\u{2CF3}' + | '\u{2CF9}'..='\u{2D25}' + | '\u{2D27}' + | '\u{2D2D}' + | '\u{2D30}'..='\u{2D67}' + | '\u{2D6F}'..='\u{2D70}' + | '\u{2D7F}'..='\u{2D96}' + | '\u{2DA0}'..='\u{2DA6}' + | '\u{2DA8}'..='\u{2DAE}' + | '\u{2DB0}'..='\u{2DB6}' + | '\u{2DB8}'..='\u{2DBE}' + | '\u{2DC0}'..='\u{2DC6}' + | '\u{2DC8}'..='\u{2DCE}' + | '\u{2DD0}'..='\u{2DD6}' + | '\u{2DD8}'..='\u{2DDE}' + | '\u{2DE0}'..='\u{2E5D}' + | '\u{2E80}'..='\u{2E99}' + | '\u{2E9B}'..='\u{2EF3}' + | '\u{2F00}'..='\u{2FD5}' + | '\u{2FF0}'..='\u{303F}' + | '\u{3041}'..='\u{3096}' + | '\u{3099}'..='\u{30FF}' + | '\u{3105}'..='\u{312F}' + | '\u{3131}'..='\u{318E}' + | '\u{3190}'..='\u{31E5}' + | '\u{31EF}'..='\u{321E}' + | '\u{3220}'..='\u{A48C}' + | '\u{A490}'..='\u{A4C6}' + | '\u{A4D0}'..='\u{A62B}' + | '\u{A640}'..='\u{A6F7}' + | '\u{A700}'..='\u{A7CD}' + | '\u{A7D0}'..='\u{A7D1}' + | '\u{A7D3}' + | '\u{A7D5}'..='\u{A7DC}' + | '\u{A7F2}'..='\u{A82C}' + | '\u{A830}'..='\u{A839}' + | '\u{A840}'..='\u{A877}' + | '\u{A880}'..='\u{A8C5}' + | '\u{A8CE}'..='\u{A8D9}' + | '\u{A8E0}'..='\u{A953}' + | '\u{A95F}'..='\u{A97C}' + | '\u{A980}'..='\u{A9CD}' + | '\u{A9CF}'..='\u{A9D9}' + | '\u{A9DE}'..='\u{A9FE}' + | '\u{AA00}'..='\u{AA36}' + | '\u{AA40}'..='\u{AA4D}' + | '\u{AA50}'..='\u{AA59}' + | '\u{AA5C}'..='\u{AAC2}' + | '\u{AADB}'..='\u{AAF6}' + | '\u{AB01}'..='\u{AB06}' + | '\u{AB09}'..='\u{AB0E}' + | '\u{AB11}'..='\u{AB16}' + | '\u{AB20}'..='\u{AB26}' + | '\u{AB28}'..='\u{AB2E}' + | '\u{AB30}'..='\u{AB6B}' + | '\u{AB70}'..='\u{ABED}' + | '\u{ABF0}'..='\u{ABF9}' + | '\u{AC00}'..='\u{D7A3}' + | '\u{D7B0}'..='\u{D7C6}' + | '\u{D7CB}'..='\u{D7FB}' + | '\u{F900}'..='\u{FA6D}' + | '\u{FA70}'..='\u{FAD9}' + | '\u{FB00}'..='\u{FB06}' + | '\u{FB13}'..='\u{FB17}' + | '\u{FB1D}'..='\u{FB36}' + | '\u{FB38}'..='\u{FB3C}' + | '\u{FB3E}' + | '\u{FB40}'..='\u{FB41}' + | '\u{FB43}'..='\u{FB44}' + | '\u{FB46}'..='\u{FBC2}' + | '\u{FBD3}'..='\u{FD8F}' + | '\u{FD92}'..='\u{FDC7}' + | '\u{FDCF}' + | '\u{FDF0}'..='\u{FE19}' + | '\u{FE20}'..='\u{FE52}' + | '\u{FE54}'..='\u{FE66}' + | '\u{FE68}'..='\u{FE6B}' + | '\u{FE70}'..='\u{FE74}' + | '\u{FE76}'..='\u{FEFC}' + | '\u{FEFF}' + | '\u{FF01}'..='\u{FFBE}' + | '\u{FFC2}'..='\u{FFC7}' + | '\u{FFCA}'..='\u{FFCF}' + | '\u{FFD2}'..='\u{FFD7}' + | '\u{FFDA}'..='\u{FFDC}' + | '\u{FFE0}'..='\u{FFE6}' + | '\u{FFE8}'..='\u{FFEE}' + | '\u{FFF9}'..='\u{FFFD}' + | '\u{10000}'..='\u{1000B}' + | '\u{1000D}'..='\u{10026}' + | '\u{10028}'..='\u{1003A}' + | '\u{1003C}'..='\u{1003D}' + | '\u{1003F}'..='\u{1004D}' + | '\u{10050}'..='\u{1005D}' + | '\u{10080}'..='\u{100FA}' + | '\u{10100}'..='\u{10102}' + | '\u{10107}'..='\u{10133}' + | '\u{10137}'..='\u{1018E}' + | '\u{10190}'..='\u{1019C}' + | '\u{101A0}' + | '\u{101D0}'..='\u{101FD}' + | '\u{10280}'..='\u{1029C}' + | '\u{102A0}'..='\u{102D0}' + | '\u{102E0}'..='\u{102FB}' + | '\u{10300}'..='\u{10323}' + | '\u{1032D}'..='\u{1034A}' + | '\u{10350}'..='\u{1037A}' + | '\u{10380}'..='\u{1039D}' + | '\u{1039F}'..='\u{103C3}' + | '\u{103C8}'..='\u{103D5}' + | '\u{10400}'..='\u{1049D}' + | '\u{104A0}'..='\u{104A9}' + | '\u{104B0}'..='\u{104D3}' + | '\u{104D8}'..='\u{104FB}' + | '\u{10500}'..='\u{10527}' + | '\u{10530}'..='\u{10563}' + | '\u{1056F}'..='\u{1057A}' + | '\u{1057C}'..='\u{1058A}' + | '\u{1058C}'..='\u{10592}' + | '\u{10594}'..='\u{10595}' + | '\u{10597}'..='\u{105A1}' + | '\u{105A3}'..='\u{105B1}' + | '\u{105B3}'..='\u{105B9}' + | '\u{105BB}'..='\u{105BC}' + | '\u{105C0}'..='\u{105F3}' + | '\u{10600}'..='\u{10736}' + | '\u{10740}'..='\u{10755}' + | '\u{10760}'..='\u{10767}' + | '\u{10780}'..='\u{10785}' + | '\u{10787}'..='\u{107B0}' + | '\u{107B2}'..='\u{107BA}' + | '\u{10800}'..='\u{10805}' + | '\u{10808}' + | '\u{1080A}'..='\u{10835}' + | '\u{10837}'..='\u{10838}' + | '\u{1083C}' + | '\u{1083F}'..='\u{10855}' + | '\u{10857}'..='\u{1089E}' + | '\u{108A7}'..='\u{108AF}' + | '\u{108E0}'..='\u{108F2}' + | '\u{108F4}'..='\u{108F5}' + | '\u{108FB}'..='\u{1091B}' + | '\u{1091F}'..='\u{10939}' + | '\u{1093F}' + | '\u{10980}'..='\u{109B7}' + | '\u{109BC}'..='\u{109CF}' + | '\u{109D2}'..='\u{10A03}' + | '\u{10A05}'..='\u{10A06}' + | '\u{10A0C}'..='\u{10A13}' + | '\u{10A15}'..='\u{10A17}' + | '\u{10A19}'..='\u{10A35}' + | '\u{10A38}'..='\u{10A3A}' + | '\u{10A3F}'..='\u{10A48}' + | '\u{10A50}'..='\u{10A58}' + | '\u{10A60}'..='\u{10A9F}' + | '\u{10AC0}'..='\u{10AE6}' + | '\u{10AEB}'..='\u{10AF6}' + | '\u{10B00}'..='\u{10B35}' + | '\u{10B39}'..='\u{10B55}' + | '\u{10B58}'..='\u{10B72}' + | '\u{10B78}'..='\u{10B91}' + | '\u{10B99}'..='\u{10B9C}' + | '\u{10BA9}'..='\u{10BAF}' + | '\u{10C00}'..='\u{10C48}' + | '\u{10C80}'..='\u{10CB2}' + | '\u{10CC0}'..='\u{10CF2}' + | '\u{10CFA}'..='\u{10D27}' + | '\u{10D30}'..='\u{10D39}' + | '\u{10D40}'..='\u{10D65}' + | '\u{10D69}'..='\u{10D85}' + | '\u{10D8E}'..='\u{10D8F}' + | '\u{10E60}'..='\u{10E7E}' + | '\u{10E80}'..='\u{10EA9}' + | '\u{10EAB}'..='\u{10EAD}' + | '\u{10EB0}'..='\u{10EB1}' + | '\u{10EC2}'..='\u{10EC4}' + | '\u{10EFC}'..='\u{10F27}' + | '\u{10F30}'..='\u{10F59}' + | '\u{10F70}'..='\u{10F89}' + | '\u{10FB0}'..='\u{10FCB}' + | '\u{10FE0}'..='\u{10FF6}' + | '\u{11000}'..='\u{1104D}' + | '\u{11052}'..='\u{11075}' + | '\u{1107F}'..='\u{110C2}' + | '\u{110CD}' + | '\u{110D0}'..='\u{110E8}' + | '\u{110F0}'..='\u{110F9}' + | '\u{11100}'..='\u{11134}' + | '\u{11136}'..='\u{11147}' + | '\u{11150}'..='\u{11176}' + | '\u{11180}'..='\u{111DF}' + | '\u{111E1}'..='\u{111F4}' + | '\u{11200}'..='\u{11211}' + | '\u{11213}'..='\u{11241}' + | '\u{11280}'..='\u{11286}' + | '\u{11288}' + | '\u{1128A}'..='\u{1128D}' + | '\u{1128F}'..='\u{1129D}' + | '\u{1129F}'..='\u{112A9}' + | '\u{112B0}'..='\u{112EA}' + | '\u{112F0}'..='\u{112F9}' + | '\u{11300}'..='\u{11303}' + | '\u{11305}'..='\u{1130C}' + | '\u{1130F}'..='\u{11310}' + | '\u{11313}'..='\u{11328}' + | '\u{1132A}'..='\u{11330}' + | '\u{11332}'..='\u{11333}' + | '\u{11335}'..='\u{11339}' + | '\u{1133B}'..='\u{11344}' + | '\u{11347}'..='\u{11348}' + | '\u{1134B}'..='\u{1134D}' + | '\u{11350}' + | '\u{11357}' + | '\u{1135D}'..='\u{11363}' + | '\u{11366}'..='\u{1136C}' + | '\u{11370}'..='\u{11374}' + | '\u{11380}'..='\u{11389}' + | '\u{1138B}' + | '\u{1138E}' + | '\u{11390}'..='\u{113B5}' + | '\u{113B7}'..='\u{113C0}' + | '\u{113C2}' + | '\u{113C5}' + | '\u{113C7}'..='\u{113CA}' + | '\u{113CC}'..='\u{113D5}' + | '\u{113D7}'..='\u{113D8}' + | '\u{113E1}'..='\u{113E2}' + | '\u{11400}'..='\u{1145B}' + | '\u{1145D}'..='\u{11461}' + | '\u{11480}'..='\u{114C7}' + | '\u{114D0}'..='\u{114D9}' + | '\u{11580}'..='\u{115B5}' + | '\u{115B8}'..='\u{115DD}' + | '\u{11600}'..='\u{11644}' + | '\u{11650}'..='\u{11659}' + | '\u{11660}'..='\u{1166C}' + | '\u{11680}'..='\u{116B9}' + | '\u{116C0}'..='\u{116C9}' + | '\u{116D0}'..='\u{116E3}' + | '\u{11700}'..='\u{1171A}' + | '\u{1171D}'..='\u{1172B}' + | '\u{11730}'..='\u{11746}' + | '\u{11800}'..='\u{1183B}' + | '\u{118A0}'..='\u{118F2}' + | '\u{118FF}'..='\u{11906}' + | '\u{11909}' + | '\u{1190C}'..='\u{11913}' + | '\u{11915}'..='\u{11916}' + | '\u{11918}'..='\u{11935}' + | '\u{11937}'..='\u{11938}' + | '\u{1193B}'..='\u{11946}' + | '\u{11950}'..='\u{11959}' + | '\u{119A0}'..='\u{119A7}' + | '\u{119AA}'..='\u{119D7}' + | '\u{119DA}'..='\u{119E4}' + | '\u{11A00}'..='\u{11A47}' + | '\u{11A50}'..='\u{11AA2}' + | '\u{11AB0}'..='\u{11AF8}' + | '\u{11B00}'..='\u{11B09}' + | '\u{11BC0}'..='\u{11BE1}' + | '\u{11BF0}'..='\u{11BF9}' + | '\u{11C00}'..='\u{11C08}' + | '\u{11C0A}'..='\u{11C36}' + | '\u{11C38}'..='\u{11C45}' + | '\u{11C50}'..='\u{11C6C}' + | '\u{11C70}'..='\u{11C8F}' + | '\u{11C92}'..='\u{11CA7}' + | '\u{11CA9}'..='\u{11CB6}' + | '\u{11D00}'..='\u{11D06}' + | '\u{11D08}'..='\u{11D09}' + | '\u{11D0B}'..='\u{11D36}' + | '\u{11D3A}' + | '\u{11D3C}'..='\u{11D3D}' + | '\u{11D3F}'..='\u{11D47}' + | '\u{11D50}'..='\u{11D59}' + | '\u{11D60}'..='\u{11D65}' + | '\u{11D67}'..='\u{11D68}' + | '\u{11D6A}'..='\u{11D8E}' + | '\u{11D90}'..='\u{11D91}' + | '\u{11D93}'..='\u{11D98}' + | '\u{11DA0}'..='\u{11DA9}' + | '\u{11EE0}'..='\u{11EF8}' + | '\u{11F00}'..='\u{11F10}' + | '\u{11F12}'..='\u{11F3A}' + | '\u{11F3E}'..='\u{11F5A}' + | '\u{11FB0}' + | '\u{11FC0}'..='\u{11FF1}' + | '\u{11FFF}'..='\u{12399}' + | '\u{12400}'..='\u{1246E}' + | '\u{12470}'..='\u{12474}' + | '\u{12480}'..='\u{12543}' + | '\u{12F90}'..='\u{12FF2}' + | '\u{13000}'..='\u{13455}' + | '\u{13460}'..='\u{143FA}' + | '\u{14400}'..='\u{14646}' + | '\u{16100}'..='\u{16139}' + | '\u{16800}'..='\u{16A38}' + | '\u{16A40}'..='\u{16A5E}' + | '\u{16A60}'..='\u{16A69}' + | '\u{16A6E}'..='\u{16ABE}' + | '\u{16AC0}'..='\u{16AC9}' + | '\u{16AD0}'..='\u{16AED}' + | '\u{16AF0}'..='\u{16AF5}' + | '\u{16B00}'..='\u{16B45}' + | '\u{16B50}'..='\u{16B59}' + | '\u{16B5B}'..='\u{16B61}' + | '\u{16B63}'..='\u{16B77}' + | '\u{16B7D}'..='\u{16B8F}' + | '\u{16D40}'..='\u{16D79}' + | '\u{16E40}'..='\u{16E9A}' + | '\u{16F00}'..='\u{16F4A}' + | '\u{16F4F}'..='\u{16F87}' + | '\u{16F8F}'..='\u{16F9F}' + | '\u{16FE0}'..='\u{16FE4}' + | '\u{16FF0}'..='\u{16FF1}' + | '\u{17000}'..='\u{187F7}' + | '\u{18800}'..='\u{18CD5}' + | '\u{18CFF}'..='\u{18D08}' + | '\u{1AFF0}'..='\u{1AFF3}' + | '\u{1AFF5}'..='\u{1AFFB}' + | '\u{1AFFD}'..='\u{1AFFE}' + | '\u{1B000}'..='\u{1B122}' + | '\u{1B132}' + | '\u{1B150}'..='\u{1B152}' + | '\u{1B155}' + | '\u{1B164}'..='\u{1B167}' + | '\u{1B170}'..='\u{1B2FB}' + | '\u{1BC00}'..='\u{1BC6A}' + | '\u{1BC70}'..='\u{1BC7C}' + | '\u{1BC80}'..='\u{1BC88}' + | '\u{1BC90}'..='\u{1BC99}' + | '\u{1BC9C}'..='\u{1BCA3}' + | '\u{1CC00}'..='\u{1CCF9}' + | '\u{1CD00}'..='\u{1CEB3}' + | '\u{1CF00}'..='\u{1CF2D}' + | '\u{1CF30}'..='\u{1CF46}' + | '\u{1CF50}'..='\u{1CFC3}' + | '\u{1D000}'..='\u{1D0F5}' + | '\u{1D100}'..='\u{1D126}' + | '\u{1D129}'..='\u{1D1EA}' + | '\u{1D200}'..='\u{1D245}' + | '\u{1D2C0}'..='\u{1D2D3}' + | '\u{1D2E0}'..='\u{1D2F3}' + | '\u{1D300}'..='\u{1D356}' + | '\u{1D360}'..='\u{1D378}' + | '\u{1D400}'..='\u{1D454}' + | '\u{1D456}'..='\u{1D49C}' + | '\u{1D49E}'..='\u{1D49F}' + | '\u{1D4A2}' + | '\u{1D4A5}'..='\u{1D4A6}' + | '\u{1D4A9}'..='\u{1D4AC}' + | '\u{1D4AE}'..='\u{1D4B9}' + | '\u{1D4BB}' + | '\u{1D4BD}'..='\u{1D4C3}' + | '\u{1D4C5}'..='\u{1D505}' + | '\u{1D507}'..='\u{1D50A}' + | '\u{1D50D}'..='\u{1D514}' + | '\u{1D516}'..='\u{1D51C}' + | '\u{1D51E}'..='\u{1D539}' + | '\u{1D53B}'..='\u{1D53E}' + | '\u{1D540}'..='\u{1D544}' + | '\u{1D546}' + | '\u{1D54A}'..='\u{1D550}' + | '\u{1D552}'..='\u{1D6A5}' + | '\u{1D6A8}'..='\u{1D7CB}' + | '\u{1D7CE}'..='\u{1DA8B}' + | '\u{1DA9B}'..='\u{1DA9F}' + | '\u{1DAA1}'..='\u{1DAAF}' + | '\u{1DF00}'..='\u{1DF1E}' + | '\u{1DF25}'..='\u{1DF2A}' + | '\u{1E000}'..='\u{1E006}' + | '\u{1E008}'..='\u{1E018}' + | '\u{1E01B}'..='\u{1E021}' + | '\u{1E023}'..='\u{1E024}' + | '\u{1E026}'..='\u{1E02A}' + | '\u{1E030}'..='\u{1E06D}' + | '\u{1E08F}' + | '\u{1E100}'..='\u{1E12C}' + | '\u{1E130}'..='\u{1E13D}' + | '\u{1E140}'..='\u{1E149}' + | '\u{1E14E}'..='\u{1E14F}' + | '\u{1E290}'..='\u{1E2AE}' + | '\u{1E2C0}'..='\u{1E2F9}' + | '\u{1E2FF}' + | '\u{1E4D0}'..='\u{1E4F9}' + | '\u{1E5D0}'..='\u{1E5FA}' + | '\u{1E5FF}' + | '\u{1E7E0}'..='\u{1E7E6}' + | '\u{1E7E8}'..='\u{1E7EB}' + | '\u{1E7ED}'..='\u{1E7EE}' + | '\u{1E7F0}'..='\u{1E7FE}' + | '\u{1E800}'..='\u{1E8C4}' + | '\u{1E8C7}'..='\u{1E8D6}' + | '\u{1E900}'..='\u{1E94B}' + | '\u{1E950}'..='\u{1E959}' + | '\u{1E95E}'..='\u{1E95F}' + | '\u{1EC71}'..='\u{1ECB4}' + | '\u{1ED01}'..='\u{1ED3D}' + | '\u{1EE00}'..='\u{1EE03}' + | '\u{1EE05}'..='\u{1EE1F}' + | '\u{1EE21}'..='\u{1EE22}' + | '\u{1EE24}' + | '\u{1EE27}' + | '\u{1EE29}'..='\u{1EE32}' + | '\u{1EE34}'..='\u{1EE37}' + | '\u{1EE39}' + | '\u{1EE3B}' + | '\u{1EE42}' + | '\u{1EE47}' + | '\u{1EE49}' + | '\u{1EE4B}' + | '\u{1EE4D}'..='\u{1EE4F}' + | '\u{1EE51}'..='\u{1EE52}' + | '\u{1EE54}' + | '\u{1EE57}' + | '\u{1EE59}' + | '\u{1EE5B}' + | '\u{1EE5D}' + | '\u{1EE5F}' + | '\u{1EE61}'..='\u{1EE62}' + | '\u{1EE64}' + | '\u{1EE67}'..='\u{1EE6A}' + | '\u{1EE6C}'..='\u{1EE72}' + | '\u{1EE74}'..='\u{1EE77}' + | '\u{1EE79}'..='\u{1EE7C}' + | '\u{1EE7E}' + | '\u{1EE80}'..='\u{1EE89}' + | '\u{1EE8B}'..='\u{1EE9B}' + | '\u{1EEA1}'..='\u{1EEA3}' + | '\u{1EEA5}'..='\u{1EEA9}' + | '\u{1EEAB}'..='\u{1EEBB}' + | '\u{1EEF0}'..='\u{1EEF1}' + | '\u{1F000}'..='\u{1F02B}' + | '\u{1F030}'..='\u{1F093}' + | '\u{1F0A0}'..='\u{1F0AE}' + | '\u{1F0B1}'..='\u{1F0BF}' + | '\u{1F0C1}'..='\u{1F0CF}' + | '\u{1F0D1}'..='\u{1F0F5}' + | '\u{1F100}'..='\u{1F1AD}' + | '\u{1F1E6}'..='\u{1F202}' + | '\u{1F210}'..='\u{1F23B}' + | '\u{1F240}'..='\u{1F248}' + | '\u{1F250}'..='\u{1F251}' + | '\u{1F260}'..='\u{1F265}' + | '\u{1F300}'..='\u{1F6D7}' + | '\u{1F6DC}'..='\u{1F6EC}' + | '\u{1F6F0}'..='\u{1F6FC}' + | '\u{1F700}'..='\u{1F776}' + | '\u{1F77B}'..='\u{1F7D9}' + | '\u{1F7E0}'..='\u{1F7EB}' + | '\u{1F7F0}' + | '\u{1F800}'..='\u{1F80B}' + | '\u{1F810}'..='\u{1F847}' + | '\u{1F850}'..='\u{1F859}' + | '\u{1F860}'..='\u{1F887}' + | '\u{1F890}'..='\u{1F8AD}' + | '\u{1F8B0}'..='\u{1F8BB}' + | '\u{1F8C0}'..='\u{1F8C1}' + | '\u{1F900}'..='\u{1FA53}' + | '\u{1FA60}'..='\u{1FA6D}' + | '\u{1FA70}'..='\u{1FA7C}' + | '\u{1FA80}'..='\u{1FA89}' + | '\u{1FA8F}'..='\u{1FAC6}' + | '\u{1FACE}'..='\u{1FADC}' + | '\u{1FADF}'..='\u{1FAE9}' + | '\u{1FAF0}'..='\u{1FAF8}' + | '\u{1FB00}'..='\u{1FB92}' + | '\u{1FB94}'..='\u{1FBF9}' + | '\u{20000}'..='\u{2A6DF}' + | '\u{2A700}'..='\u{2B739}' + | '\u{2B740}'..='\u{2B81D}' + | '\u{2B820}'..='\u{2CEA1}' + | '\u{2CEB0}'..='\u{2EBE0}' + | '\u{2EBF0}'..='\u{2EE5D}' + | '\u{2F800}'..='\u{2FA1D}' + | '\u{30000}'..='\u{3134A}' + | '\u{31350}'..='\u{323AF}' + | '\u{E0001}' + | '\u{E0020}'..='\u{E007F}' + | '\u{E0100}'..='\u{E01EF}' => true, + _ => false, + } +} + +#[inline] +#[allow(ellipsis_inclusive_range_patterns)] +pub fn qc_nfc(c: char) -> IsNormalized { + match c { + '\u{0340}'..='\u{0341}' => No, + '\u{0343}'..='\u{0344}' => No, + '\u{0374}' => No, + '\u{037E}' => No, + '\u{0387}' => No, + '\u{0958}'..='\u{095F}' => No, + '\u{09DC}'..='\u{09DD}' => No, + '\u{09DF}' => No, + '\u{0A33}' => No, + '\u{0A36}' => No, + '\u{0A59}'..='\u{0A5B}' => No, + '\u{0A5E}' => No, + '\u{0B5C}'..='\u{0B5D}' => No, + '\u{0F43}' => No, + '\u{0F4D}' => No, + '\u{0F52}' => No, + '\u{0F57}' => No, + '\u{0F5C}' => No, + '\u{0F69}' => No, + '\u{0F73}' => No, + '\u{0F75}'..='\u{0F76}' => No, + '\u{0F78}' => No, + '\u{0F81}' => No, + '\u{0F93}' => No, + '\u{0F9D}' => No, + '\u{0FA2}' => No, + '\u{0FA7}' => No, + '\u{0FAC}' => No, + '\u{0FB9}' => No, + '\u{1F71}' => No, + '\u{1F73}' => No, + '\u{1F75}' => No, + '\u{1F77}' => No, + '\u{1F79}' => No, + '\u{1F7B}' => No, + '\u{1F7D}' => No, + '\u{1FBB}' => No, + '\u{1FBE}' => No, + '\u{1FC9}' => No, + '\u{1FCB}' => No, + '\u{1FD3}' => No, + '\u{1FDB}' => No, + '\u{1FE3}' => No, + '\u{1FEB}' => No, + '\u{1FEE}'..='\u{1FEF}' => No, + '\u{1FF9}' => No, + '\u{1FFB}' => No, + '\u{1FFD}' => No, + '\u{2000}'..='\u{2001}' => No, + '\u{2126}' => No, + '\u{212A}'..='\u{212B}' => No, + '\u{2329}' => No, + '\u{232A}' => No, + '\u{2ADC}' => No, + '\u{F900}'..='\u{FA0D}' => No, + '\u{FA10}' => No, + '\u{FA12}' => No, + '\u{FA15}'..='\u{FA1E}' => No, + '\u{FA20}' => No, + '\u{FA22}' => No, + '\u{FA25}'..='\u{FA26}' => No, + '\u{FA2A}'..='\u{FA6D}' => No, + '\u{FA70}'..='\u{FAD9}' => No, + '\u{FB1D}' => No, + '\u{FB1F}' => No, + '\u{FB2A}'..='\u{FB36}' => No, + '\u{FB38}'..='\u{FB3C}' => No, + '\u{FB3E}' => No, + '\u{FB40}'..='\u{FB41}' => No, + '\u{FB43}'..='\u{FB44}' => No, + '\u{FB46}'..='\u{FB4E}' => No, + '\u{1D15E}'..='\u{1D164}' => No, + '\u{1D1BB}'..='\u{1D1C0}' => No, + '\u{2F800}'..='\u{2FA1D}' => No, + '\u{0300}'..='\u{0304}' => Maybe, + '\u{0306}'..='\u{030C}' => Maybe, + '\u{030F}' => Maybe, + '\u{0311}' => Maybe, + '\u{0313}'..='\u{0314}' => Maybe, + '\u{031B}' => Maybe, + '\u{0323}'..='\u{0328}' => Maybe, + '\u{032D}'..='\u{032E}' => Maybe, + '\u{0330}'..='\u{0331}' => Maybe, + '\u{0338}' => Maybe, + '\u{0342}' => Maybe, + '\u{0345}' => Maybe, + '\u{0653}'..='\u{0655}' => Maybe, + '\u{093C}' => Maybe, + '\u{09BE}' => Maybe, + '\u{09D7}' => Maybe, + '\u{0B3E}' => Maybe, + '\u{0B56}' => Maybe, + '\u{0B57}' => Maybe, + '\u{0BBE}' => Maybe, + '\u{0BD7}' => Maybe, + '\u{0C56}' => Maybe, + '\u{0CC2}' => Maybe, + '\u{0CD5}'..='\u{0CD6}' => Maybe, + '\u{0D3E}' => Maybe, + '\u{0D57}' => Maybe, + '\u{0DCA}' => Maybe, + '\u{0DCF}' => Maybe, + '\u{0DDF}' => Maybe, + '\u{102E}' => Maybe, + '\u{1161}'..='\u{1175}' => Maybe, + '\u{11A8}'..='\u{11C2}' => Maybe, + '\u{1B35}' => Maybe, + '\u{3099}'..='\u{309A}' => Maybe, + '\u{110BA}' => Maybe, + '\u{11127}' => Maybe, + '\u{1133E}' => Maybe, + '\u{11357}' => Maybe, + '\u{113B8}' => Maybe, + '\u{113BB}' => Maybe, + '\u{113C2}' => Maybe, + '\u{113C5}' => Maybe, + '\u{113C7}'..='\u{113C9}' => Maybe, + '\u{114B0}' => Maybe, + '\u{114BA}' => Maybe, + '\u{114BD}' => Maybe, + '\u{115AF}' => Maybe, + '\u{11930}' => Maybe, + '\u{1611E}'..='\u{16129}' => Maybe, + '\u{16D67}'..='\u{16D68}' => Maybe, + _ => Yes, + } +} +#[inline] +#[allow(ellipsis_inclusive_range_patterns)] +pub fn qc_nfkc(c: char) -> IsNormalized { + match c { + '\u{00A0}' => No, + '\u{00A8}' => No, + '\u{00AA}' => No, + '\u{00AF}' => No, + '\u{00B2}'..='\u{00B3}' => No, + '\u{00B4}' => No, + '\u{00B5}' => No, + '\u{00B8}' => No, + '\u{00B9}' => No, + '\u{00BA}' => No, + '\u{00BC}'..='\u{00BE}' => No, + '\u{0132}'..='\u{0133}' => No, + '\u{013F}'..='\u{0140}' => No, + '\u{0149}' => No, + '\u{017F}' => No, + '\u{01C4}'..='\u{01CC}' => No, + '\u{01F1}'..='\u{01F3}' => No, + '\u{02B0}'..='\u{02B8}' => No, + '\u{02D8}'..='\u{02DD}' => No, + '\u{02E0}'..='\u{02E4}' => No, + '\u{0340}'..='\u{0341}' => No, + '\u{0343}'..='\u{0344}' => No, + '\u{0374}' => No, + '\u{037A}' => No, + '\u{037E}' => No, + '\u{0384}'..='\u{0385}' => No, + '\u{0387}' => No, + '\u{03D0}'..='\u{03D6}' => No, + '\u{03F0}'..='\u{03F2}' => No, + '\u{03F4}'..='\u{03F5}' => No, + '\u{03F9}' => No, + '\u{0587}' => No, + '\u{0675}'..='\u{0678}' => No, + '\u{0958}'..='\u{095F}' => No, + '\u{09DC}'..='\u{09DD}' => No, + '\u{09DF}' => No, + '\u{0A33}' => No, + '\u{0A36}' => No, + '\u{0A59}'..='\u{0A5B}' => No, + '\u{0A5E}' => No, + '\u{0B5C}'..='\u{0B5D}' => No, + '\u{0E33}' => No, + '\u{0EB3}' => No, + '\u{0EDC}'..='\u{0EDD}' => No, + '\u{0F0C}' => No, + '\u{0F43}' => No, + '\u{0F4D}' => No, + '\u{0F52}' => No, + '\u{0F57}' => No, + '\u{0F5C}' => No, + '\u{0F69}' => No, + '\u{0F73}' => No, + '\u{0F75}'..='\u{0F79}' => No, + '\u{0F81}' => No, + '\u{0F93}' => No, + '\u{0F9D}' => No, + '\u{0FA2}' => No, + '\u{0FA7}' => No, + '\u{0FAC}' => No, + '\u{0FB9}' => No, + '\u{10FC}' => No, + '\u{1D2C}'..='\u{1D2E}' => No, + '\u{1D30}'..='\u{1D3A}' => No, + '\u{1D3C}'..='\u{1D4D}' => No, + '\u{1D4F}'..='\u{1D6A}' => No, + '\u{1D78}' => No, + '\u{1D9B}'..='\u{1DBF}' => No, + '\u{1E9A}'..='\u{1E9B}' => No, + '\u{1F71}' => No, + '\u{1F73}' => No, + '\u{1F75}' => No, + '\u{1F77}' => No, + '\u{1F79}' => No, + '\u{1F7B}' => No, + '\u{1F7D}' => No, + '\u{1FBB}' => No, + '\u{1FBD}' => No, + '\u{1FBE}' => No, + '\u{1FBF}'..='\u{1FC1}' => No, + '\u{1FC9}' => No, + '\u{1FCB}' => No, + '\u{1FCD}'..='\u{1FCF}' => No, + '\u{1FD3}' => No, + '\u{1FDB}' => No, + '\u{1FDD}'..='\u{1FDF}' => No, + '\u{1FE3}' => No, + '\u{1FEB}' => No, + '\u{1FED}'..='\u{1FEF}' => No, + '\u{1FF9}' => No, + '\u{1FFB}' => No, + '\u{1FFD}'..='\u{1FFE}' => No, + '\u{2000}'..='\u{200A}' => No, + '\u{2011}' => No, + '\u{2017}' => No, + '\u{2024}'..='\u{2026}' => No, + '\u{202F}' => No, + '\u{2033}'..='\u{2034}' => No, + '\u{2036}'..='\u{2037}' => No, + '\u{203C}' => No, + '\u{203E}' => No, + '\u{2047}'..='\u{2049}' => No, + '\u{2057}' => No, + '\u{205F}' => No, + '\u{2070}' => No, + '\u{2071}' => No, + '\u{2074}'..='\u{2079}' => No, + '\u{207A}'..='\u{207C}' => No, + '\u{207D}' => No, + '\u{207E}' => No, + '\u{207F}' => No, + '\u{2080}'..='\u{2089}' => No, + '\u{208A}'..='\u{208C}' => No, + '\u{208D}' => No, + '\u{208E}' => No, + '\u{2090}'..='\u{209C}' => No, + '\u{20A8}' => No, + '\u{2100}'..='\u{2101}' => No, + '\u{2102}' => No, + '\u{2103}' => No, + '\u{2105}'..='\u{2106}' => No, + '\u{2107}' => No, + '\u{2109}' => No, + '\u{210A}'..='\u{2113}' => No, + '\u{2115}' => No, + '\u{2116}' => No, + '\u{2119}'..='\u{211D}' => No, + '\u{2120}'..='\u{2122}' => No, + '\u{2124}' => No, + '\u{2126}' => No, + '\u{2128}' => No, + '\u{212A}'..='\u{212D}' => No, + '\u{212F}'..='\u{2131}' => No, + '\u{2133}'..='\u{2134}' => No, + '\u{2135}'..='\u{2138}' => No, + '\u{2139}' => No, + '\u{213B}' => No, + '\u{213C}'..='\u{213F}' => No, + '\u{2140}' => No, + '\u{2145}'..='\u{2149}' => No, + '\u{2150}'..='\u{215F}' => No, + '\u{2160}'..='\u{217F}' => No, + '\u{2189}' => No, + '\u{222C}'..='\u{222D}' => No, + '\u{222F}'..='\u{2230}' => No, + '\u{2329}' => No, + '\u{232A}' => No, + '\u{2460}'..='\u{249B}' => No, + '\u{249C}'..='\u{24E9}' => No, + '\u{24EA}' => No, + '\u{2A0C}' => No, + '\u{2A74}'..='\u{2A76}' => No, + '\u{2ADC}' => No, + '\u{2C7C}'..='\u{2C7D}' => No, + '\u{2D6F}' => No, + '\u{2E9F}' => No, + '\u{2EF3}' => No, + '\u{2F00}'..='\u{2FD5}' => No, + '\u{3000}' => No, + '\u{3036}' => No, + '\u{3038}'..='\u{303A}' => No, + '\u{309B}'..='\u{309C}' => No, + '\u{309F}' => No, + '\u{30FF}' => No, + '\u{3131}'..='\u{318E}' => No, + '\u{3192}'..='\u{3195}' => No, + '\u{3196}'..='\u{319F}' => No, + '\u{3200}'..='\u{321E}' => No, + '\u{3220}'..='\u{3229}' => No, + '\u{322A}'..='\u{3247}' => No, + '\u{3250}' => No, + '\u{3251}'..='\u{325F}' => No, + '\u{3260}'..='\u{327E}' => No, + '\u{3280}'..='\u{3289}' => No, + '\u{328A}'..='\u{32B0}' => No, + '\u{32B1}'..='\u{32BF}' => No, + '\u{32C0}'..='\u{33FF}' => No, + '\u{A69C}'..='\u{A69D}' => No, + '\u{A770}' => No, + '\u{A7F2}'..='\u{A7F4}' => No, + '\u{A7F8}'..='\u{A7F9}' => No, + '\u{AB5C}'..='\u{AB5F}' => No, + '\u{AB69}' => No, + '\u{F900}'..='\u{FA0D}' => No, + '\u{FA10}' => No, + '\u{FA12}' => No, + '\u{FA15}'..='\u{FA1E}' => No, + '\u{FA20}' => No, + '\u{FA22}' => No, + '\u{FA25}'..='\u{FA26}' => No, + '\u{FA2A}'..='\u{FA6D}' => No, + '\u{FA70}'..='\u{FAD9}' => No, + '\u{FB00}'..='\u{FB06}' => No, + '\u{FB13}'..='\u{FB17}' => No, + '\u{FB1D}' => No, + '\u{FB1F}'..='\u{FB28}' => No, + '\u{FB29}' => No, + '\u{FB2A}'..='\u{FB36}' => No, + '\u{FB38}'..='\u{FB3C}' => No, + '\u{FB3E}' => No, + '\u{FB40}'..='\u{FB41}' => No, + '\u{FB43}'..='\u{FB44}' => No, + '\u{FB46}'..='\u{FBB1}' => No, + '\u{FBD3}'..='\u{FD3D}' => No, + '\u{FD50}'..='\u{FD8F}' => No, + '\u{FD92}'..='\u{FDC7}' => No, + '\u{FDF0}'..='\u{FDFB}' => No, + '\u{FDFC}' => No, + '\u{FE10}'..='\u{FE16}' => No, + '\u{FE17}' => No, + '\u{FE18}' => No, + '\u{FE19}' => No, + '\u{FE30}' => No, + '\u{FE31}'..='\u{FE32}' => No, + '\u{FE33}'..='\u{FE34}' => No, + '\u{FE35}' => No, + '\u{FE36}' => No, + '\u{FE37}' => No, + '\u{FE38}' => No, + '\u{FE39}' => No, + '\u{FE3A}' => No, + '\u{FE3B}' => No, + '\u{FE3C}' => No, + '\u{FE3D}' => No, + '\u{FE3E}' => No, + '\u{FE3F}' => No, + '\u{FE40}' => No, + '\u{FE41}' => No, + '\u{FE42}' => No, + '\u{FE43}' => No, + '\u{FE44}' => No, + '\u{FE47}' => No, + '\u{FE48}' => No, + '\u{FE49}'..='\u{FE4C}' => No, + '\u{FE4D}'..='\u{FE4F}' => No, + '\u{FE50}'..='\u{FE52}' => No, + '\u{FE54}'..='\u{FE57}' => No, + '\u{FE58}' => No, + '\u{FE59}' => No, + '\u{FE5A}' => No, + '\u{FE5B}' => No, + '\u{FE5C}' => No, + '\u{FE5D}' => No, + '\u{FE5E}' => No, + '\u{FE5F}'..='\u{FE61}' => No, + '\u{FE62}' => No, + '\u{FE63}' => No, + '\u{FE64}'..='\u{FE66}' => No, + '\u{FE68}' => No, + '\u{FE69}' => No, + '\u{FE6A}'..='\u{FE6B}' => No, + '\u{FE70}'..='\u{FE72}' => No, + '\u{FE74}' => No, + '\u{FE76}'..='\u{FEFC}' => No, + '\u{FF01}'..='\u{FF03}' => No, + '\u{FF04}' => No, + '\u{FF05}'..='\u{FF07}' => No, + '\u{FF08}' => No, + '\u{FF09}' => No, + '\u{FF0A}' => No, + '\u{FF0B}' => No, + '\u{FF0C}' => No, + '\u{FF0D}' => No, + '\u{FF0E}'..='\u{FF0F}' => No, + '\u{FF10}'..='\u{FF19}' => No, + '\u{FF1A}'..='\u{FF1B}' => No, + '\u{FF1C}'..='\u{FF1E}' => No, + '\u{FF1F}'..='\u{FF20}' => No, + '\u{FF21}'..='\u{FF3A}' => No, + '\u{FF3B}' => No, + '\u{FF3C}' => No, + '\u{FF3D}' => No, + '\u{FF3E}' => No, + '\u{FF3F}' => No, + '\u{FF40}' => No, + '\u{FF41}'..='\u{FF5A}' => No, + '\u{FF5B}' => No, + '\u{FF5C}' => No, + '\u{FF5D}' => No, + '\u{FF5E}' => No, + '\u{FF5F}' => No, + '\u{FF60}' => No, + '\u{FF61}' => No, + '\u{FF62}' => No, + '\u{FF63}' => No, + '\u{FF64}'..='\u{FF65}' => No, + '\u{FF66}'..='\u{FF6F}' => No, + '\u{FF70}' => No, + '\u{FF71}'..='\u{FF9D}' => No, + '\u{FF9E}'..='\u{FF9F}' => No, + '\u{FFA0}'..='\u{FFBE}' => No, + '\u{FFC2}'..='\u{FFC7}' => No, + '\u{FFCA}'..='\u{FFCF}' => No, + '\u{FFD2}'..='\u{FFD7}' => No, + '\u{FFDA}'..='\u{FFDC}' => No, + '\u{FFE0}'..='\u{FFE1}' => No, + '\u{FFE2}' => No, + '\u{FFE3}' => No, + '\u{FFE4}' => No, + '\u{FFE5}'..='\u{FFE6}' => No, + '\u{FFE8}' => No, + '\u{FFE9}'..='\u{FFEC}' => No, + '\u{FFED}'..='\u{FFEE}' => No, + '\u{10781}'..='\u{10785}' => No, + '\u{10787}'..='\u{107B0}' => No, + '\u{107B2}'..='\u{107BA}' => No, + '\u{1CCD6}'..='\u{1CCEF}' => No, + '\u{1CCF0}'..='\u{1CCF9}' => No, + '\u{1D15E}'..='\u{1D164}' => No, + '\u{1D1BB}'..='\u{1D1C0}' => No, + '\u{1D400}'..='\u{1D454}' => No, + '\u{1D456}'..='\u{1D49C}' => No, + '\u{1D49E}'..='\u{1D49F}' => No, + '\u{1D4A2}' => No, + '\u{1D4A5}'..='\u{1D4A6}' => No, + '\u{1D4A9}'..='\u{1D4AC}' => No, + '\u{1D4AE}'..='\u{1D4B9}' => No, + '\u{1D4BB}' => No, + '\u{1D4BD}'..='\u{1D4C3}' => No, + '\u{1D4C5}'..='\u{1D505}' => No, + '\u{1D507}'..='\u{1D50A}' => No, + '\u{1D50D}'..='\u{1D514}' => No, + '\u{1D516}'..='\u{1D51C}' => No, + '\u{1D51E}'..='\u{1D539}' => No, + '\u{1D53B}'..='\u{1D53E}' => No, + '\u{1D540}'..='\u{1D544}' => No, + '\u{1D546}' => No, + '\u{1D54A}'..='\u{1D550}' => No, + '\u{1D552}'..='\u{1D6A5}' => No, + '\u{1D6A8}'..='\u{1D6C0}' => No, + '\u{1D6C1}' => No, + '\u{1D6C2}'..='\u{1D6DA}' => No, + '\u{1D6DB}' => No, + '\u{1D6DC}'..='\u{1D6FA}' => No, + '\u{1D6FB}' => No, + '\u{1D6FC}'..='\u{1D714}' => No, + '\u{1D715}' => No, + '\u{1D716}'..='\u{1D734}' => No, + '\u{1D735}' => No, + '\u{1D736}'..='\u{1D74E}' => No, + '\u{1D74F}' => No, + '\u{1D750}'..='\u{1D76E}' => No, + '\u{1D76F}' => No, + '\u{1D770}'..='\u{1D788}' => No, + '\u{1D789}' => No, + '\u{1D78A}'..='\u{1D7A8}' => No, + '\u{1D7A9}' => No, + '\u{1D7AA}'..='\u{1D7C2}' => No, + '\u{1D7C3}' => No, + '\u{1D7C4}'..='\u{1D7CB}' => No, + '\u{1D7CE}'..='\u{1D7FF}' => No, + '\u{1E030}'..='\u{1E06D}' => No, + '\u{1EE00}'..='\u{1EE03}' => No, + '\u{1EE05}'..='\u{1EE1F}' => No, + '\u{1EE21}'..='\u{1EE22}' => No, + '\u{1EE24}' => No, + '\u{1EE27}' => No, + '\u{1EE29}'..='\u{1EE32}' => No, + '\u{1EE34}'..='\u{1EE37}' => No, + '\u{1EE39}' => No, + '\u{1EE3B}' => No, + '\u{1EE42}' => No, + '\u{1EE47}' => No, + '\u{1EE49}' => No, + '\u{1EE4B}' => No, + '\u{1EE4D}'..='\u{1EE4F}' => No, + '\u{1EE51}'..='\u{1EE52}' => No, + '\u{1EE54}' => No, + '\u{1EE57}' => No, + '\u{1EE59}' => No, + '\u{1EE5B}' => No, + '\u{1EE5D}' => No, + '\u{1EE5F}' => No, + '\u{1EE61}'..='\u{1EE62}' => No, + '\u{1EE64}' => No, + '\u{1EE67}'..='\u{1EE6A}' => No, + '\u{1EE6C}'..='\u{1EE72}' => No, + '\u{1EE74}'..='\u{1EE77}' => No, + '\u{1EE79}'..='\u{1EE7C}' => No, + '\u{1EE7E}' => No, + '\u{1EE80}'..='\u{1EE89}' => No, + '\u{1EE8B}'..='\u{1EE9B}' => No, + '\u{1EEA1}'..='\u{1EEA3}' => No, + '\u{1EEA5}'..='\u{1EEA9}' => No, + '\u{1EEAB}'..='\u{1EEBB}' => No, + '\u{1F100}'..='\u{1F10A}' => No, + '\u{1F110}'..='\u{1F12E}' => No, + '\u{1F130}'..='\u{1F14F}' => No, + '\u{1F16A}'..='\u{1F16C}' => No, + '\u{1F190}' => No, + '\u{1F200}'..='\u{1F202}' => No, + '\u{1F210}'..='\u{1F23B}' => No, + '\u{1F240}'..='\u{1F248}' => No, + '\u{1F250}'..='\u{1F251}' => No, + '\u{1FBF0}'..='\u{1FBF9}' => No, + '\u{2F800}'..='\u{2FA1D}' => No, + '\u{0300}'..='\u{0304}' => Maybe, + '\u{0306}'..='\u{030C}' => Maybe, + '\u{030F}' => Maybe, + '\u{0311}' => Maybe, + '\u{0313}'..='\u{0314}' => Maybe, + '\u{031B}' => Maybe, + '\u{0323}'..='\u{0328}' => Maybe, + '\u{032D}'..='\u{032E}' => Maybe, + '\u{0330}'..='\u{0331}' => Maybe, + '\u{0338}' => Maybe, + '\u{0342}' => Maybe, + '\u{0345}' => Maybe, + '\u{0653}'..='\u{0655}' => Maybe, + '\u{093C}' => Maybe, + '\u{09BE}' => Maybe, + '\u{09D7}' => Maybe, + '\u{0B3E}' => Maybe, + '\u{0B56}' => Maybe, + '\u{0B57}' => Maybe, + '\u{0BBE}' => Maybe, + '\u{0BD7}' => Maybe, + '\u{0C56}' => Maybe, + '\u{0CC2}' => Maybe, + '\u{0CD5}'..='\u{0CD6}' => Maybe, + '\u{0D3E}' => Maybe, + '\u{0D57}' => Maybe, + '\u{0DCA}' => Maybe, + '\u{0DCF}' => Maybe, + '\u{0DDF}' => Maybe, + '\u{102E}' => Maybe, + '\u{1161}'..='\u{1175}' => Maybe, + '\u{11A8}'..='\u{11C2}' => Maybe, + '\u{1B35}' => Maybe, + '\u{3099}'..='\u{309A}' => Maybe, + '\u{110BA}' => Maybe, + '\u{11127}' => Maybe, + '\u{1133E}' => Maybe, + '\u{11357}' => Maybe, + '\u{113B8}' => Maybe, + '\u{113BB}' => Maybe, + '\u{113C2}' => Maybe, + '\u{113C5}' => Maybe, + '\u{113C7}'..='\u{113C9}' => Maybe, + '\u{114B0}' => Maybe, + '\u{114BA}' => Maybe, + '\u{114BD}' => Maybe, + '\u{115AF}' => Maybe, + '\u{11930}' => Maybe, + '\u{1611E}'..='\u{16129}' => Maybe, + '\u{16D67}'..='\u{16D68}' => Maybe, + _ => Yes, + } +} +#[inline] +#[allow(ellipsis_inclusive_range_patterns)] +pub fn qc_nfd(c: char) -> IsNormalized { + match c { + '\u{00C0}'..='\u{00C5}' => No, + '\u{00C7}'..='\u{00CF}' => No, + '\u{00D1}'..='\u{00D6}' => No, + '\u{00D9}'..='\u{00DD}' => No, + '\u{00E0}'..='\u{00E5}' => No, + '\u{00E7}'..='\u{00EF}' => No, + '\u{00F1}'..='\u{00F6}' => No, + '\u{00F9}'..='\u{00FD}' => No, + '\u{00FF}'..='\u{010F}' => No, + '\u{0112}'..='\u{0125}' => No, + '\u{0128}'..='\u{0130}' => No, + '\u{0134}'..='\u{0137}' => No, + '\u{0139}'..='\u{013E}' => No, + '\u{0143}'..='\u{0148}' => No, + '\u{014C}'..='\u{0151}' => No, + '\u{0154}'..='\u{0165}' => No, + '\u{0168}'..='\u{017E}' => No, + '\u{01A0}'..='\u{01A1}' => No, + '\u{01AF}'..='\u{01B0}' => No, + '\u{01CD}'..='\u{01DC}' => No, + '\u{01DE}'..='\u{01E3}' => No, + '\u{01E6}'..='\u{01F0}' => No, + '\u{01F4}'..='\u{01F5}' => No, + '\u{01F8}'..='\u{021B}' => No, + '\u{021E}'..='\u{021F}' => No, + '\u{0226}'..='\u{0233}' => No, + '\u{0340}'..='\u{0341}' => No, + '\u{0343}'..='\u{0344}' => No, + '\u{0374}' => No, + '\u{037E}' => No, + '\u{0385}' => No, + '\u{0386}' => No, + '\u{0387}' => No, + '\u{0388}'..='\u{038A}' => No, + '\u{038C}' => No, + '\u{038E}'..='\u{0390}' => No, + '\u{03AA}'..='\u{03B0}' => No, + '\u{03CA}'..='\u{03CE}' => No, + '\u{03D3}'..='\u{03D4}' => No, + '\u{0400}'..='\u{0401}' => No, + '\u{0403}' => No, + '\u{0407}' => No, + '\u{040C}'..='\u{040E}' => No, + '\u{0419}' => No, + '\u{0439}' => No, + '\u{0450}'..='\u{0451}' => No, + '\u{0453}' => No, + '\u{0457}' => No, + '\u{045C}'..='\u{045E}' => No, + '\u{0476}'..='\u{0477}' => No, + '\u{04C1}'..='\u{04C2}' => No, + '\u{04D0}'..='\u{04D3}' => No, + '\u{04D6}'..='\u{04D7}' => No, + '\u{04DA}'..='\u{04DF}' => No, + '\u{04E2}'..='\u{04E7}' => No, + '\u{04EA}'..='\u{04F5}' => No, + '\u{04F8}'..='\u{04F9}' => No, + '\u{0622}'..='\u{0626}' => No, + '\u{06C0}' => No, + '\u{06C2}' => No, + '\u{06D3}' => No, + '\u{0929}' => No, + '\u{0931}' => No, + '\u{0934}' => No, + '\u{0958}'..='\u{095F}' => No, + '\u{09CB}'..='\u{09CC}' => No, + '\u{09DC}'..='\u{09DD}' => No, + '\u{09DF}' => No, + '\u{0A33}' => No, + '\u{0A36}' => No, + '\u{0A59}'..='\u{0A5B}' => No, + '\u{0A5E}' => No, + '\u{0B48}' => No, + '\u{0B4B}'..='\u{0B4C}' => No, + '\u{0B5C}'..='\u{0B5D}' => No, + '\u{0B94}' => No, + '\u{0BCA}'..='\u{0BCC}' => No, + '\u{0C48}' => No, + '\u{0CC0}' => No, + '\u{0CC7}'..='\u{0CC8}' => No, + '\u{0CCA}'..='\u{0CCB}' => No, + '\u{0D4A}'..='\u{0D4C}' => No, + '\u{0DDA}' => No, + '\u{0DDC}'..='\u{0DDE}' => No, + '\u{0F43}' => No, + '\u{0F4D}' => No, + '\u{0F52}' => No, + '\u{0F57}' => No, + '\u{0F5C}' => No, + '\u{0F69}' => No, + '\u{0F73}' => No, + '\u{0F75}'..='\u{0F76}' => No, + '\u{0F78}' => No, + '\u{0F81}' => No, + '\u{0F93}' => No, + '\u{0F9D}' => No, + '\u{0FA2}' => No, + '\u{0FA7}' => No, + '\u{0FAC}' => No, + '\u{0FB9}' => No, + '\u{1026}' => No, + '\u{1B06}' => No, + '\u{1B08}' => No, + '\u{1B0A}' => No, + '\u{1B0C}' => No, + '\u{1B0E}' => No, + '\u{1B12}' => No, + '\u{1B3B}' => No, + '\u{1B3D}' => No, + '\u{1B40}'..='\u{1B41}' => No, + '\u{1B43}' => No, + '\u{1E00}'..='\u{1E99}' => No, + '\u{1E9B}' => No, + '\u{1EA0}'..='\u{1EF9}' => No, + '\u{1F00}'..='\u{1F15}' => No, + '\u{1F18}'..='\u{1F1D}' => No, + '\u{1F20}'..='\u{1F45}' => No, + '\u{1F48}'..='\u{1F4D}' => No, + '\u{1F50}'..='\u{1F57}' => No, + '\u{1F59}' => No, + '\u{1F5B}' => No, + '\u{1F5D}' => No, + '\u{1F5F}'..='\u{1F7D}' => No, + '\u{1F80}'..='\u{1FB4}' => No, + '\u{1FB6}'..='\u{1FBC}' => No, + '\u{1FBE}' => No, + '\u{1FC1}' => No, + '\u{1FC2}'..='\u{1FC4}' => No, + '\u{1FC6}'..='\u{1FCC}' => No, + '\u{1FCD}'..='\u{1FCF}' => No, + '\u{1FD0}'..='\u{1FD3}' => No, + '\u{1FD6}'..='\u{1FDB}' => No, + '\u{1FDD}'..='\u{1FDF}' => No, + '\u{1FE0}'..='\u{1FEC}' => No, + '\u{1FED}'..='\u{1FEF}' => No, + '\u{1FF2}'..='\u{1FF4}' => No, + '\u{1FF6}'..='\u{1FFC}' => No, + '\u{1FFD}' => No, + '\u{2000}'..='\u{2001}' => No, + '\u{2126}' => No, + '\u{212A}'..='\u{212B}' => No, + '\u{219A}'..='\u{219B}' => No, + '\u{21AE}' => No, + '\u{21CD}' => No, + '\u{21CE}'..='\u{21CF}' => No, + '\u{2204}' => No, + '\u{2209}' => No, + '\u{220C}' => No, + '\u{2224}' => No, + '\u{2226}' => No, + '\u{2241}' => No, + '\u{2244}' => No, + '\u{2247}' => No, + '\u{2249}' => No, + '\u{2260}' => No, + '\u{2262}' => No, + '\u{226D}'..='\u{2271}' => No, + '\u{2274}'..='\u{2275}' => No, + '\u{2278}'..='\u{2279}' => No, + '\u{2280}'..='\u{2281}' => No, + '\u{2284}'..='\u{2285}' => No, + '\u{2288}'..='\u{2289}' => No, + '\u{22AC}'..='\u{22AF}' => No, + '\u{22E0}'..='\u{22E3}' => No, + '\u{22EA}'..='\u{22ED}' => No, + '\u{2329}' => No, + '\u{232A}' => No, + '\u{2ADC}' => No, + '\u{304C}' => No, + '\u{304E}' => No, + '\u{3050}' => No, + '\u{3052}' => No, + '\u{3054}' => No, + '\u{3056}' => No, + '\u{3058}' => No, + '\u{305A}' => No, + '\u{305C}' => No, + '\u{305E}' => No, + '\u{3060}' => No, + '\u{3062}' => No, + '\u{3065}' => No, + '\u{3067}' => No, + '\u{3069}' => No, + '\u{3070}'..='\u{3071}' => No, + '\u{3073}'..='\u{3074}' => No, + '\u{3076}'..='\u{3077}' => No, + '\u{3079}'..='\u{307A}' => No, + '\u{307C}'..='\u{307D}' => No, + '\u{3094}' => No, + '\u{309E}' => No, + '\u{30AC}' => No, + '\u{30AE}' => No, + '\u{30B0}' => No, + '\u{30B2}' => No, + '\u{30B4}' => No, + '\u{30B6}' => No, + '\u{30B8}' => No, + '\u{30BA}' => No, + '\u{30BC}' => No, + '\u{30BE}' => No, + '\u{30C0}' => No, + '\u{30C2}' => No, + '\u{30C5}' => No, + '\u{30C7}' => No, + '\u{30C9}' => No, + '\u{30D0}'..='\u{30D1}' => No, + '\u{30D3}'..='\u{30D4}' => No, + '\u{30D6}'..='\u{30D7}' => No, + '\u{30D9}'..='\u{30DA}' => No, + '\u{30DC}'..='\u{30DD}' => No, + '\u{30F4}' => No, + '\u{30F7}'..='\u{30FA}' => No, + '\u{30FE}' => No, + '\u{AC00}'..='\u{D7A3}' => No, + '\u{F900}'..='\u{FA0D}' => No, + '\u{FA10}' => No, + '\u{FA12}' => No, + '\u{FA15}'..='\u{FA1E}' => No, + '\u{FA20}' => No, + '\u{FA22}' => No, + '\u{FA25}'..='\u{FA26}' => No, + '\u{FA2A}'..='\u{FA6D}' => No, + '\u{FA70}'..='\u{FAD9}' => No, + '\u{FB1D}' => No, + '\u{FB1F}' => No, + '\u{FB2A}'..='\u{FB36}' => No, + '\u{FB38}'..='\u{FB3C}' => No, + '\u{FB3E}' => No, + '\u{FB40}'..='\u{FB41}' => No, + '\u{FB43}'..='\u{FB44}' => No, + '\u{FB46}'..='\u{FB4E}' => No, + '\u{105C9}' => No, + '\u{105E4}' => No, + '\u{1109A}' => No, + '\u{1109C}' => No, + '\u{110AB}' => No, + '\u{1112E}'..='\u{1112F}' => No, + '\u{1134B}'..='\u{1134C}' => No, + '\u{11383}' => No, + '\u{11385}' => No, + '\u{1138E}' => No, + '\u{11391}' => No, + '\u{113C5}' => No, + '\u{113C7}'..='\u{113C8}' => No, + '\u{114BB}'..='\u{114BC}' => No, + '\u{114BE}' => No, + '\u{115BA}'..='\u{115BB}' => No, + '\u{11938}' => No, + '\u{16121}'..='\u{16128}' => No, + '\u{16D68}'..='\u{16D6A}' => No, + '\u{1D15E}'..='\u{1D164}' => No, + '\u{1D1BB}'..='\u{1D1C0}' => No, + '\u{2F800}'..='\u{2FA1D}' => No, + _ => Yes, + } +} +#[inline] +#[allow(ellipsis_inclusive_range_patterns)] +pub fn qc_nfkd(c: char) -> IsNormalized { + match c { + '\u{00A0}' => No, + '\u{00A8}' => No, + '\u{00AA}' => No, + '\u{00AF}' => No, + '\u{00B2}'..='\u{00B3}' => No, + '\u{00B4}' => No, + '\u{00B5}' => No, + '\u{00B8}' => No, + '\u{00B9}' => No, + '\u{00BA}' => No, + '\u{00BC}'..='\u{00BE}' => No, + '\u{00C0}'..='\u{00C5}' => No, + '\u{00C7}'..='\u{00CF}' => No, + '\u{00D1}'..='\u{00D6}' => No, + '\u{00D9}'..='\u{00DD}' => No, + '\u{00E0}'..='\u{00E5}' => No, + '\u{00E7}'..='\u{00EF}' => No, + '\u{00F1}'..='\u{00F6}' => No, + '\u{00F9}'..='\u{00FD}' => No, + '\u{00FF}'..='\u{010F}' => No, + '\u{0112}'..='\u{0125}' => No, + '\u{0128}'..='\u{0130}' => No, + '\u{0132}'..='\u{0137}' => No, + '\u{0139}'..='\u{0140}' => No, + '\u{0143}'..='\u{0149}' => No, + '\u{014C}'..='\u{0151}' => No, + '\u{0154}'..='\u{0165}' => No, + '\u{0168}'..='\u{017F}' => No, + '\u{01A0}'..='\u{01A1}' => No, + '\u{01AF}'..='\u{01B0}' => No, + '\u{01C4}'..='\u{01DC}' => No, + '\u{01DE}'..='\u{01E3}' => No, + '\u{01E6}'..='\u{01F5}' => No, + '\u{01F8}'..='\u{021B}' => No, + '\u{021E}'..='\u{021F}' => No, + '\u{0226}'..='\u{0233}' => No, + '\u{02B0}'..='\u{02B8}' => No, + '\u{02D8}'..='\u{02DD}' => No, + '\u{02E0}'..='\u{02E4}' => No, + '\u{0340}'..='\u{0341}' => No, + '\u{0343}'..='\u{0344}' => No, + '\u{0374}' => No, + '\u{037A}' => No, + '\u{037E}' => No, + '\u{0384}'..='\u{0385}' => No, + '\u{0386}' => No, + '\u{0387}' => No, + '\u{0388}'..='\u{038A}' => No, + '\u{038C}' => No, + '\u{038E}'..='\u{0390}' => No, + '\u{03AA}'..='\u{03B0}' => No, + '\u{03CA}'..='\u{03CE}' => No, + '\u{03D0}'..='\u{03D6}' => No, + '\u{03F0}'..='\u{03F2}' => No, + '\u{03F4}'..='\u{03F5}' => No, + '\u{03F9}' => No, + '\u{0400}'..='\u{0401}' => No, + '\u{0403}' => No, + '\u{0407}' => No, + '\u{040C}'..='\u{040E}' => No, + '\u{0419}' => No, + '\u{0439}' => No, + '\u{0450}'..='\u{0451}' => No, + '\u{0453}' => No, + '\u{0457}' => No, + '\u{045C}'..='\u{045E}' => No, + '\u{0476}'..='\u{0477}' => No, + '\u{04C1}'..='\u{04C2}' => No, + '\u{04D0}'..='\u{04D3}' => No, + '\u{04D6}'..='\u{04D7}' => No, + '\u{04DA}'..='\u{04DF}' => No, + '\u{04E2}'..='\u{04E7}' => No, + '\u{04EA}'..='\u{04F5}' => No, + '\u{04F8}'..='\u{04F9}' => No, + '\u{0587}' => No, + '\u{0622}'..='\u{0626}' => No, + '\u{0675}'..='\u{0678}' => No, + '\u{06C0}' => No, + '\u{06C2}' => No, + '\u{06D3}' => No, + '\u{0929}' => No, + '\u{0931}' => No, + '\u{0934}' => No, + '\u{0958}'..='\u{095F}' => No, + '\u{09CB}'..='\u{09CC}' => No, + '\u{09DC}'..='\u{09DD}' => No, + '\u{09DF}' => No, + '\u{0A33}' => No, + '\u{0A36}' => No, + '\u{0A59}'..='\u{0A5B}' => No, + '\u{0A5E}' => No, + '\u{0B48}' => No, + '\u{0B4B}'..='\u{0B4C}' => No, + '\u{0B5C}'..='\u{0B5D}' => No, + '\u{0B94}' => No, + '\u{0BCA}'..='\u{0BCC}' => No, + '\u{0C48}' => No, + '\u{0CC0}' => No, + '\u{0CC7}'..='\u{0CC8}' => No, + '\u{0CCA}'..='\u{0CCB}' => No, + '\u{0D4A}'..='\u{0D4C}' => No, + '\u{0DDA}' => No, + '\u{0DDC}'..='\u{0DDE}' => No, + '\u{0E33}' => No, + '\u{0EB3}' => No, + '\u{0EDC}'..='\u{0EDD}' => No, + '\u{0F0C}' => No, + '\u{0F43}' => No, + '\u{0F4D}' => No, + '\u{0F52}' => No, + '\u{0F57}' => No, + '\u{0F5C}' => No, + '\u{0F69}' => No, + '\u{0F73}' => No, + '\u{0F75}'..='\u{0F79}' => No, + '\u{0F81}' => No, + '\u{0F93}' => No, + '\u{0F9D}' => No, + '\u{0FA2}' => No, + '\u{0FA7}' => No, + '\u{0FAC}' => No, + '\u{0FB9}' => No, + '\u{1026}' => No, + '\u{10FC}' => No, + '\u{1B06}' => No, + '\u{1B08}' => No, + '\u{1B0A}' => No, + '\u{1B0C}' => No, + '\u{1B0E}' => No, + '\u{1B12}' => No, + '\u{1B3B}' => No, + '\u{1B3D}' => No, + '\u{1B40}'..='\u{1B41}' => No, + '\u{1B43}' => No, + '\u{1D2C}'..='\u{1D2E}' => No, + '\u{1D30}'..='\u{1D3A}' => No, + '\u{1D3C}'..='\u{1D4D}' => No, + '\u{1D4F}'..='\u{1D6A}' => No, + '\u{1D78}' => No, + '\u{1D9B}'..='\u{1DBF}' => No, + '\u{1E00}'..='\u{1E9B}' => No, + '\u{1EA0}'..='\u{1EF9}' => No, + '\u{1F00}'..='\u{1F15}' => No, + '\u{1F18}'..='\u{1F1D}' => No, + '\u{1F20}'..='\u{1F45}' => No, + '\u{1F48}'..='\u{1F4D}' => No, + '\u{1F50}'..='\u{1F57}' => No, + '\u{1F59}' => No, + '\u{1F5B}' => No, + '\u{1F5D}' => No, + '\u{1F5F}'..='\u{1F7D}' => No, + '\u{1F80}'..='\u{1FB4}' => No, + '\u{1FB6}'..='\u{1FBC}' => No, + '\u{1FBD}' => No, + '\u{1FBE}' => No, + '\u{1FBF}'..='\u{1FC1}' => No, + '\u{1FC2}'..='\u{1FC4}' => No, + '\u{1FC6}'..='\u{1FCC}' => No, + '\u{1FCD}'..='\u{1FCF}' => No, + '\u{1FD0}'..='\u{1FD3}' => No, + '\u{1FD6}'..='\u{1FDB}' => No, + '\u{1FDD}'..='\u{1FDF}' => No, + '\u{1FE0}'..='\u{1FEC}' => No, + '\u{1FED}'..='\u{1FEF}' => No, + '\u{1FF2}'..='\u{1FF4}' => No, + '\u{1FF6}'..='\u{1FFC}' => No, + '\u{1FFD}'..='\u{1FFE}' => No, + '\u{2000}'..='\u{200A}' => No, + '\u{2011}' => No, + '\u{2017}' => No, + '\u{2024}'..='\u{2026}' => No, + '\u{202F}' => No, + '\u{2033}'..='\u{2034}' => No, + '\u{2036}'..='\u{2037}' => No, + '\u{203C}' => No, + '\u{203E}' => No, + '\u{2047}'..='\u{2049}' => No, + '\u{2057}' => No, + '\u{205F}' => No, + '\u{2070}' => No, + '\u{2071}' => No, + '\u{2074}'..='\u{2079}' => No, + '\u{207A}'..='\u{207C}' => No, + '\u{207D}' => No, + '\u{207E}' => No, + '\u{207F}' => No, + '\u{2080}'..='\u{2089}' => No, + '\u{208A}'..='\u{208C}' => No, + '\u{208D}' => No, + '\u{208E}' => No, + '\u{2090}'..='\u{209C}' => No, + '\u{20A8}' => No, + '\u{2100}'..='\u{2101}' => No, + '\u{2102}' => No, + '\u{2103}' => No, + '\u{2105}'..='\u{2106}' => No, + '\u{2107}' => No, + '\u{2109}' => No, + '\u{210A}'..='\u{2113}' => No, + '\u{2115}' => No, + '\u{2116}' => No, + '\u{2119}'..='\u{211D}' => No, + '\u{2120}'..='\u{2122}' => No, + '\u{2124}' => No, + '\u{2126}' => No, + '\u{2128}' => No, + '\u{212A}'..='\u{212D}' => No, + '\u{212F}'..='\u{2131}' => No, + '\u{2133}'..='\u{2134}' => No, + '\u{2135}'..='\u{2138}' => No, + '\u{2139}' => No, + '\u{213B}' => No, + '\u{213C}'..='\u{213F}' => No, + '\u{2140}' => No, + '\u{2145}'..='\u{2149}' => No, + '\u{2150}'..='\u{215F}' => No, + '\u{2160}'..='\u{217F}' => No, + '\u{2189}' => No, + '\u{219A}'..='\u{219B}' => No, + '\u{21AE}' => No, + '\u{21CD}' => No, + '\u{21CE}'..='\u{21CF}' => No, + '\u{2204}' => No, + '\u{2209}' => No, + '\u{220C}' => No, + '\u{2224}' => No, + '\u{2226}' => No, + '\u{222C}'..='\u{222D}' => No, + '\u{222F}'..='\u{2230}' => No, + '\u{2241}' => No, + '\u{2244}' => No, + '\u{2247}' => No, + '\u{2249}' => No, + '\u{2260}' => No, + '\u{2262}' => No, + '\u{226D}'..='\u{2271}' => No, + '\u{2274}'..='\u{2275}' => No, + '\u{2278}'..='\u{2279}' => No, + '\u{2280}'..='\u{2281}' => No, + '\u{2284}'..='\u{2285}' => No, + '\u{2288}'..='\u{2289}' => No, + '\u{22AC}'..='\u{22AF}' => No, + '\u{22E0}'..='\u{22E3}' => No, + '\u{22EA}'..='\u{22ED}' => No, + '\u{2329}' => No, + '\u{232A}' => No, + '\u{2460}'..='\u{249B}' => No, + '\u{249C}'..='\u{24E9}' => No, + '\u{24EA}' => No, + '\u{2A0C}' => No, + '\u{2A74}'..='\u{2A76}' => No, + '\u{2ADC}' => No, + '\u{2C7C}'..='\u{2C7D}' => No, + '\u{2D6F}' => No, + '\u{2E9F}' => No, + '\u{2EF3}' => No, + '\u{2F00}'..='\u{2FD5}' => No, + '\u{3000}' => No, + '\u{3036}' => No, + '\u{3038}'..='\u{303A}' => No, + '\u{304C}' => No, + '\u{304E}' => No, + '\u{3050}' => No, + '\u{3052}' => No, + '\u{3054}' => No, + '\u{3056}' => No, + '\u{3058}' => No, + '\u{305A}' => No, + '\u{305C}' => No, + '\u{305E}' => No, + '\u{3060}' => No, + '\u{3062}' => No, + '\u{3065}' => No, + '\u{3067}' => No, + '\u{3069}' => No, + '\u{3070}'..='\u{3071}' => No, + '\u{3073}'..='\u{3074}' => No, + '\u{3076}'..='\u{3077}' => No, + '\u{3079}'..='\u{307A}' => No, + '\u{307C}'..='\u{307D}' => No, + '\u{3094}' => No, + '\u{309B}'..='\u{309C}' => No, + '\u{309E}' => No, + '\u{309F}' => No, + '\u{30AC}' => No, + '\u{30AE}' => No, + '\u{30B0}' => No, + '\u{30B2}' => No, + '\u{30B4}' => No, + '\u{30B6}' => No, + '\u{30B8}' => No, + '\u{30BA}' => No, + '\u{30BC}' => No, + '\u{30BE}' => No, + '\u{30C0}' => No, + '\u{30C2}' => No, + '\u{30C5}' => No, + '\u{30C7}' => No, + '\u{30C9}' => No, + '\u{30D0}'..='\u{30D1}' => No, + '\u{30D3}'..='\u{30D4}' => No, + '\u{30D6}'..='\u{30D7}' => No, + '\u{30D9}'..='\u{30DA}' => No, + '\u{30DC}'..='\u{30DD}' => No, + '\u{30F4}' => No, + '\u{30F7}'..='\u{30FA}' => No, + '\u{30FE}' => No, + '\u{30FF}' => No, + '\u{3131}'..='\u{318E}' => No, + '\u{3192}'..='\u{3195}' => No, + '\u{3196}'..='\u{319F}' => No, + '\u{3200}'..='\u{321E}' => No, + '\u{3220}'..='\u{3229}' => No, + '\u{322A}'..='\u{3247}' => No, + '\u{3250}' => No, + '\u{3251}'..='\u{325F}' => No, + '\u{3260}'..='\u{327E}' => No, + '\u{3280}'..='\u{3289}' => No, + '\u{328A}'..='\u{32B0}' => No, + '\u{32B1}'..='\u{32BF}' => No, + '\u{32C0}'..='\u{33FF}' => No, + '\u{A69C}'..='\u{A69D}' => No, + '\u{A770}' => No, + '\u{A7F2}'..='\u{A7F4}' => No, + '\u{A7F8}'..='\u{A7F9}' => No, + '\u{AB5C}'..='\u{AB5F}' => No, + '\u{AB69}' => No, + '\u{AC00}'..='\u{D7A3}' => No, + '\u{F900}'..='\u{FA0D}' => No, + '\u{FA10}' => No, + '\u{FA12}' => No, + '\u{FA15}'..='\u{FA1E}' => No, + '\u{FA20}' => No, + '\u{FA22}' => No, + '\u{FA25}'..='\u{FA26}' => No, + '\u{FA2A}'..='\u{FA6D}' => No, + '\u{FA70}'..='\u{FAD9}' => No, + '\u{FB00}'..='\u{FB06}' => No, + '\u{FB13}'..='\u{FB17}' => No, + '\u{FB1D}' => No, + '\u{FB1F}'..='\u{FB28}' => No, + '\u{FB29}' => No, + '\u{FB2A}'..='\u{FB36}' => No, + '\u{FB38}'..='\u{FB3C}' => No, + '\u{FB3E}' => No, + '\u{FB40}'..='\u{FB41}' => No, + '\u{FB43}'..='\u{FB44}' => No, + '\u{FB46}'..='\u{FBB1}' => No, + '\u{FBD3}'..='\u{FD3D}' => No, + '\u{FD50}'..='\u{FD8F}' => No, + '\u{FD92}'..='\u{FDC7}' => No, + '\u{FDF0}'..='\u{FDFB}' => No, + '\u{FDFC}' => No, + '\u{FE10}'..='\u{FE16}' => No, + '\u{FE17}' => No, + '\u{FE18}' => No, + '\u{FE19}' => No, + '\u{FE30}' => No, + '\u{FE31}'..='\u{FE32}' => No, + '\u{FE33}'..='\u{FE34}' => No, + '\u{FE35}' => No, + '\u{FE36}' => No, + '\u{FE37}' => No, + '\u{FE38}' => No, + '\u{FE39}' => No, + '\u{FE3A}' => No, + '\u{FE3B}' => No, + '\u{FE3C}' => No, + '\u{FE3D}' => No, + '\u{FE3E}' => No, + '\u{FE3F}' => No, + '\u{FE40}' => No, + '\u{FE41}' => No, + '\u{FE42}' => No, + '\u{FE43}' => No, + '\u{FE44}' => No, + '\u{FE47}' => No, + '\u{FE48}' => No, + '\u{FE49}'..='\u{FE4C}' => No, + '\u{FE4D}'..='\u{FE4F}' => No, + '\u{FE50}'..='\u{FE52}' => No, + '\u{FE54}'..='\u{FE57}' => No, + '\u{FE58}' => No, + '\u{FE59}' => No, + '\u{FE5A}' => No, + '\u{FE5B}' => No, + '\u{FE5C}' => No, + '\u{FE5D}' => No, + '\u{FE5E}' => No, + '\u{FE5F}'..='\u{FE61}' => No, + '\u{FE62}' => No, + '\u{FE63}' => No, + '\u{FE64}'..='\u{FE66}' => No, + '\u{FE68}' => No, + '\u{FE69}' => No, + '\u{FE6A}'..='\u{FE6B}' => No, + '\u{FE70}'..='\u{FE72}' => No, + '\u{FE74}' => No, + '\u{FE76}'..='\u{FEFC}' => No, + '\u{FF01}'..='\u{FF03}' => No, + '\u{FF04}' => No, + '\u{FF05}'..='\u{FF07}' => No, + '\u{FF08}' => No, + '\u{FF09}' => No, + '\u{FF0A}' => No, + '\u{FF0B}' => No, + '\u{FF0C}' => No, + '\u{FF0D}' => No, + '\u{FF0E}'..='\u{FF0F}' => No, + '\u{FF10}'..='\u{FF19}' => No, + '\u{FF1A}'..='\u{FF1B}' => No, + '\u{FF1C}'..='\u{FF1E}' => No, + '\u{FF1F}'..='\u{FF20}' => No, + '\u{FF21}'..='\u{FF3A}' => No, + '\u{FF3B}' => No, + '\u{FF3C}' => No, + '\u{FF3D}' => No, + '\u{FF3E}' => No, + '\u{FF3F}' => No, + '\u{FF40}' => No, + '\u{FF41}'..='\u{FF5A}' => No, + '\u{FF5B}' => No, + '\u{FF5C}' => No, + '\u{FF5D}' => No, + '\u{FF5E}' => No, + '\u{FF5F}' => No, + '\u{FF60}' => No, + '\u{FF61}' => No, + '\u{FF62}' => No, + '\u{FF63}' => No, + '\u{FF64}'..='\u{FF65}' => No, + '\u{FF66}'..='\u{FF6F}' => No, + '\u{FF70}' => No, + '\u{FF71}'..='\u{FF9D}' => No, + '\u{FF9E}'..='\u{FF9F}' => No, + '\u{FFA0}'..='\u{FFBE}' => No, + '\u{FFC2}'..='\u{FFC7}' => No, + '\u{FFCA}'..='\u{FFCF}' => No, + '\u{FFD2}'..='\u{FFD7}' => No, + '\u{FFDA}'..='\u{FFDC}' => No, + '\u{FFE0}'..='\u{FFE1}' => No, + '\u{FFE2}' => No, + '\u{FFE3}' => No, + '\u{FFE4}' => No, + '\u{FFE5}'..='\u{FFE6}' => No, + '\u{FFE8}' => No, + '\u{FFE9}'..='\u{FFEC}' => No, + '\u{FFED}'..='\u{FFEE}' => No, + '\u{105C9}' => No, + '\u{105E4}' => No, + '\u{10781}'..='\u{10785}' => No, + '\u{10787}'..='\u{107B0}' => No, + '\u{107B2}'..='\u{107BA}' => No, + '\u{1109A}' => No, + '\u{1109C}' => No, + '\u{110AB}' => No, + '\u{1112E}'..='\u{1112F}' => No, + '\u{1134B}'..='\u{1134C}' => No, + '\u{11383}' => No, + '\u{11385}' => No, + '\u{1138E}' => No, + '\u{11391}' => No, + '\u{113C5}' => No, + '\u{113C7}'..='\u{113C8}' => No, + '\u{114BB}'..='\u{114BC}' => No, + '\u{114BE}' => No, + '\u{115BA}'..='\u{115BB}' => No, + '\u{11938}' => No, + '\u{16121}'..='\u{16128}' => No, + '\u{16D68}'..='\u{16D6A}' => No, + '\u{1CCD6}'..='\u{1CCEF}' => No, + '\u{1CCF0}'..='\u{1CCF9}' => No, + '\u{1D15E}'..='\u{1D164}' => No, + '\u{1D1BB}'..='\u{1D1C0}' => No, + '\u{1D400}'..='\u{1D454}' => No, + '\u{1D456}'..='\u{1D49C}' => No, + '\u{1D49E}'..='\u{1D49F}' => No, + '\u{1D4A2}' => No, + '\u{1D4A5}'..='\u{1D4A6}' => No, + '\u{1D4A9}'..='\u{1D4AC}' => No, + '\u{1D4AE}'..='\u{1D4B9}' => No, + '\u{1D4BB}' => No, + '\u{1D4BD}'..='\u{1D4C3}' => No, + '\u{1D4C5}'..='\u{1D505}' => No, + '\u{1D507}'..='\u{1D50A}' => No, + '\u{1D50D}'..='\u{1D514}' => No, + '\u{1D516}'..='\u{1D51C}' => No, + '\u{1D51E}'..='\u{1D539}' => No, + '\u{1D53B}'..='\u{1D53E}' => No, + '\u{1D540}'..='\u{1D544}' => No, + '\u{1D546}' => No, + '\u{1D54A}'..='\u{1D550}' => No, + '\u{1D552}'..='\u{1D6A5}' => No, + '\u{1D6A8}'..='\u{1D6C0}' => No, + '\u{1D6C1}' => No, + '\u{1D6C2}'..='\u{1D6DA}' => No, + '\u{1D6DB}' => No, + '\u{1D6DC}'..='\u{1D6FA}' => No, + '\u{1D6FB}' => No, + '\u{1D6FC}'..='\u{1D714}' => No, + '\u{1D715}' => No, + '\u{1D716}'..='\u{1D734}' => No, + '\u{1D735}' => No, + '\u{1D736}'..='\u{1D74E}' => No, + '\u{1D74F}' => No, + '\u{1D750}'..='\u{1D76E}' => No, + '\u{1D76F}' => No, + '\u{1D770}'..='\u{1D788}' => No, + '\u{1D789}' => No, + '\u{1D78A}'..='\u{1D7A8}' => No, + '\u{1D7A9}' => No, + '\u{1D7AA}'..='\u{1D7C2}' => No, + '\u{1D7C3}' => No, + '\u{1D7C4}'..='\u{1D7CB}' => No, + '\u{1D7CE}'..='\u{1D7FF}' => No, + '\u{1E030}'..='\u{1E06D}' => No, + '\u{1EE00}'..='\u{1EE03}' => No, + '\u{1EE05}'..='\u{1EE1F}' => No, + '\u{1EE21}'..='\u{1EE22}' => No, + '\u{1EE24}' => No, + '\u{1EE27}' => No, + '\u{1EE29}'..='\u{1EE32}' => No, + '\u{1EE34}'..='\u{1EE37}' => No, + '\u{1EE39}' => No, + '\u{1EE3B}' => No, + '\u{1EE42}' => No, + '\u{1EE47}' => No, + '\u{1EE49}' => No, + '\u{1EE4B}' => No, + '\u{1EE4D}'..='\u{1EE4F}' => No, + '\u{1EE51}'..='\u{1EE52}' => No, + '\u{1EE54}' => No, + '\u{1EE57}' => No, + '\u{1EE59}' => No, + '\u{1EE5B}' => No, + '\u{1EE5D}' => No, + '\u{1EE5F}' => No, + '\u{1EE61}'..='\u{1EE62}' => No, + '\u{1EE64}' => No, + '\u{1EE67}'..='\u{1EE6A}' => No, + '\u{1EE6C}'..='\u{1EE72}' => No, + '\u{1EE74}'..='\u{1EE77}' => No, + '\u{1EE79}'..='\u{1EE7C}' => No, + '\u{1EE7E}' => No, + '\u{1EE80}'..='\u{1EE89}' => No, + '\u{1EE8B}'..='\u{1EE9B}' => No, + '\u{1EEA1}'..='\u{1EEA3}' => No, + '\u{1EEA5}'..='\u{1EEA9}' => No, + '\u{1EEAB}'..='\u{1EEBB}' => No, + '\u{1F100}'..='\u{1F10A}' => No, + '\u{1F110}'..='\u{1F12E}' => No, + '\u{1F130}'..='\u{1F14F}' => No, + '\u{1F16A}'..='\u{1F16C}' => No, + '\u{1F190}' => No, + '\u{1F200}'..='\u{1F202}' => No, + '\u{1F210}'..='\u{1F23B}' => No, + '\u{1F240}'..='\u{1F248}' => No, + '\u{1F250}'..='\u{1F251}' => No, + '\u{1FBF0}'..='\u{1FBF9}' => No, + '\u{2F800}'..='\u{2FA1D}' => No, + _ => Yes, + } +} +#[inline] +pub fn stream_safe_leading_nonstarters(c: char) -> usize { + match c { + '\u{0340}' => 1, + '\u{0341}' => 1, + '\u{0343}' => 1, + '\u{0344}' => 2, + '\u{0F73}' => 2, + '\u{0F75}' => 2, + '\u{0F81}' => 2, + '\u{FF9E}' => 1, + '\u{FF9F}' => 1, + _ => 0, + } +} + +pub(crate) const TRAILING_NONSTARTERS_SALT: &[u16] = &[ + 0x4B0, 0x000, 0x012, 0x151, 0x000, 0x051, 0x000, 0x166, 0x00E, 0x000, 0x000, 0x00A, 0x004, + 0x008, 0x000, 0x012, 0x002, 0x000, 0x002, 0x000, 0x00E, 0x000, 0x000, 0x127, 0x000, 0x000, + 0x000, 0x004, 0x18C, 0x019, 0x000, 0x000, 0x001, 0x005, 0x000, 0x06A, 0x001, 0x0C5, 0x010, + 0x000, 0x000, 0x002, 0x003, 0x011, 0x002, 0x000, 0x000, 0x003, 0x008, 0x026, 0x104, 0x0BC, + 0x033, 0x043, 0x033, 0x00E, 0x000, 0x000, 0x02D, 0x020, 0x000, 0x00D, 0x002, 0x000, 0x027, + 0x000, 0x023, 0x038, 0x008, 0x00D, 0x060, 0x026, 0x000, 0x01B, 0x000, 0x000, 0x05A, 0x002, + 0x000, 0x007, 0x048, 0x00F, 0x003, 0x001, 0x00F, 0x04A, 0x002, 0x003, 0x000, 0x003, 0x004, + 0x002, 0x037, 0x00C, 0x001, 0x044, 0x000, 0x000, 0x006, 0x012, 0x000, 0x001, 0x001, 0x000, + 0x035, 0x00C, 0x00B, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x00B, 0x000, 0x005, 0x00F, + 0x000, 0x000, 0x00F, 0x012, 0x000, 0x00B, 0x009, 0x001, 0x001, 0x016, 0x000, 0x000, 0x000, + 0x003, 0x02C, 0x007, 0x00C, 0x002, 0x001, 0x003, 0x002, 0x008, 0x00C, 0x002, 0x01B, 0x004, + 0x002, 0x002, 0x001, 0x005, 0x001, 0x000, 0x000, 0x015, 0x000, 0x000, 0x00D, 0x008, 0x000, + 0x000, 0x005, 0x026, 0x008, 0x000, 0x000, 0x000, 0x000, 0x013, 0x001, 0x001, 0x000, 0x032, + 0x000, 0x003, 0x00B, 0x006, 0x002, 0x000, 0x000, 0x000, 0x002, 0x003, 0x001, 0x002, 0x000, + 0x033, 0x000, 0x002, 0x004, 0x01D, 0x000, 0x001, 0x003, 0x000, 0x000, 0x000, 0x030, 0x00C, + 0x006, 0x000, 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x005, 0x000, 0x002, 0x001, 0x002, + 0x003, 0x00D, 0x008, 0x000, 0x003, 0x001, 0x000, 0x002, 0x000, 0x000, 0x000, 0x001, 0x008, + 0x000, 0x007, 0x000, 0x000, 0x000, 0x00A, 0x000, 0x003, 0x000, 0x019, 0x000, 0x006, 0x007, + 0x007, 0x005, 0x001, 0x001, 0x001, 0x001, 0x000, 0x004, 0x003, 0x006, 0x00A, 0x000, 0x000, + 0x000, 0x000, 0x001, 0x001, 0x000, 0x003, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x003, + 0x00A, 0x012, 0x000, 0x000, 0x001, 0x000, 0x009, 0x002, 0x003, 0x001, 0x007, 0x000, 0x000, + 0x005, 0x005, 0x000, 0x002, 0x00C, 0x008, 0x016, 0x003, 0x000, 0x000, 0x000, 0x000, 0x007, + 0x009, 0x001, 0x000, 0x000, 0x00A, 0x000, 0x002, 0x000, 0x014, 0x000, 0x002, 0x001, 0x007, + 0x000, 0x004, 0x000, 0x000, 0x000, 0x004, 0x010, 0x002, 0x001, 0x00A, 0x00C, 0x004, 0x000, + 0x003, 0x000, 0x001, 0x00B, 0x000, 0x005, 0x001, 0x00B, 0x000, 0x005, 0x007, 0x005, 0x000, + 0x002, 0x008, 0x002, 0x000, 0x005, 0x006, 0x000, 0x000, 0x000, 0x001, 0x000, 0x006, 0x00C, + 0x021, 0x005, 0x004, 0x000, 0x003, 0x000, 0x000, 0x006, 0x003, 0x000, 0x00B, 0x000, 0x002, + 0x001, 0x000, 0x002, 0x000, 0x000, 0x007, 0x000, 0x001, 0x000, 0x006, 0x000, 0x000, 0x000, + 0x002, 0x004, 0x013, 0x000, 0x013, 0x001, 0x000, 0x007, 0x002, 0x005, 0x000, 0x000, 0x00A, + 0x001, 0x010, 0x009, 0x000, 0x001, 0x003, 0x001, 0x000, 0x000, 0x000, 0x001, 0x000, 0x00C, + 0x001, 0x003, 0x000, 0x009, 0x00E, 0x003, 0x006, 0x001, 0x003, 0x003, 0x000, 0x002, 0x003, + 0x004, 0x000, 0x00C, 0x002, 0x004, 0x010, 0x002, 0x005, 0x001, 0x000, 0x000, 0x004, 0x000, + 0x006, 0x000, 0x000, 0x006, 0x000, 0x000, 0x00C, 0x000, 0x002, 0x000, 0x000, 0x003, 0x000, + 0x004, 0x002, 0x003, 0x001, 0x001, 0x000, 0x001, 0x000, 0x002, 0x001, 0x001, 0x001, 0x000, + 0x001, 0x000, 0x000, 0x003, 0x000, 0x000, 0x004, 0x004, 0x003, 0x000, 0x003, 0x000, 0x000, + 0x010, 0x000, 0x000, 0x001, 0x006, 0x001, 0x003, 0x000, 0x004, 0x001, 0x000, 0x00F, 0x002, + 0x007, 0x001, 0x000, 0x000, 0x006, 0x003, 0x002, 0x000, 0x014, 0x002, 0x02B, 0x000, 0x000, + 0x00E, 0x000, 0x003, 0x000, 0x000, 0x00C, 0x000, 0x006, 0x004, 0x010, 0x007, 0x002, 0x006, + 0x00D, 0x000, 0x003, 0x001, 0x00C, 0x004, 0x001, 0x000, 0x005, 0x002, 0x000, 0x001, 0x00B, + 0x001, 0x001, 0x000, 0x001, 0x000, 0x000, 0x012, 0x000, 0x000, 0x007, 0x000, 0x000, 0x001, + 0x000, 0x004, 0x005, 0x004, 0x000, 0x001, 0x000, 0x002, 0x00C, 0x005, 0x00C, 0x001, 0x007, + 0x001, 0x003, 0x000, 0x005, 0x004, 0x001, 0x000, 0x000, 0x004, 0x000, 0x001, 0x005, 0x004, + 0x001, 0x000, 0x00A, 0x002, 0x001, 0x001, 0x000, 0x001, 0x001, 0x007, 0x000, 0x004, 0x001, + 0x006, 0x005, 0x003, 0x002, 0x001, 0x001, 0x003, 0x000, 0x004, 0x000, 0x005, 0x004, 0x000, + 0x006, 0x002, 0x000, 0x000, 0x007, 0x004, 0x002, 0x000, 0x000, 0x008, 0x000, 0x003, 0x002, + 0x007, 0x002, 0x003, 0x000, 0x000, 0x000, 0x002, 0x003, 0x003, 0x001, 0x000, 0x000, 0x004, + 0x002, 0x003, 0x002, 0x000, 0x000, 0x005, 0x000, 0x001, 0x000, 0x001, 0x000, 0x006, 0x002, + 0x001, 0x003, 0x001, 0x001, 0x000, 0x007, 0x001, 0x000, 0x005, 0x000, 0x001, 0x002, 0x000, + 0x004, 0x000, 0x001, 0x000, 0x004, 0x002, 0x003, 0x002, 0x001, 0x001, 0x003, 0x000, 0x000, + 0x000, 0x003, 0x000, 0x007, 0x002, 0x000, 0x008, 0x004, 0x001, 0x000, 0x001, 0x003, 0x000, + 0x000, 0x00A, 0x000, 0x000, 0x01D, 0x002, 0x000, 0x000, 0x011, 0x000, 0x001, 0x001, 0x003, + 0x000, 0x007, 0x001, 0x000, 0x001, 0x000, 0x002, 0x00B, 0x000, 0x002, 0x003, 0x003, 0x004, + 0x00D, 0x000, 0x001, 0x00A, 0x000, 0x002, 0x008, 0x001, 0x005, 0x001, 0x005, 0x001, 0x000, + 0x003, 0x005, 0x000, 0x002, 0x000, 0x000, 0x000, 0x003, 0x003, 0x001, 0x001, 0x000, 0x000, + 0x000, 0x000, 0x001, 0x000, 0x000, 0x001, 0x000, 0x000, 0x011, 0x001, 0x000, 0x003, 0x001, + 0x002, 0x004, 0x000, 0x004, 0x000, 0x000, 0x00A, 0x000, 0x001, 0x000, 0x001, 0x001, 0x002, + 0x001, 0x000, 0x00C, 0x000, 0x000, 0x001, 0x000, 0x000, 0x002, 0x004, 0x000, 0x000, 0x000, + 0x000, 0x003, 0x005, 0x001, 0x004, 0x000, 0x002, 0x005, 0x001, 0x003, 0x005, 0x001, 0x001, + 0x001, 0x00F, 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x002, 0x003, 0x003, 0x000, 0x005, + 0x003, 0x000, 0x000, 0x000, 0x00A, 0x000, 0x002, 0x003, 0x000, 0x001, 0x006, 0x000, 0x004, + 0x004, 0x000, 0x001, 0x002, 0x000, 0x003, 0x001, 0x000, 0x001, 0x003, 0x003, 0x003, 0x002, + 0x001, 0x007, 0x002, 0x002, 0x003, 0x000, 0x003, 0x001, 0x000, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x006, 0x000, 0x001, 0x005, 0x002, 0x003, 0x003, 0x008, 0x000, 0x000, + 0x000, 0x002, 0x004, 0x001, 0x000, 0x003, 0x002, 0x006, 0x000, 0x00B, 0x002, 0x001, 0x000, + 0x001, 0x000, 0x001, 0x008, 0x004, 0x006, 0x001, 0x000, 0x000, 0x002, 0x009, 0x001, 0x005, + 0x003, 0x002, 0x000, 0x001, 0x001, 0x009, 0x001, 0x007, 0x001, 0x000, 0x001, 0x000, 0x001, + 0x000, 0x002, 0x007, 0x001, 0x002, 0x002, 0x003, 0x001, 0x000, 0x00A, 0x004, 0x000, 0x001, + 0x002, 0x001, 0x005, 0x000, 0x00B, 0x001, 0x000, 0x001, 0x002, 0x000, 0x001, 0x007, 0x000, + 0x001, 0x001, 0x001, 0x005, 0x003, 0x001, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, + 0x000, 0x000, 0x003, 0x003, 0x000, 0x000, 0x001, 0x007, 0x001, 0x004, 0x001, 0x002, 0x001, + 0x000, 0x008, 0x000, 0x003, 0x000, 0x003, 0x004, 0x006, 0x002, 0x001, 0x000, 0x000, 0x000, + 0x001, 0x003, 0x003, 0x003, 0x005, 0x000, 0x002, 0x003, 0x003, 0x003, 0x001, 0x003, 0x003, + 0x001, 0x002, 0x000, 0x002, 0x000, 0x000, 0x000, 0x001, 0x001, 0x000, 0x001, 0x006, 0x002, + 0x001, 0x000, 0x000, 0x003, 0x001, 0x002, 0x008, 0x001, 0x002, 0x000, 0x000, 0x000, 0x002, + 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, 0x002, 0x002, 0x003, 0x003, 0x003, 0x000, 0x003, + 0x001, 0x001, 0x006, 0x000, 0x000, 0x002, 0x002, 0x001, 0x001, 0x001, 0x005, 0x000, 0x003, + 0x002, 0x000, 0x004, 0x008, 0x000, 0x000, 0x001, 0x002, 0x000, 0x000, 0x004, 0x001, 0x002, + 0x000, 0x000, 0x001, 0x000, 0x001, 0x001, 0x001, 0x001, 0x000, 0x002, 0x001, 0x000, 0x001, + 0x000, 0x000, 0x001, 0x000, 0x004, 0x002, 0x000, 0x000, 0x002, 0x001, 0x003, 0x000, 0x000, + 0x000, 0x001, 0x003, 0x003, 0x000, 0x003, 0x004, 0x002, 0x002, 0x000, 0x000, 0x001, 0x001, + 0x000, 0x006, 0x000, 0x002, 0x000, 0x00C, 0x001, 0x001, 0x002, 0x001, 0x000, 0x002, 0x001, + 0x001, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x005, + 0x001, 0x000, 0x005, 0x000, 0x000, 0x003, 0x001, 0x000, 0x000, 0x001, 0x000, 0x000, 0x005, + 0x001, 0x001, 0x000, 0x001, 0x001, 0x007, 0x003, 0x002, 0x004, 0x000, 0x003, 0x002, 0x001, +]; +pub(crate) const TRAILING_NONSTARTERS_KV: &[u32] = &[ + 0x030D401, 0x01F2E02, 0x01F1D02, 0x0227801, 0x0224901, 0x000E101, 0x01FFE01, 0x001A001, + 0x01F0A02, 0x0022901, 0x0307401, 0x01F6C02, 0x01E7601, 0x030B001, 0x004D001, 0x0FB3801, + 0x01EA902, 0x0FEF901, 0x0038F01, 0x01F3101, 0x0011701, 0x0034301, 0x0226201, 0x01FF801, + 0x00F7302, 0x0FE8B01, 0x0307601, 0x003AE01, 0x01FC202, 0x0FC6002, 0x0224101, 0x0012B01, + 0x01F0402, 0x0220401, 0x003B002, 0x01F9A03, 0x01EB702, 0x01E9301, 0x00A5B01, 0x01F5602, + 0x0021B01, 0x1D1C002, 0x1D16102, 0x0016E01, 0x01FD202, 0x01EEF02, 0x030AC01, 0x01F3502, + 0x01FE101, 0x01E6802, 0x004E701, 0x0010801, 0x0309E01, 0x01F3302, 0x01EC901, 0x001FA02, + 0x01E7B02, 0x01EDE02, 0x01FE702, 0x01FD001, 0x01E2E02, 0x01EBF02, 0x0034101, 0x0227001, + 0x01FBF01, 0x001C401, 0x01F9403, 0x01FAB03, 0x01E5102, 0x01F0101, 0x001AF01, 0x0045101, + 0x004F001, 0x0038E01, 0x0016401, 0x01F4801, 0x004EA01, 0x01EBB01, 0x01EAF02, 0x0FB4801, + 0x01E2201, 0x01EEA02, 0x01F7A01, 0x0FB4A01, 0x000E701, 0x01E1B01, 0x0011D01, 0x0FB3601, + 0x0017901, 0x0012201, 0x0FB3B01, 0x01E5D02, 0x0012A01, 0x0FC5F02, 0x01EF102, 0x003D301, + 0x0227401, 0x01FA802, 0x01FC301, 0x0FEF501, 0x0047601, 0x0022D02, 0x004DC01, 0x001FB02, + 0x0014D01, 0x030DA01, 0x0020A01, 0x01FFC01, 0x0016201, 0x01FC901, 0x0FC5C01, 0x01FB202, + 0x030BA01, 0x01F2702, 0x000CB01, 0x01FEA01, 0x003CA01, 0x0021601, 0x0015601, 0x003AC01, + 0x004D301, 0x0045D01, 0x01E4801, 0x01EAD02, 0x030D701, 0x022E301, 0x01F9303, 0x001DA02, + 0x01FC702, 0x0017501, 0x030BC01, 0x01E6602, 0x0010D01, 0x01FB402, 0x030FE01, 0x0FC6102, + 0x01FE801, 0x01FFB01, 0x000FC01, 0x01EE401, 0x000C301, 0x01E3701, 0x000EB01, 0x001D301, + 0x000CD01, 0x0FB1F01, 0x01E0802, 0x0FE8C01, 0x0FB4701, 0x01EE002, 0x01E6402, 0x01E9801, + 0x0FB4101, 0x01ECE01, 0x0011201, 0x01EF301, 0x001D001, 0x0307101, 0x01E3C01, 0x01FC001, + 0x0FCD901, 0x01E8401, 0x01E8201, 0x0FB3301, 0x01F8703, 0x01E6C01, 0x0FB4001, 0x01F6901, + 0x01E7701, 0x01FBB01, 0x0FE7D01, 0x01E8D01, 0x0220901, 0x01E5C02, 0x0011301, 0x01E1E01, + 0x009DC01, 0x01F1A02, 0x01FCD02, 0x0FCF202, 0x0309C01, 0x01E4D02, 0x030C701, 0x01FCE02, + 0x01E8101, 0x000E301, 0x01E5601, 0x0FB1D01, 0x00F8102, 0x01E8701, 0x01E6201, 0x0040101, + 0x01F2202, 0x0062601, 0x0015B01, 0x01F3901, 0x01FB901, 0x0020B01, 0x0014C01, 0x01F9203, + 0x01E0902, 0x01E3F01, 0x01F7901, 0x01F2F02, 0x0226E01, 0x01F3B02, 0x030D101, 0x004EF01, + 0x000B801, 0x0227901, 0x01E6001, 0x000D601, 0x0017B01, 0x01E6A01, 0x0015101, 0x01F4B02, + 0x0010001, 0x022ED01, 0x030D601, 0x01FCB01, 0x01E3902, 0x0040701, 0x004ED01, 0x01ED202, + 0x01EE202, 0x0304E01, 0x0FB3901, 0x0305A01, 0x01ECF01, 0x0011601, 0x01E2001, 0x0017601, + 0x0FB3401, 0x0093101, 0x004EE01, 0x0330401, 0x0012301, 0x01FE302, 0x0020F01, 0x01FA403, + 0x01F8F03, 0x00F7702, 0x01F5502, 0x001EF01, 0x000EA01, 0x01FAF03, 0x000FA01, 0x0022F01, + 0x01E2901, 0x004E201, 0x004C201, 0x004EC01, 0x0039002, 0x01FB702, 0x0FC5E02, 0x0012401, + 0x01F3A02, 0x0FB2C02, 0x01F9102, 0x0228401, 0x01EC102, 0x000F901, 0x000E801, 0x01EA101, + 0x004E401, 0x0021A01, 0x0FB4901, 0x0017A01, 0x0010F01, 0x01FB601, 0x001FF01, 0x001E201, + 0x004D701, 0x01F5302, 0x01EB801, 0x01FAA03, 0x0FCF402, 0x01F0901, 0x0017801, 0x0305401, + 0x01F6202, 0x01F6E02, 0x000A801, 0x01EAB02, 0x0016B01, 0x01EA201, 0x01F9D03, 0x01F2101, + 0x00F7601, 0x01FCC01, 0x01E3A01, 0x0013C01, 0x01E5A01, 0x001EC02, 0x0021401, 0x01EEE02, + 0x01F8503, 0x0307901, 0x0015E01, 0x0FE8401, 0x01E7501, 0x0306501, 0x0013B01, 0x0305801, + 0x01E8901, 0x0FC6202, 0x01E9201, 0x0011A01, 0x105E401, 0x0222601, 0x0010401, 0x01F2602, + 0x0227501, 0x0095901, 0x01F7301, 0x0014E01, 0x01EF701, 0x0043901, 0x01E2501, 0x0FB4C01, + 0x1109A01, 0x01F6101, 0x01E4101, 0x0010E01, 0x01FED02, 0x01EA402, 0x0021F01, 0x004D201, + 0x01F0302, 0x003D401, 0x0307701, 0x01FB101, 0x01E1101, 0x01F1402, 0x0014401, 0x0332101, + 0x0010C01, 0x01F4402, 0x0038502, 0x0305C01, 0x01E4301, 0x001DE02, 0x01F3702, 0x01EC502, + 0x004DE01, 0x0306001, 0x01FE601, 0x01EC002, 0x001ED02, 0x0015401, 0x000E001, 0x01F9C03, + 0x0021701, 0x1D15F01, 0x01E1602, 0x01ED902, 0x0FB2D02, 0x0FB3E01, 0x0020101, 0x01E4F02, + 0x01E4001, 0x0015501, 0x004E501, 0x01FA303, 0x01EE501, 0x0020701, 0x0FC6302, 0x01E9601, + 0x01FCF02, 0x0228001, 0x001A101, 0x0017301, 0x0022E01, 0x01F0F02, 0x01F9F03, 0x001D602, + 0x0FB3201, 0x1D1BD02, 0x00F7902, 0x003AB01, 0x01EC202, 0x01F0B02, 0x000E401, 0x0016A01, + 0x01F7001, 0x030D301, 0x01FA203, 0x0FF9E01, 0x01EE802, 0x01FF202, 0x01F6A02, 0x01E4E02, + 0x01E0E01, 0x01E2701, 0x0201701, 0x030DD01, 0x00C4801, 0x01EAC02, 0x01E9B01, 0x01EF801, + 0x021CD01, 0x00B5C01, 0x0305201, 0x0034402, 0x01F5901, 0x030B801, 0x0045301, 0x01E2B01, + 0x0016801, 0x01F9703, 0x01FA902, 0x01EDF02, 0x030F401, 0x0FBB101, 0x01F6302, 0x01E7F01, + 0x01EB002, 0x0017001, 0x01EE902, 0x0224401, 0x000C701, 0x01EEC02, 0x01FEC01, 0x0FE7F01, + 0x0FEF801, 0x01EB402, 0x01EBD01, 0x01F8902, 0x01FA002, 0x01EAE02, 0x0034001, 0x01F1B02, + 0x0010301, 0x0011C01, 0x01E1201, 0x0020E01, 0x0021001, 0x01F4001, 0x0FE8901, 0x01E1C02, + 0x0011E01, 0x00A5901, 0x004DF01, 0x0307C01, 0x0020601, 0x003CB01, 0x0FB3A01, 0x0022B02, + 0x002D901, 0x01F6F02, 0x00DDA01, 0x0015D01, 0x0047701, 0x030F701, 0x0FD3D01, 0x0FE7B01, + 0x000CE01, 0x0023102, 0x0FB3001, 0x110AB01, 0x0228501, 0x0334001, 0x01E5801, 0x004F301, + 0x001F801, 0x01F7101, 0x0017401, 0x001C601, 0x0040301, 0x01E4B01, 0x000D401, 0x01F9802, + 0x004D601, 0x01F1101, 0x030BE01, 0x0FE7901, 0x001E102, 0x000DD01, 0x000F101, 0x01EA001, + 0x002DA01, 0x01F3E02, 0x022AD01, 0x01F8403, 0x0045C01, 0x01EF401, 0x01E3601, 0x006D301, + 0x01E6301, 0x004F401, 0x01E3101, 0x01E8001, 0x01FAD03, 0x01F4302, 0x0011401, 0x0016F01, + 0x01F1202, 0x0013901, 0x01F9E03, 0x00A3301, 0x01EA502, 0x0011801, 0x01F0E02, 0x01E9101, + 0x0203E01, 0x01E5B01, 0x000C401, 0x0021E01, 0x0017C01, 0x0226001, 0x0FEF701, 0x01F8802, + 0x0334E01, 0x01F2502, 0x01FD302, 0x0095D01, 0x0038C01, 0x0012F01, 0x0040001, 0x01E7C01, + 0x0017201, 0x0FB4D01, 0x01E6702, 0x00F7502, 0x01E0201, 0x0045701, 0x000D901, 0x01F0001, + 0x01E1D02, 0x000C501, 0x0FCF302, 0x0333B01, 0x000B401, 0x01FBD01, 0x030C001, 0x004F801, + 0x022AF01, 0x004D101, 0x001F901, 0x01E0C01, 0x0FE7001, 0x000EE01, 0x01EDD02, 0x01E7D01, + 0x01F7801, 0x1D15E01, 0x01EB502, 0x0FB4401, 0x000E901, 0x022E201, 0x001EB01, 0x0015A01, + 0x01F6702, 0x0219B01, 0x002DD01, 0x0017D01, 0x01E2101, 0x0022C02, 0x01E1001, 0x01E5002, + 0x01E0601, 0x01E3001, 0x01F7601, 0x001D802, 0x0095E01, 0x0045001, 0x004F101, 0x01FDD02, + 0x0307301, 0x004EB01, 0x01E8E01, 0x1D1BE02, 0x0020501, 0x000DC01, 0x0FE8601, 0x01F7401, + 0x0FE4901, 0x01FA703, 0x030B201, 0x01E5501, 0x01FF301, 0x01E4901, 0x01E5E01, 0x01EB901, + 0x01E0D01, 0x01F7C01, 0x01F5001, 0x0FBB001, 0x01ED002, 0x0FB3C01, 0x0222401, 0x003AA01, + 0x003AF01, 0x01FB301, 0x01ECA01, 0x01E4C02, 0x0015701, 0x0040C01, 0x01EDA02, 0x01E3401, + 0x01E1301, 0x01F0502, 0x0020C01, 0x01FEE02, 0x01F5B02, 0x004F901, 0x01FD601, 0x0FB2E01, + 0x01E4501, 0x000ED01, 0x0045E01, 0x01FE901, 0x0020001, 0x0012101, 0x01E8F01, 0x0013601, + 0x0020301, 0x1D16302, 0x001E801, 0x001F401, 0x01E8A01, 0x01FC102, 0x01EDB02, 0x01F2D02, + 0x0016301, 0x01F2801, 0x000E201, 0x000C201, 0x01EF901, 0x01FBC01, 0x01FB801, 0x021CF01, + 0x009DF01, 0x01E3D01, 0x01EB602, 0x01F8603, 0x0022A02, 0x0010501, 0x01FC801, 0x0040E01, + 0x0037A01, 0x01F8B03, 0x01F4A02, 0x01F0D02, 0x01ED102, 0x01E8C01, 0x01EB102, 0x01E3B01, + 0x0FC5B01, 0x021CE01, 0x01E3E01, 0x004DD01, 0x01E4401, 0x01F6502, 0x0FEF601, 0x004F201, + 0x030F801, 0x002D801, 0x01EC801, 0x01EE701, 0x000FD01, 0x01ED702, 0x01EBC01, 0x0011501, + 0x01F5F02, 0x0FE7801, 0x01E7802, 0x1D16002, 0x0038901, 0x1D1BB01, 0x0010701, 0x0306901, + 0x0FB4301, 0x0016C01, 0x01EF501, 0x01FB001, 0x01F3801, 0x0228801, 0x01FDE02, 0x0226F01, + 0x0FE8501, 0x0FE7201, 0x003CD01, 0x0021801, 0x0013501, 0x01F8203, 0x0020901, 0x01FD101, + 0x000F201, 0x0021101, 0x0014601, 0x1D16202, 0x01E5F01, 0x004DB01, 0x0015F01, 0x02ADC01, + 0x0095B01, 0x01F6001, 0x01FDB01, 0x0FB4E01, 0x0228901, 0x01E2301, 0x0305601, 0x022AC01, + 0x01E7301, 0x01E7A02, 0x01E7401, 0x01FBA01, 0x001FE01, 0x01EB302, 0x01F2402, 0x0FD3C01, + 0x01E7201, 0x0038401, 0x0012E01, 0x0013701, 0x000EF01, 0x01E0101, 0x021AE01, 0x0333201, + 0x000DA01, 0x001DB02, 0x001F001, 0x01E5202, 0x0307D01, 0x000F301, 0x001EA01, 0x0012D01, + 0x01ED802, 0x01F2001, 0x00B5D01, 0x0021901, 0x01E1502, 0x0FE4A01, 0x01FD801, 0x01F1C02, + 0x0020201, 0x000C801, 0x01EEB02, 0x01E2401, 0x004F501, 0x01FAC03, 0x030DC01, 0x022AE01, + 0x030F901, 0x01E2A01, 0x01EF002, 0x01E0701, 0x01F3D02, 0x01FE001, 0x01F7201, 0x01ED402, + 0x001FC01, 0x0012001, 0x01F7701, 0x0304C01, 0x01E4201, 0x0062201, 0x004E301, 0x01FEB01, + 0x01ECD01, 0x01FC402, 0x01E8501, 0x01F5202, 0x01F6D02, 0x01EA301, 0x030C201, 0x0095A01, + 0x01F3202, 0x01F8102, 0x01E2801, 0x006C201, 0x01E9901, 0x0017101, 0x01F2A02, 0x01ED602, + 0x001E601, 0x01F3001, 0x01F3F02, 0x000C001, 0x000DB01, 0x000F601, 0x1D16402, 0x01EBA01, + 0x0015901, 0x0331E01, 0x000C901, 0x030C901, 0x0FC5D01, 0x01F8A03, 0x0020401, 0x01E1901, + 0x01F4D02, 0x01F2C02, 0x01FF901, 0x0013401, 0x01EB202, 0x0015C01, 0x01E6F01, 0x0FE8301, + 0x001D401, 0x001F501, 0x01F8D03, 0x0093401, 0x0041901, 0x0038801, 0x009DD01, 0x01EBE02, + 0x01EC602, 0x01F5702, 0x01E6101, 0x0010A01, 0x002DB01, 0x001C501, 0x001E002, 0x0014701, + 0x0306701, 0x0012C01, 0x022E101, 0x01F4202, 0x004DA01, 0x0023301, 0x01E2601, 0x01F1302, + 0x01F8C03, 0x022EC01, 0x0062501, 0x01F5D02, 0x01E8B01, 0x1F21301, 0x0010101, 0x01ED502, + 0x01FE202, 0x003AD01, 0x000D201, 0x01FF601, 0x001E901, 0x000C101, 0x01F1001, 0x01E9701, + 0x01E0301, 0x030B601, 0x01E1A01, 0x001CE01, 0x001B001, 0x0011F01, 0x0022701, 0x01E3501, + 0x01F0602, 0x001E701, 0x01ED302, 0x01FFD01, 0x01E2D01, 0x0092901, 0x01E8301, 0x0062301, + 0x01E6E01, 0x0306201, 0x0021501, 0x0228101, 0x000CA01, 0x01E5701, 0x01FDA01, 0x01F4502, + 0x0FE8101, 0x01E5302, 0x0022601, 0x000E501, 0x0FE8A01, 0x01E9001, 0x022E001, 0x01F9603, + 0x01EA602, 0x001D902, 0x01F2901, 0x01F5402, 0x0FB2B01, 0x01FD702, 0x001D502, 0x0FF9F01, + 0x0FE7101, 0x001E301, 0x000CF01, 0x01FCA01, 0x01F8E03, 0x01E4701, 0x000AF01, 0x0FE7E01, + 0x0FE7401, 0x0FB2A01, 0x01F7501, 0x0334B01, 0x001D201, 0x022EA01, 0x001CF01, 0x01E6502, + 0x002DC01, 0x01F3C02, 0x0307A01, 0x001DF02, 0x001EE01, 0x0305001, 0x01E7902, 0x00DDD01, + 0x01EA802, 0x0021201, 0x01E2F02, 0x0FE4C01, 0x0040D01, 0x01F4101, 0x0023201, 0x01E8801, + 0x01F2302, 0x01EED02, 0x01F0C02, 0x0FB4601, 0x01F6801, 0x0062401, 0x01E2C01, 0x01ECB01, + 0x0FE8701, 0x01E5901, 0x01E0A01, 0x01E1F01, 0x00A5A01, 0x0017701, 0x01E5401, 0x0FB2F01, + 0x01FAE03, 0x00A3601, 0x01ECC01, 0x0FB3501, 0x000D301, 0x01EF601, 0x01F8303, 0x0FEFA01, + 0x0095F01, 0x01FFA01, 0x01E3301, 0x01E1801, 0x0FB4B01, 0x01E7E01, 0x00A5E01, 0x0330701, + 0x01E6D01, 0x030FA01, 0x000EC01, 0x01F0202, 0x0038601, 0x01F5101, 0x01F1901, 0x01F1502, + 0x0016001, 0x01E4601, 0x0038A01, 0x0FC9001, 0x0016901, 0x01F1801, 0x0220C01, 0x01E0B01, + 0x030C501, 0x0020D01, 0x01F9B03, 0x0021301, 0x0010601, 0x0FE7A01, 0x00F7801, 0x0013A01, + 0x01E6B01, 0x01FE501, 0x0012801, 0x001FD01, 0x01E6902, 0x0FE8201, 0x01F4901, 0x01E3201, + 0x01E0001, 0x1109C01, 0x01F7B01, 0x0FE8801, 0x0FE4B01, 0x0010B01, 0x000D501, 0x01F6402, + 0x001CD01, 0x01E1702, 0x01FA503, 0x01FD901, 0x01EC402, 0x004E601, 0x0014801, 0x001D101, + 0x01F9902, 0x01F6B02, 0x01F8002, 0x0FBA501, 0x01EC702, 0x01F6602, 0x0015001, 0x0212B01, + 0x0013E01, 0x01EDC02, 0x01EA702, 0x0023002, 0x004C101, 0x0016D01, 0x01F0702, 0x01F2B02, + 0x0012501, 0x01F4C02, 0x030D001, 0x0305E01, 0x0010201, 0x006C001, 0x0309401, 0x0012901, + 0x0016101, 0x0224701, 0x0011901, 0x0FFE301, 0x01E0501, 0x105C901, 0x1D1BC01, 0x0307001, + 0x0017E01, 0x01FA603, 0x01FA102, 0x01E9401, 0x0309B01, 0x0022801, 0x01E0F01, 0x0016501, + 0x01EC302, 0x0020801, 0x000CC01, 0x01F9002, 0x003CC01, 0x01FC601, 0x01EE302, 0x01E4A01, + 0x003CE01, 0x0095C01, 0x01FF702, 0x001D702, 0x0227101, 0x01EE102, 0x01E7101, 0x000FB01, + 0x0095801, 0x01EAA02, 0x000F501, 0x1D1BF02, 0x0011B01, 0x01F7D01, 0x022EB01, 0x0013D01, + 0x01F0801, 0x0014F01, 0x01F3602, 0x0FB3101, 0x01FE401, 0x01F9503, 0x0014301, 0x0015801, + 0x01EE601, 0x0FE7C01, 0x01FDF02, 0x01E0401, 0x01E7001, 0x0331001, 0x000F401, 0x0FE7701, + 0x01E1402, 0x0FE7601, 0x01E3802, 0x030B401, 0x01F3402, 0x0226D01, 0x000FF01, 0x01E8601, + 0x0014501, 0x0013001, 0x030D901, 0x001DC02, 0x01EF201, 0x0FBA401, 0x01FF402, 0x01E9501, + 0x030AE01, 0x0010901, 0x0219A01, 0x000D101, +]; diff --git a/third_party/rust/unicode-normalization/src/test.rs b/third_party/rust/unicode-normalization/src/test.rs new file mode 100644 index 000000000000..cd1d9584f5b5 --- /dev/null +++ b/third_party/rust/unicode-normalization/src/test.rs @@ -0,0 +1,130 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::char::is_combining_mark; +use super::UnicodeNormalization; +use core::char; + +#[cfg(not(feature = "std"))] +use alloc::string::{String, ToString}; + +#[test] +fn test_nfd() { + macro_rules! t { + ($input: expr, $expected: expr) => { + assert_eq!($input.nfd().to_string(), $expected); + // A dummy iterator that is not std::str::Chars directly; + // note that `id_func` is used to ensure `Clone` implementation + assert_eq!( + $input.chars().map(|c| c).nfd().collect::(), + $expected + ); + }; + } + t!("abc", "abc"); + t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}"); + t!("\u{2026}", "\u{2026}"); + t!("\u{2126}", "\u{3a9}"); + t!("\u{1e0b}\u{323}", "d\u{323}\u{307}"); + t!("\u{1e0d}\u{307}", "d\u{323}\u{307}"); + t!("a\u{301}", "a\u{301}"); + t!("\u{301}a", "\u{301}a"); + t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}"); + t!("\u{ac1c}", "\u{1100}\u{1162}"); +} + +#[test] +fn test_nfkd() { + macro_rules! t { + ($input: expr, $expected: expr) => { + assert_eq!($input.nfkd().to_string(), $expected); + }; + } + t!("abc", "abc"); + t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}"); + t!("\u{2026}", "..."); + t!("\u{2126}", "\u{3a9}"); + t!("\u{1e0b}\u{323}", "d\u{323}\u{307}"); + t!("\u{1e0d}\u{307}", "d\u{323}\u{307}"); + t!("a\u{301}", "a\u{301}"); + t!("\u{301}a", "\u{301}a"); + t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}"); + t!("\u{ac1c}", "\u{1100}\u{1162}"); +} + +#[test] +fn test_nfc() { + macro_rules! t { + ($input: expr, $expected: expr) => { + assert_eq!($input.nfc().to_string(), $expected); + }; + } + t!("abc", "abc"); + t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}"); + t!("\u{2026}", "\u{2026}"); + t!("\u{2126}", "\u{3a9}"); + t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}"); + t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}"); + t!("a\u{301}", "\u{e1}"); + t!("\u{301}a", "\u{301}a"); + t!("\u{d4db}", "\u{d4db}"); + t!("\u{ac1c}", "\u{ac1c}"); + t!( + "a\u{300}\u{305}\u{315}\u{5ae}b", + "\u{e0}\u{5ae}\u{305}\u{315}b" + ); +} + +#[test] +fn test_nfkc() { + macro_rules! t { + ($input: expr, $expected: expr) => { + assert_eq!($input.nfkc().to_string(), $expected); + }; + } + t!("abc", "abc"); + t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}"); + t!("\u{2026}", "..."); + t!("\u{2126}", "\u{3a9}"); + t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}"); + t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}"); + t!("a\u{301}", "\u{e1}"); + t!("\u{301}a", "\u{301}a"); + t!("\u{d4db}", "\u{d4db}"); + t!("\u{ac1c}", "\u{ac1c}"); + t!( + "a\u{300}\u{305}\u{315}\u{5ae}b", + "\u{e0}\u{5ae}\u{305}\u{315}b" + ); +} + +#[test] +fn test_normalize_char() { + assert_eq!('\u{2126}'.nfd().to_string(), "\u{3a9}") +} + +#[test] +fn test_is_combining_mark_ascii() { + for cp in 0..0x7f { + assert!(!is_combining_mark(char::from_u32(cp).unwrap())); + } +} + +#[test] +fn test_is_combining_mark_misc() { + // https://github.com/unicode-rs/unicode-normalization/issues/16 + // U+11C3A BHAIKSUKI VOWEL SIGN O + // Category: Mark, Nonspacing [Mn] + assert!(is_combining_mark('\u{11C3A}')); + + // U+11C3F BHAIKSUKI SIGN VIRAMA + // Category: Mark, Nonspacing [Mn] + assert!(is_combining_mark('\u{11C3F}')); +} diff --git a/third_party/rust/viaduct/.cargo-checksum.json b/third_party/rust/viaduct/.cargo-checksum.json index af980b3229d7..a476136b8a4e 100644 --- a/third_party/rust/viaduct/.cargo-checksum.json +++ b/third_party/rust/viaduct/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"0f74fac18c6b7c0c3b6e16fe6e25f6b4a068fe8aa6e617c2b5ba3294cac1de87","README.md":"7507842687c0a9f7146318fe1541183a2fdca65ec86aafb12207c994012ab15a","src/backend.rs":"22c313dd0ecbe92803219d3770bb97b3f876ed2fdc4ac8b5ac8dbea92b563e9f","src/backend/ffi.rs":"a1ccc25c3f52cc94718624d39c082c9c7e34082804bb12f0b96f5d3a064e0c54","src/error.rs":"98ca92b58bd8b4f3c9d4c6d03ed235609d486fe8121277004283b9cfda6e3260","src/fetch_msg_types.proto":"de8a46a4947a140783a4d714364f18ccf02c4759d6ab5ace9da0b1c058efa6c3","src/headers.rs":"bf3cd6b717dfb337c64ce0bc6d275364181884378fc47afed7c80c435ce0733f","src/headers/name.rs":"dcfd4d42326724f822893cf6ac90f1e14734dba178150dcb606f4b19de5e66d7","src/lib.rs":"abddea31021b5743e4cc6d20c0bd89dc59b248a15405bf9717c79ed732950a35","src/mozilla.appservices.httpconfig.protobuf.rs":"9ede762489a0c07bc08a5b852b33013a410cb41b44b92a44555f85bb2db91412","src/settings.rs":"f62d0779d7b86af5daad0c23fb61a5982c11520e6fa528ebe2e2d6ad76e70afd"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"7d1b3d433b80240513e0baf8134725481593861ee19c4c5d9d3412c9cf6a7b80","README.md":"7507842687c0a9f7146318fe1541183a2fdca65ec86aafb12207c994012ab15a","src/backend.rs":"69007970c1ed57d976f0f3b081577242e4cf015836da487087f144c1256afc12","src/backend/ffi.rs":"f8ed4c9085906b7fa68291e97e2a89933e363b3a54fe8ed2d24edd396d6e7b48","src/error.rs":"98ca92b58bd8b4f3c9d4c6d03ed235609d486fe8121277004283b9cfda6e3260","src/fetch_msg_types.proto":"de8a46a4947a140783a4d714364f18ccf02c4759d6ab5ace9da0b1c058efa6c3","src/headers.rs":"bf3cd6b717dfb337c64ce0bc6d275364181884378fc47afed7c80c435ce0733f","src/headers/name.rs":"6014813c502792ad2d01c31ac2d62909d8402457337b03392c586e983d38b2fa","src/lib.rs":"9787e99bffa6e6edc3ce81f4b0be65f9361938387a3f24f29232694a9b021227","src/mozilla.appservices.httpconfig.protobuf.rs":"9ede762489a0c07bc08a5b852b33013a410cb41b44b92a44555f85bb2db91412","src/settings.rs":"f62d0779d7b86af5daad0c23fb61a5982c11520e6fa528ebe2e2d6ad76e70afd"},"package":null} \ No newline at end of file diff --git a/third_party/rust/viaduct/Cargo.toml b/third_party/rust/viaduct/Cargo.toml index 20b4996dc731..1aeb05811640 100644 --- a/third_party/rust/viaduct/Cargo.toml +++ b/third_party/rust/viaduct/Cargo.toml @@ -34,7 +34,6 @@ path = "src/lib.rs" [dependencies] ffi-support = "0.4" -log = "0.4" once_cell = "1.5" prost = "0.12" serde = "1" @@ -42,5 +41,8 @@ serde_json = "1" thiserror = "1.0" url = "2" +[dependencies.error-support] +path = "../support/error" + [dependencies.parking_lot] version = ">=0.11,<=0.12" diff --git a/third_party/rust/viaduct/src/backend.rs b/third_party/rust/viaduct/src/backend.rs index 599a26bd986d..09285a63883b 100644 --- a/third_party/rust/viaduct/src/backend.rs +++ b/third_party/rust/viaduct/src/backend.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::GLOBAL_SETTINGS; +use crate::{info, trace}; use ffi::FfiBackend; use once_cell::sync::OnceCell; mod ffi; @@ -14,11 +15,11 @@ pub fn note_backend(which: &str) { static NOTE_BACKEND_ONCE: std::sync::Once = std::sync::Once::new(); let mut called = false; NOTE_BACKEND_ONCE.call_once(|| { - log::info!("Using HTTP backend {}", which); + info!("Using HTTP backend {}", which); called = true; }); if !called { - log::trace!("Using HTTP backend {}", which); + trace!("Using HTTP backend {}", which); } } diff --git a/third_party/rust/viaduct/src/backend/ffi.rs b/third_party/rust/viaduct/src/backend/ffi.rs index a4bc685cb1bd..b6348ed46f53 100644 --- a/third_party/rust/viaduct/src/backend/ffi.rs +++ b/third_party/rust/viaduct/src/backend/ffi.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::{backend::Backend, settings::GLOBAL_SETTINGS}; -use crate::{msg_types, Error}; +use crate::{error, msg_types, warn, Error}; use ffi_support::{ByteBuffer, FfiStr}; ffi_support::implement_into_ffi_by_protobuf!(msg_types::Request); @@ -29,7 +29,7 @@ impl From for msg_types::Request { macro_rules! backend_error { ($($args:tt)*) => {{ let msg = format!($($args)*); - log::error!("{}", msg); + error!("{}", msg); Error::BackendError(msg) }}; } @@ -77,7 +77,7 @@ impl Backend for FfiBackend { Ok(name) => name, Err(e) => { // Ignore headers with invalid names, since nobody can look for them anyway. - log::warn!("Server sent back invalid header name: '{}'", e); + warn!("Server sent back invalid header name: '{}'", e); continue; } }; @@ -119,6 +119,7 @@ type FetchCallback = unsafe extern "C" fn(ByteBuffer) -> ByteBuffer; /// Module that manages get/set of the global fetch callback pointer. mod callback_holder { use super::FetchCallback; + use crate::error; use std::sync::atomic::{AtomicUsize, Ordering}; /// Note: We only assign to this once. @@ -158,7 +159,7 @@ mod callback_holder { // it sets this only once. Note that this is actually going to be // before logging is initialized in practice, so there's not a lot // we can actually do here. - log::error!("Bug: Initialized CALLBACK_PTR multiple times"); + error!("Bug: Initialized CALLBACK_PTR multiple times"); false } } @@ -179,9 +180,7 @@ pub extern "C" fn viaduct_alloc_bytebuffer(sz: i32) -> ByteBuffer { #[no_mangle] pub extern "C" fn viaduct_log_error(s: FfiStr<'_>) { let mut error = ffi_support::ExternError::default(); - ffi_support::call_with_output(&mut error, || { - log::error!("Viaduct Ffi Error: {}", s.as_str()) - }); + ffi_support::call_with_output(&mut error, || error!("Viaduct Ffi Error: {}", s.as_str())); error.consume_and_log_if_error(); } diff --git a/third_party/rust/viaduct/src/headers/name.rs b/third_party/rust/viaduct/src/headers/name.rs index 7fe322ddd6c4..3cccef20bd91 100644 --- a/third_party/rust/viaduct/src/headers/name.rs +++ b/third_party/rust/viaduct/src/headers/name.rs @@ -107,7 +107,7 @@ impl std::fmt::Display for HeaderName { #[cold] #[inline(never)] fn invalid_header_name(s: Cow<'static, str>) -> InvalidHeaderName { - log::warn!("Invalid header name: {}", s); + crate::warn!("Invalid header name: {}", s); InvalidHeaderName(s) } // Note: 0 = invalid, 1 = valid, 2 = valid but needs lowercasing. I'd use an diff --git a/third_party/rust/viaduct/src/lib.rs b/third_party/rust/viaduct/src/lib.rs index eb751ce6af2b..ab88d2fea8ee 100644 --- a/third_party/rust/viaduct/src/lib.rs +++ b/third_party/rust/viaduct/src/lib.rs @@ -13,6 +13,8 @@ mod backend; pub mod error; pub mod settings; pub use error::*; +// reexport logging helpers. +pub use error_support::{debug, error, info, trace, warn}; pub use backend::{note_backend, set_backend, Backend}; pub use headers::{consts as header_names, Header, HeaderName, Headers, InvalidHeaderName}; diff --git a/third_party/rust/webext-storage/.cargo-checksum.json b/third_party/rust/webext-storage/.cargo-checksum.json index 0536e1dae42d..944856042bbe 100644 --- a/third_party/rust/webext-storage/.cargo-checksum.json +++ b/third_party/rust/webext-storage/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"593176ab8f1999a5d71dedac7a50e7b0b66815807f630a50ace84948bd1c6838","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"f4ff15cd54890d3e3636e77a0458ba9a8882f271ccb0056a0bbae1975cdd75d5","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"6a3c3e09797df06165091a3d66e3830febb63bd901250f89f7d6886ba0f408cd","src/db.rs":"9676325b259faadecfc28180d43f8b0a640a1204c2783fc626137eee62a9089b","src/error.rs":"10d99e3dc6a38951456c0fac7e46fb4f441e976b47fdddea257badbc66b8702d","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"e00636eb57498ab015387b08ffe64618dca31e95977e60be624aa259d7dfe4b5","src/migration.rs":"a87a9628f31a4b5a1d1610f80fb37ddb8f94c28a9455980bd5153198d1d7aa2a","src/schema.rs":"d90556dcfa5784a2d3e9432968b6eed60630e3bff5978d73abd8da2b4c71ea63","src/store.rs":"a898492e4a53472414e114ad275bf6a750313a228e589814d73c803f6ce59288","src/sync/bridge.rs":"14d095bc67e511297b833e279912f61dd67993a877be941cc058afe9017cb058","src/sync/incoming.rs":"5899c880810968e1e99f4b2de5ea1eb9d0886643eea85c851571e4ac6f2eca08","src/sync/mod.rs":"75091c8f3138fa5585352b5ea7e5967088e76b1857d24cc02d3e142c0ee9e89d","src/sync/outgoing.rs":"e1577ceef9d1d87c0a0985cad16bc13938dc2144dd0befeb7aca2c97375e7ee7","src/sync/sync_tests.rs":"f999b9acfb95604e4b3b981a29527a490b64e39026ea9d9668418912cda54536","src/webext-storage.udl":"a37a5c796bcdc71b61dbb189a8801bbff9e67bf81aebb489db0e7fcafc58521d","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"3dabddc8c56828528ac713fcaf2dc2f4f275571d119615cf652e698d64ff92e9","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"f4ff15cd54890d3e3636e77a0458ba9a8882f271ccb0056a0bbae1975cdd75d5","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"f257b7ad208af1274b679d953bc3425f72b66c65037ab57e822a520892b273c2","src/db.rs":"b24a68226889cf84f0020142dddfdecf84949f47e4582c2e0c7b62d4e2883a9d","src/error.rs":"4a37ff2221551ebf53a835085b3e21f9de3f86a74711ddd5903975c7110333a1","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"e00636eb57498ab015387b08ffe64618dca31e95977e60be624aa259d7dfe4b5","src/migration.rs":"7f09887df071e15f34be5bd24116f43b786410e935e1f1d7e49471877629dd19","src/schema.rs":"0a668212a6db65cf5c59a786eaa342707583d580c1d374c81374335301f758bc","src/store.rs":"a092586b65a6ebfa36c62cb45859ba7626631a699e1a2445c8cfb54fec9bb44a","src/sync/bridge.rs":"14d095bc67e511297b833e279912f61dd67993a877be941cc058afe9017cb058","src/sync/incoming.rs":"8b7cd75463aae7bc08e87d5feb2b125ae68b512bcb712483457d2837c4b0086a","src/sync/mod.rs":"5e6ae17f5a0fe0e278ed1fe552cea4fb7993280811333c36ac40599cde4059d6","src/sync/outgoing.rs":"3a6227d0cabc672917ba52e041bee2ac4b61dc0c2bc8c7cd57458d36891ce950","src/sync/sync_tests.rs":"c5490abbaed5cffc2afa397bdd8386762c30b28b7d95a30ce0825678a72e56b3","src/webext-storage.udl":"a37a5c796bcdc71b61dbb189a8801bbff9e67bf81aebb489db0e7fcafc58521d","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null} \ No newline at end of file diff --git a/third_party/rust/webext-storage/Cargo.toml b/third_party/rust/webext-storage/Cargo.toml index bae030836c9e..a4572fbdb23a 100644 --- a/third_party/rust/webext-storage/Cargo.toml +++ b/third_party/rust/webext-storage/Cargo.toml @@ -35,7 +35,6 @@ path = "src/lib.rs" anyhow = "1.0" ffi-support = "0.4" lazy_static = "1.4" -log = "0.4" parking_lot = ">=0.11,<=0.12" serde = "1" serde_derive = "1" @@ -81,9 +80,9 @@ features = ["serde"] [dev-dependencies] tempfile = "3" -[dev-dependencies.env_logger] -version = "0.10" -default-features = false +[dev-dependencies.error-support] +path = "../support/error" +features = ["testing"] [dev-dependencies.serde_json] version = "1" diff --git a/third_party/rust/webext-storage/src/api.rs b/third_party/rust/webext-storage/src/api.rs index 4f173475483e..787b609fbc76 100644 --- a/third_party/rust/webext-storage/src/api.rs +++ b/third_party/rust/webext-storage/src/api.rs @@ -69,7 +69,7 @@ fn save_to_db(tx: &Transaction<'_>, ext_id: &str, val: &StorageChangeOp) -> Resu )? .unwrap_or_default(); if in_mirror { - log::trace!("saving data for '{}': leaving a tombstone", ext_id); + trace!("saving data for '{}': leaving a tombstone", ext_id); tx.execute_cached( " INSERT INTO storage_sync_data(ext_id, data, sync_change_counter) @@ -81,7 +81,7 @@ fn save_to_db(tx: &Transaction<'_>, ext_id: &str, val: &StorageChangeOp) -> Resu }, )?; } else { - log::trace!("saving data for '{}': removing the row", ext_id); + trace!("saving data for '{}': removing the row", ext_id); tx.execute_cached( " DELETE FROM storage_sync_data WHERE ext_id = :ext_id", @@ -104,7 +104,7 @@ fn save_to_db(tx: &Transaction<'_>, ext_id: &str, val: &StorageChangeOp) -> Resu StorageChangeOp::Clear => unreachable!(), }; - log::trace!("saving data for '{}': writing", ext_id); + trace!("saving data for '{}': writing", ext_id); tx.execute_cached( "INSERT INTO storage_sync_data(ext_id, data, sync_change_counter) VALUES (:ext_id, :data, 1) diff --git a/third_party/rust/webext-storage/src/db.rs b/third_party/rust/webext-storage/src/db.rs index d716c061d7f0..621825e57b88 100644 --- a/third_party/rust/webext-storage/src/db.rs +++ b/third_party/rust/webext-storage/src/db.rs @@ -258,7 +258,7 @@ pub mod test { static ATOMIC_COUNTER: AtomicUsize = AtomicUsize::new(0); pub fn new_mem_db() -> StorageDb { - let _ = env_logger::try_init(); + error_support::init_for_tests(); let counter = ATOMIC_COUNTER.fetch_add(1, Ordering::Relaxed); StorageDb::new_memory(&format!("test-api-{}", counter)).expect("should get an API") } diff --git a/third_party/rust/webext-storage/src/error.rs b/third_party/rust/webext-storage/src/error.rs index 7774f15dce47..124cc3dafa1a 100644 --- a/third_party/rust/webext-storage/src/error.rs +++ b/third_party/rust/webext-storage/src/error.rs @@ -3,6 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use error_support::{ErrorHandling, GetErrorHandling}; +// reexport logging helpers. +pub use error_support::{debug, error, info, trace, warn}; + use interrupt_support::Interrupted; use std::fmt; @@ -95,17 +98,17 @@ impl GetErrorHandling for Error { fn get_error_handling(&self) -> ErrorHandling { match self { Error::QuotaError(reason) => { - log::info!("webext-storage-quota-error"); + info!("webext-storage-quota-error"); ErrorHandling::convert(WebExtStorageApiError::QuotaError { reason: *reason }) } Error::JsonError(e) => { - log::info!("webext-storage-json-error"); + info!("webext-storage-json-error"); ErrorHandling::convert(WebExtStorageApiError::JsonError { reason: e.to_string(), }) } _ => { - log::info!("webext-storage-unexpected-error"); + info!("webext-storage-unexpected-error"); ErrorHandling::convert(WebExtStorageApiError::UnexpectedError { reason: self.to_string(), }) diff --git a/third_party/rust/webext-storage/src/migration.rs b/third_party/rust/webext-storage/src/migration.rs index fa2d0cc8626e..3372f6d33de8 100644 --- a/third_party/rust/webext-storage/src/migration.rs +++ b/third_party/rust/webext-storage/src/migration.rs @@ -57,24 +57,24 @@ impl LegacyRow { // our target database. fn parse(&self) -> Option> { if self.col_name.len() < 8 { - log::trace!("collection_name of '{}' is too short", self.col_name); + trace!("collection_name of '{}' is too short", self.col_name); return None; } if &self.col_name[..8] != "default/" { - log::trace!("collection_name of '{}' isn't ours", self.col_name); + trace!("collection_name of '{}' isn't ours", self.col_name); return None; } let ext_id = &self.col_name[8..]; let mut record_map = match serde_json::from_str(&self.record) { Ok(Value::Object(m)) => m, Ok(o) => { - log::info!("skipping non-json-object 'record' column"); - log::trace!("record value is json, but not an object: {}", o); + info!("skipping non-json-object 'record' column"); + trace!("record value is json, but not an object: {}", o); return None; } Err(e) => { - log::info!("skipping non-json 'record' column"); - log::trace!("record value isn't json: {}", e); + info!("skipping non-json 'record' column"); + trace!("record value isn't json: {}", e); return None; } }; @@ -82,18 +82,18 @@ impl LegacyRow { let key = match record_map.remove("key") { Some(Value::String(s)) if !s.is_empty() => s, Some(o) => { - log::trace!("key is json but not a string: {}", o); + trace!("key is json but not a string: {}", o); return None; } _ => { - log::trace!("key doesn't exist in the map"); + trace!("key doesn't exist in the map"); return None; } }; let data = match record_map.remove("data") { Some(d) => d, _ => { - log::trace!("data doesn't exist in the map"); + trace!("data doesn't exist in the map"); return None; } }; @@ -114,7 +114,7 @@ pub fn migrate(tx: &Transaction<'_>, filename: &Path) -> Result { let mut curr_values: Vec<(String, serde_json::Value)> = Vec::new(); let (rows, mut mi) = read_rows(filename); for row in rows { - log::trace!("processing '{}' - '{}'", row.col_name, row.record); + trace!("processing '{}' - '{}'", row.col_name, row.record); let parsed = match row.parse() { Some(p) => p, None => continue, @@ -133,7 +133,7 @@ pub fn migrate(tx: &Transaction<'_>, filename: &Path) -> Result { // no 'else' here - must also enter this block on ext_id change. if parsed.ext_id == last_ext_id { curr_values.push((parsed.key.to_string(), parsed.data)); - log::trace!( + trace!( "extension {} now has {} keys", parsed.ext_id, curr_values.len() @@ -147,7 +147,7 @@ pub fn migrate(tx: &Transaction<'_>, filename: &Path) -> Result { mi.extensions_successful += 1; mi.entries_successful += entries; } - log::info!("migrated {} extensions: {:?}", mi.extensions_successful, mi); + info!("migrated {} extensions: {:?}", mi.extensions_successful, mi); Ok(mi) } @@ -156,7 +156,7 @@ fn read_rows(filename: &Path) -> (Vec, MigrationInfo) { let src_conn = match Connection::open_with_flags(filename, flags) { Ok(conn) => conn, Err(e) => { - log::warn!("Failed to open the source DB: {}", e); + warn!("Failed to open the source DB: {}", e); return (Vec::new(), MigrationInfo::open_failure()); } }; @@ -169,7 +169,7 @@ fn read_rows(filename: &Path) -> (Vec, MigrationInfo) { ) { Ok(stmt) => stmt, Err(e) => { - log::warn!("Failed to prepare the statement: {}", e); + warn!("Failed to prepare the statement: {}", e); return (Vec::new(), MigrationInfo::open_failure()); } }; @@ -181,7 +181,7 @@ fn read_rows(filename: &Path) -> (Vec, MigrationInfo) { }) { Ok(r) => r, Err(e) => { - log::warn!("Failed to read any rows from the source DB: {}", e); + warn!("Failed to read any rows from the source DB: {}", e); return (Vec::new(), MigrationInfo::open_failure()); } }; diff --git a/third_party/rust/webext-storage/src/schema.rs b/third_party/rust/webext-storage/src/schema.rs index 94467050d09f..db65e8b50adf 100644 --- a/third_party/rust/webext-storage/src/schema.rs +++ b/third_party/rust/webext-storage/src/schema.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::db::sql_fns; -use crate::error::Result; +use crate::error::{debug, Result}; use rusqlite::{Connection, Transaction}; use sql_support::open_database::{ ConnectionInitializer as MigrationLogic, Error as MigrationError, Result as MigrationResult, @@ -34,7 +34,7 @@ impl MigrationLogic for WebExtMigrationLogin { } fn init(&self, db: &Transaction<'_>) -> MigrationResult<()> { - log::debug!("Creating schema"); + debug!("Creating schema"); db.execute_batch(CREATE_SCHEMA_SQL)?; Ok(()) } @@ -76,7 +76,7 @@ fn upgrade_from_1(db: &Connection) -> MigrationResult<()> { // ensure we are syncing with a clean state, after to be good memory citizens // given the temp tables are in memory. pub fn create_empty_sync_temp_tables(db: &Connection) -> Result<()> { - log::debug!("Initializing sync temp tables"); + debug!("Initializing sync temp tables"); db.execute_batch(CREATE_SYNC_TEMP_TABLES_SQL)?; Ok(()) } @@ -163,7 +163,7 @@ mod tests { #[test] fn test_upgrade_2() -> Result<()> { - let _ = env_logger::try_init(); + error_support::init_for_tests(); let db_file = MigratedDatabaseFile::new(WebExtMigrationLogin, CREATE_SCHEMA_V1_SQL); db_file.upgrade_to(2); diff --git a/third_party/rust/webext-storage/src/store.rs b/third_party/rust/webext-storage/src/store.rs index cee0522b5dfe..596b19ba6546 100644 --- a/third_party/rust/webext-storage/src/store.rs +++ b/third_party/rust/webext-storage/src/store.rs @@ -161,7 +161,7 @@ impl WebExtStorageStore { // Failing to store this information should not cause migration failure. if let Err(e) = result.store(conn) { debug_assert!(false, "Migration error: {:?}", e); - log::warn!("Failed to record migration telmetry: {}", e); + warn!("Failed to record migration telmetry: {}", e); } Ok(()) } diff --git a/third_party/rust/webext-storage/src/sync/incoming.rs b/third_party/rust/webext-storage/src/sync/incoming.rs index 6f2cea9718fb..2049fcdca500 100644 --- a/third_party/rust/webext-storage/src/sync/incoming.rs +++ b/third_party/rust/webext-storage/src/sync/incoming.rs @@ -89,7 +89,7 @@ pub fn stage_incoming( params.push(None); } IncomingKind::Malformed => { - log::error!("Ignoring incoming malformed record: {}", record.envelope.id); + error!("Ignoring incoming malformed record: {}", record.envelope.id); } } } @@ -413,7 +413,7 @@ pub fn apply_actions( for (item, action) in actions { signal.err_if_interrupted()?; - log::trace!("action for '{:?}': {:?}", item, action); + trace!("action for '{:?}': {:?}", item, action); match action { IncomingAction::DeleteLocally { ext_id, changes } => { // Can just nuke it entirely. diff --git a/third_party/rust/webext-storage/src/sync/mod.rs b/third_party/rust/webext-storage/src/sync/mod.rs index 8dd75d761bda..b1d8944ada3f 100644 --- a/third_party/rust/webext-storage/src/sync/mod.rs +++ b/third_party/rust/webext-storage/src/sync/mod.rs @@ -53,7 +53,7 @@ fn merge( for (key, parent_value) in parent.into_iter() { if let Some(incoming_value) = other.remove(&key) { if incoming_value != parent_value { - log::trace!( + trace!( "merge: key {} was updated in incoming - copying value locally", key ); @@ -71,7 +71,7 @@ fn merge( } else { // Key was not present in incoming value. // Another client must have deleted it. - log::trace!( + trace!( "merge: key {} no longer present in incoming - removing it locally", key ); @@ -89,7 +89,7 @@ fn merge( // the ones where a corresponding key does not exist in // parent, so it is a new key, and we need to add it. for (key, incoming_value) in other.into_iter() { - log::trace!( + trace!( "merge: key {} doesn't occur in parent - copying from incoming", key ); @@ -103,7 +103,7 @@ fn merge( } else { // No parent. Server wins. Overwrite every key in ours with // the corresponding value in other. - log::trace!("merge: no parent - copying all keys from incoming"); + trace!("merge: no parent - copying all keys from incoming"); for (key, incoming_value) in other.into_iter() { let old_value = ours.remove(&key); let new_value = Some(incoming_value.clone()); @@ -179,7 +179,7 @@ pub mod test { use crate::schema::create_empty_sync_temp_tables; pub fn new_syncable_mem_db() -> StorageDb { - let _ = env_logger::try_init(); + error_support::init_for_tests(); let db = new_mem_db(); let conn = db.get_connection().expect("should retrieve connection"); create_empty_sync_temp_tables(conn).expect("should work"); diff --git a/third_party/rust/webext-storage/src/sync/outgoing.rs b/third_party/rust/webext-storage/src/sync/outgoing.rs index b14bb097646f..674a1ebb259e 100644 --- a/third_party/rust/webext-storage/src/sync/outgoing.rs +++ b/third_party/rust/webext-storage/src/sync/outgoing.rs @@ -79,7 +79,7 @@ pub fn get_outgoing(conn: &Connection, signal: &dyn Interruptee) -> Result Result<()> { - log::debug!( + debug!( "record_uploaded recording that {} items were uploaded", items.len() ); diff --git a/third_party/rust/webext-storage/src/sync/sync_tests.rs b/third_party/rust/webext-storage/src/sync/sync_tests.rs index fb5ad5f911c8..5d9f9d156c27 100644 --- a/third_party/rust/webext-storage/src/sync/sync_tests.rs +++ b/third_party/rust/webext-storage/src/sync/sync_tests.rs @@ -26,7 +26,7 @@ fn do_sync( tx: &Transaction<'_>, incoming_payloads: &[IncomingContent], ) -> Result> { - log::info!("test do_sync() starting"); + info!("test do_sync() starting"); // First we stage the incoming in the temp tables. stage_incoming(tx, incoming_payloads, &NeverInterrupts)?; // Then we process them getting a Vec of (item, state), which we turn into @@ -35,12 +35,12 @@ fn do_sync( .into_iter() .map(|(item, state)| (item, plan_incoming(state))) .collect(); - log::debug!("do_sync applying {:?}", actions); + debug!("do_sync applying {:?}", actions); apply_actions(tx, actions, &NeverInterrupts)?; // So we've done incoming - do outgoing. stage_outgoing(tx)?; let outgoing = get_outgoing(tx, &NeverInterrupts)?; - log::debug!("do_sync has outgoing {:?}", outgoing); + debug!("do_sync has outgoing {:?}", outgoing); record_uploaded( tx, outgoing @@ -51,7 +51,7 @@ fn do_sync( &NeverInterrupts, )?; create_empty_sync_temp_tables(tx)?; - log::info!("test do_sync() complete"); + info!("test do_sync() complete"); Ok(outgoing) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs index 0c839c519b1b..9e6945134c33 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs @@ -308,6 +308,34 @@ const uniffiObjectPtr = Symbol("uniffiObjectPtr"); const constructUniffiObject = Symbol("constructUniffiObject"); UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr; +// Export the FFIConverter object to make external types work. +export class FfiConverterU8 extends FfiConverter { + static checkType(value) { + super.checkType(value); + if (!Number.isInteger(value)) { + throw new UniFFITypeError(`${value} is not an integer`); + } + if (value < 0 || value > 256) { + throw new UniFFITypeError(`${value} exceeds the U8 bounds`); + } + } + static computeSize(_value) { + return 1; + } + static lift(value) { + return value; + } + static lower(value) { + return value; + } + static write(dataStream, value) { + dataStream.writeUint8(value) + } + static read(dataStream) { + return dataStream.readUint8() + } +} + // Export the FFIConverter object to make external types work. export class FfiConverterI32 extends FfiConverter { static checkType(value) { @@ -551,7 +579,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callSync( - 53, // suggest:uniffi_suggest_fn_constructor_suggeststore_new + 54, // suggest:uniffi_suggest_fn_constructor_suggeststore_new FfiConverterString.lower(path), FfiConverterTypeRemoteSettingsService.lower(remoteSettingsService), ) @@ -713,33 +741,45 @@ export class SuggestStore { } } + /** + * Fetches a geoname's names stored in the database. + * + * See `fetch_geoname_alternates` in `geoname.rs` for documentation. + * @returns {GeonameAlternates} + */ + fetchGeonameAlternates(geoname) { + const liftResult = (result) => FfiConverterTypeGeonameAlternates.lift(result); + const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data); + const functionCall = () => { + try { + FfiConverterTypeGeoname.checkType(geoname) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("geoname"); + } + throw e; + } + return UniFFIScaffolding.callAsyncWrapper( + 44, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates + FfiConverterTypeSuggestStore.lower(this), + FfiConverterTypeGeoname.lower(geoname), + ) + } + try { + return functionCall().then((result) => handleRustResult(result, liftResult, liftError)); + } catch (error) { + return Promise.reject(error) + } + } + /** * Fetches geonames stored in the database. A geoname represents a * geographic place. * - * `query` is a string that will be matched directly against geoname names. - * It is not a query string in the usual Suggest sense. `match_name_prefix` - * determines whether prefix matching is performed on names excluding - * abbreviations and airport codes. When `true`, names that start with - * `query` will match. When false, names that equal `query` will match. - * - * `geoname_type` restricts returned geonames to a [`GeonameType`]. - * - * `filter` restricts returned geonames to certain cities or regions. - * Cities can be restricted to regions by including the regions in - * `filter`, and regions can be restricted to those containing certain - * cities by including the cities in `filter`. This is especially useful - * since city and region names are not unique. `filter` is disjunctive: If - * any item in `filter` matches a geoname, the geoname will be filtered in. - * - * The query can match a single geoname in more than one way. For example, - * it can match both a full name and an abbreviation. The returned vec of - * [`GeonameMatch`] values will include all matches for a geoname, one - * match per `match_type` per geoname. In other words, a matched geoname - * can map to more than one `GeonameMatch`. + * See `fetch_geonames` in `geoname.rs` for documentation. * @returns {Array.} */ - fetchGeonames(query,matchNamePrefix,geonameType,filter) { + fetchGeonames(query,matchNamePrefix,filter) { const liftResult = (result) => FfiConverterSequenceTypeGeonameMatch.lift(result); const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data); const functionCall = () => { @@ -759,14 +799,6 @@ export class SuggestStore { } throw e; } - try { - FfiConverterOptionalTypeGeonameType.checkType(geonameType) - } catch (e) { - if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart("geonameType"); - } - throw e; - } try { FfiConverterOptionalSequenceTypeGeoname.checkType(filter) } catch (e) { @@ -776,11 +808,10 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 44, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_geonames + 45, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_geonames FfiConverterTypeSuggestStore.lower(this), FfiConverterString.lower(query), FfiConverterBool.lower(matchNamePrefix), - FfiConverterOptionalTypeGeonameType.lower(geonameType), FfiConverterOptionalSequenceTypeGeoname.lower(filter), ) } @@ -800,7 +831,7 @@ export class SuggestStore { const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 45, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_global_config + 46, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_global_config FfiConverterTypeSuggestStore.lower(this), ) } @@ -828,7 +859,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 46, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_provider_config + 47, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_provider_config FfiConverterTypeSuggestStore.lower(this), FfiConverterTypeSuggestionProvider.lower(provider), ) @@ -857,7 +888,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 47, // suggest:uniffi_suggest_fn_method_suggeststore_ingest + 48, // suggest:uniffi_suggest_fn_method_suggeststore_ingest FfiConverterTypeSuggestStore.lower(this), FfiConverterTypeSuggestIngestionConstraints.lower(constraints), ) @@ -889,7 +920,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callSync( - 48, // suggest:uniffi_suggest_fn_method_suggeststore_interrupt + 49, // suggest:uniffi_suggest_fn_method_suggeststore_interrupt FfiConverterTypeSuggestStore.lower(this), FfiConverterOptionalTypeInterruptKind.lower(kind), ) @@ -919,7 +950,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 49, // suggest:uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key + 50, // suggest:uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key FfiConverterTypeSuggestStore.lower(this), FfiConverterString.lower(key), ) @@ -952,7 +983,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 50, // suggest:uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion + 51, // suggest:uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion FfiConverterTypeSuggestStore.lower(this), FfiConverterTypeSuggestion.lower(suggestion), ) @@ -981,7 +1012,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 51, // suggest:uniffi_suggest_fn_method_suggeststore_query + 52, // suggest:uniffi_suggest_fn_method_suggeststore_query FfiConverterTypeSuggestStore.lower(this), FfiConverterTypeSuggestionQuery.lower(query), ) @@ -1010,7 +1041,7 @@ export class SuggestStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 52, // suggest:uniffi_suggest_fn_method_suggeststore_query_with_metrics + 53, // suggest:uniffi_suggest_fn_method_suggeststore_query_with_metrics FfiConverterTypeSuggestStore.lower(this), FfiConverterTypeSuggestionQuery.lower(query), ) @@ -1081,7 +1112,7 @@ export class SuggestStoreBuilder { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 61, // suggest:uniffi_suggest_fn_constructor_suggeststorebuilder_new + 62, // suggest:uniffi_suggest_fn_constructor_suggeststorebuilder_new ) } return handleRustResult(functionCall(), liftResult, liftError);} @@ -1095,7 +1126,7 @@ export class SuggestStoreBuilder { const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callSync( - 54, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_build + 55, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_build FfiConverterTypeSuggestStoreBuilder.lower(this), ) } @@ -1119,7 +1150,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 55, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_cache_path + 56, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_cache_path FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterString.lower(path), ) @@ -1148,7 +1179,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callSync( - 56, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_data_path + 57, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_data_path FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterString.lower(path), ) @@ -1185,7 +1216,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callSync( - 57, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_load_extension + 58, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_load_extension FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterString.lower(library), FfiConverterOptionalstring.lower(entryPoint), @@ -1211,7 +1242,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callSync( - 58, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name + 59, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterString.lower(bucketName), ) @@ -1236,7 +1267,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callSync( - 59, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server + 60, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterTypeRemoteSettingsServer.lower(server), ) @@ -1261,7 +1292,7 @@ export class SuggestStoreBuilder { throw e; } return UniFFIScaffolding.callSync( - 60, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service + 61, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service FfiConverterTypeSuggestStoreBuilder.lower(this), FfiConverterTypeRemoteSettingsService.lower(rsService), ) @@ -1300,6 +1331,118 @@ export class FfiConverterTypeSuggestStoreBuilder extends FfiConverter { } } +/** + * A set of names for a single entity. + */ +export class AlternateNames { + constructor({ primary, localized, abbreviation } = { primary: undefined, localized: undefined, abbreviation: undefined }) { + try { + FfiConverterString.checkType(primary) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("primary"); + } + throw e; + } + try { + FfiConverterOptionalstring.checkType(localized) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("localized"); + } + throw e; + } + try { + FfiConverterOptionalstring.checkType(abbreviation) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("abbreviation"); + } + throw e; + } + /** + * The entity's primary name. For a `Geoname`, this is `Geoname::name`. + * @type {string} + */ + this.primary = primary; + /** + * The entity's name in the language that was ingested according to the + * locale in the remote settings context. If none exists and this + * `AlternateNames` is for a `Geoname`, then this will be its primary name. + * @type {?string} + */ + this.localized = localized; + /** + * The entity's abbreviation, if any. + * @type {?string} + */ + this.abbreviation = abbreviation; + } + + equals(other) { + return ( + this.primary == other.primary && + this.localized == other.localized && + this.abbreviation == other.abbreviation + ) + } +} + +// Export the FFIConverter object to make external types work. +export class FfiConverterTypeAlternateNames extends FfiConverterArrayBuffer { + static read(dataStream) { + return new AlternateNames({ + primary: FfiConverterString.read(dataStream), + localized: FfiConverterOptionalstring.read(dataStream), + abbreviation: FfiConverterOptionalstring.read(dataStream), + }); + } + static write(dataStream, value) { + FfiConverterString.write(dataStream, value.primary); + FfiConverterOptionalstring.write(dataStream, value.localized); + FfiConverterOptionalstring.write(dataStream, value.abbreviation); + } + + static computeSize(value) { + let totalSize = 0; + totalSize += FfiConverterString.computeSize(value.primary); + totalSize += FfiConverterOptionalstring.computeSize(value.localized); + totalSize += FfiConverterOptionalstring.computeSize(value.abbreviation); + return totalSize + } + + static checkType(value) { + super.checkType(value); + if (!(value instanceof AlternateNames)) { + throw new UniFFITypeError(`Expected 'AlternateNames', found '${typeof value}'`); + } + try { + FfiConverterString.checkType(value.primary); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".primary"); + } + throw e; + } + try { + FfiConverterOptionalstring.checkType(value.localized); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".localized"); + } + throw e; + } + try { + FfiConverterOptionalstring.checkType(value.abbreviation); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".abbreviation"); + } + throw e; + } + } +} + /** * Additional data about how an FTS match was made */ @@ -1394,7 +1537,7 @@ export class FfiConverterTypeFtsMatchInfo extends FfiConverterArrayBuffer { * [1]: https://download.geonames.org/export/dump/readme.txt */ export class Geoname { - constructor({ geonameId, name, latitude, longitude, countryCode, admin1Code, population } = { geonameId: undefined, name: undefined, latitude: undefined, longitude: undefined, countryCode: undefined, admin1Code: undefined, population: undefined }) { + constructor({ geonameId, geonameType, name, countryCode, featureClass, featureCode, adminDivisionCodes, population, latitude, longitude } = { geonameId: undefined, geonameType: undefined, name: undefined, countryCode: undefined, featureClass: undefined, featureCode: undefined, adminDivisionCodes: undefined, population: undefined, latitude: undefined, longitude: undefined }) { try { FfiConverterI64.checkType(geonameId) } catch (e) { @@ -1403,6 +1546,14 @@ export class Geoname { } throw e; } + try { + FfiConverterTypeGeonameType.checkType(geonameType) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("geonameType"); + } + throw e; + } try { FfiConverterString.checkType(name) } catch (e) { @@ -1411,22 +1562,6 @@ export class Geoname { } throw e; } - try { - FfiConverterF64.checkType(latitude) - } catch (e) { - if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart("latitude"); - } - throw e; - } - try { - FfiConverterF64.checkType(longitude) - } catch (e) { - if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart("longitude"); - } - throw e; - } try { FfiConverterString.checkType(countryCode) } catch (e) { @@ -1436,10 +1571,26 @@ export class Geoname { throw e; } try { - FfiConverterString.checkType(admin1Code) + FfiConverterString.checkType(featureClass) } catch (e) { if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart("admin1Code"); + e.addItemDescriptionPart("featureClass"); + } + throw e; + } + try { + FfiConverterString.checkType(featureCode) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("featureCode"); + } + throw e; + } + try { + FfiConverterMapU8String.checkType(adminDivisionCodes) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("adminDivisionCodes"); } throw e; } @@ -1451,58 +1602,97 @@ export class Geoname { } throw e; } + try { + FfiConverterString.checkType(latitude) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("latitude"); + } + throw e; + } + try { + FfiConverterString.checkType(longitude) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("longitude"); + } + throw e; + } /** * The `geonameid` straight from the geoname table. * @type {number} */ this.geonameId = geonameId; /** - * This is pretty much the place's canonical name. Usually there will be a - * row in the alternates table with the same name, but not always. When - * there is such a row, it doesn't always have `is_preferred_name` set, and - * in fact fact there may be another row with a different name with - * `is_preferred_name` set. + * The geoname type. This is derived from `feature_class` and + * `feature_code` as a more convenient representation of the type. + * @type {GeonameType} + */ + this.geonameType = geonameType; + /** + * The place's primary name. * @type {string} */ this.name = name; - /** - * Latitude in decimal degrees. - * @type {number} - */ - this.latitude = latitude; - /** - * Longitude in decimal degrees. - * @type {number} - */ - this.longitude = longitude; /** * ISO-3166 two-letter uppercase country code, e.g., "US". * @type {string} */ this.countryCode = countryCode; /** - * The top-level administrative region for the place within its country, - * like a state or province. For the U.S., the two-letter uppercase state - * abbreviation. + * Primary geoname category. Examples: + * + * "PCLI" - Independent political entity: country + * "A" - Administrative division: state, province, borough, district, etc. + * "P" - Populated place: city, village, etc. * @type {string} */ - this.admin1Code = admin1Code; + this.featureClass = featureClass; + /** + * Secondary geoname category, depends on `feature_class`. Examples: + * + * "ADM1" - Administrative division 1 + * "PPL" - Populated place like a city + * @type {string} + */ + this.featureCode = featureCode; + /** + * Administrative divisions. This maps admin division levels (1-based) to + * their corresponding codes. For example, Liverpool has two admin + * divisions: "ENG" at level 1 and "H8" at level 2. They would be + * represented in this map with entries `(1, "ENG")` and `(2, "H8")`. + * @type {object} + */ + this.adminDivisionCodes = adminDivisionCodes; /** * Population size. * @type {number} */ this.population = population; + /** + * Latitude in decimal degrees (as a string). + * @type {string} + */ + this.latitude = latitude; + /** + * Longitude in decimal degrees (as a string). + * @type {string} + */ + this.longitude = longitude; } equals(other) { return ( this.geonameId == other.geonameId && + this.geonameType == other.geonameType && this.name == other.name && - this.latitude == other.latitude && - this.longitude == other.longitude && this.countryCode == other.countryCode && - this.admin1Code == other.admin1Code && - this.population == other.population + this.featureClass == other.featureClass && + this.featureCode == other.featureCode && + this.adminDivisionCodes == other.adminDivisionCodes && + this.population == other.population && + this.latitude == other.latitude && + this.longitude == other.longitude ) } } @@ -1512,33 +1702,42 @@ export class FfiConverterTypeGeoname extends FfiConverterArrayBuffer { static read(dataStream) { return new Geoname({ geonameId: FfiConverterI64.read(dataStream), + geonameType: FfiConverterTypeGeonameType.read(dataStream), name: FfiConverterString.read(dataStream), - latitude: FfiConverterF64.read(dataStream), - longitude: FfiConverterF64.read(dataStream), countryCode: FfiConverterString.read(dataStream), - admin1Code: FfiConverterString.read(dataStream), + featureClass: FfiConverterString.read(dataStream), + featureCode: FfiConverterString.read(dataStream), + adminDivisionCodes: FfiConverterMapU8String.read(dataStream), population: FfiConverterU64.read(dataStream), + latitude: FfiConverterString.read(dataStream), + longitude: FfiConverterString.read(dataStream), }); } static write(dataStream, value) { FfiConverterI64.write(dataStream, value.geonameId); + FfiConverterTypeGeonameType.write(dataStream, value.geonameType); FfiConverterString.write(dataStream, value.name); - FfiConverterF64.write(dataStream, value.latitude); - FfiConverterF64.write(dataStream, value.longitude); FfiConverterString.write(dataStream, value.countryCode); - FfiConverterString.write(dataStream, value.admin1Code); + FfiConverterString.write(dataStream, value.featureClass); + FfiConverterString.write(dataStream, value.featureCode); + FfiConverterMapU8String.write(dataStream, value.adminDivisionCodes); FfiConverterU64.write(dataStream, value.population); + FfiConverterString.write(dataStream, value.latitude); + FfiConverterString.write(dataStream, value.longitude); } static computeSize(value) { let totalSize = 0; totalSize += FfiConverterI64.computeSize(value.geonameId); + totalSize += FfiConverterTypeGeonameType.computeSize(value.geonameType); totalSize += FfiConverterString.computeSize(value.name); - totalSize += FfiConverterF64.computeSize(value.latitude); - totalSize += FfiConverterF64.computeSize(value.longitude); totalSize += FfiConverterString.computeSize(value.countryCode); - totalSize += FfiConverterString.computeSize(value.admin1Code); + totalSize += FfiConverterString.computeSize(value.featureClass); + totalSize += FfiConverterString.computeSize(value.featureCode); + totalSize += FfiConverterMapU8String.computeSize(value.adminDivisionCodes); totalSize += FfiConverterU64.computeSize(value.population); + totalSize += FfiConverterString.computeSize(value.latitude); + totalSize += FfiConverterString.computeSize(value.longitude); return totalSize } @@ -1555,6 +1754,14 @@ export class FfiConverterTypeGeoname extends FfiConverterArrayBuffer { } throw e; } + try { + FfiConverterTypeGeonameType.checkType(value.geonameType); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".geonameType"); + } + throw e; + } try { FfiConverterString.checkType(value.name); } catch (e) { @@ -1563,22 +1770,6 @@ export class FfiConverterTypeGeoname extends FfiConverterArrayBuffer { } throw e; } - try { - FfiConverterF64.checkType(value.latitude); - } catch (e) { - if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart(".latitude"); - } - throw e; - } - try { - FfiConverterF64.checkType(value.longitude); - } catch (e) { - if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart(".longitude"); - } - throw e; - } try { FfiConverterString.checkType(value.countryCode); } catch (e) { @@ -1588,10 +1779,26 @@ export class FfiConverterTypeGeoname extends FfiConverterArrayBuffer { throw e; } try { - FfiConverterString.checkType(value.admin1Code); + FfiConverterString.checkType(value.featureClass); } catch (e) { if (e instanceof UniFFITypeError) { - e.addItemDescriptionPart(".admin1Code"); + e.addItemDescriptionPart(".featureClass"); + } + throw e; + } + try { + FfiConverterString.checkType(value.featureCode); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".featureCode"); + } + throw e; + } + try { + FfiConverterMapU8String.checkType(value.adminDivisionCodes); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".adminDivisionCodes"); } throw e; } @@ -1603,6 +1810,135 @@ export class FfiConverterTypeGeoname extends FfiConverterArrayBuffer { } throw e; } + try { + FfiConverterString.checkType(value.latitude); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".latitude"); + } + throw e; + } + try { + FfiConverterString.checkType(value.longitude); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".longitude"); + } + throw e; + } + } +} + +/** + * Alternate names for a geoname and its country and admin divisions. + */ +export class GeonameAlternates { + constructor({ geoname, country, adminDivisions } = { geoname: undefined, country: undefined, adminDivisions: undefined }) { + try { + FfiConverterTypeAlternateNames.checkType(geoname) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("geoname"); + } + throw e; + } + try { + FfiConverterOptionalTypeAlternateNames.checkType(country) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("country"); + } + throw e; + } + try { + FfiConverterMapU8TypeAlternateNames.checkType(adminDivisions) + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("adminDivisions"); + } + throw e; + } + /** + * Names for the geoname itself. + * @type {AlternateNames} + */ + this.geoname = geoname; + /** + * Names for the geoname's country. This will be `Some` as long as the + * country is also in the ingested data, which should typically be true. + * @type {?AlternateNames} + */ + this.country = country; + /** + * Names for the geoname's admin divisions. This is parallel to + * `Geoname::admin_division_codes`. If there are no names in the ingested + * data for an admin division, then it will be absent from this map. + * @type {object} + */ + this.adminDivisions = adminDivisions; + } + + equals(other) { + return ( + this.geoname.equals(other.geoname) && + this.country == other.country && + this.adminDivisions == other.adminDivisions + ) + } +} + +// Export the FFIConverter object to make external types work. +export class FfiConverterTypeGeonameAlternates extends FfiConverterArrayBuffer { + static read(dataStream) { + return new GeonameAlternates({ + geoname: FfiConverterTypeAlternateNames.read(dataStream), + country: FfiConverterOptionalTypeAlternateNames.read(dataStream), + adminDivisions: FfiConverterMapU8TypeAlternateNames.read(dataStream), + }); + } + static write(dataStream, value) { + FfiConverterTypeAlternateNames.write(dataStream, value.geoname); + FfiConverterOptionalTypeAlternateNames.write(dataStream, value.country); + FfiConverterMapU8TypeAlternateNames.write(dataStream, value.adminDivisions); + } + + static computeSize(value) { + let totalSize = 0; + totalSize += FfiConverterTypeAlternateNames.computeSize(value.geoname); + totalSize += FfiConverterOptionalTypeAlternateNames.computeSize(value.country); + totalSize += FfiConverterMapU8TypeAlternateNames.computeSize(value.adminDivisions); + return totalSize + } + + static checkType(value) { + super.checkType(value); + if (!(value instanceof GeonameAlternates)) { + throw new UniFFITypeError(`Expected 'GeonameAlternates', found '${typeof value}'`); + } + try { + FfiConverterTypeAlternateNames.checkType(value.geoname); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".geoname"); + } + throw e; + } + try { + FfiConverterOptionalTypeAlternateNames.checkType(value.country); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".country"); + } + throw e; + } + try { + FfiConverterMapU8TypeAlternateNames.checkType(value.adminDivisions); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(".adminDivisions"); + } + throw e; + } } } @@ -2433,7 +2769,7 @@ export class FfiConverterTypeAmpMatchingStrategy extends FfiConverterArrayBuffer */ export const GeonameMatchType = { /** - * For U.S. states, abbreviations are the usual two-letter codes ("CA"). + * ABBREVIATION */ ABBREVIATION:0, /** @@ -2498,54 +2834,131 @@ export class FfiConverterTypeGeonameMatchType extends FfiConverterArrayBuffer { /** * The type of a geoname. */ -export const GeonameType = { - /** - * CITY - */ - CITY:0, - /** - * REGION - */ - REGION:1, -}; +export class GeonameType {} +/** + * Country + */ +GeonameType.Country = class extends GeonameType{ + constructor( + ) { + super(); + } +} +/** + * A state, province, prefecture, district, borough, etc. + */ +GeonameType.AdminDivision = class extends GeonameType{ + constructor( + level + ) { + super(); + this.level = level; + } +} +/** + * AdminDivisionOther + */ +GeonameType.AdminDivisionOther = class extends GeonameType{ + constructor( + ) { + super(); + } +} +/** + * A city, town, village, populated place, etc. + */ +GeonameType.City = class extends GeonameType{ + constructor( + ) { + super(); + } +} +/** + * Other + */ +GeonameType.Other = class extends GeonameType{ + constructor( + ) { + super(); + } +} -Object.freeze(GeonameType); // Export the FFIConverter object to make external types work. export class FfiConverterTypeGeonameType extends FfiConverterArrayBuffer { - static #validValues = Object.values(GeonameType); - static read(dataStream) { // Use sequential indices (1-based) for the wire format to match Python bindings switch (dataStream.readInt32()) { case 1: - return GeonameType.CITY + return new GeonameType.Country( + ); case 2: - return GeonameType.REGION + return new GeonameType.AdminDivision( + FfiConverterU8.read(dataStream) + ); + case 3: + return new GeonameType.AdminDivisionOther( + ); + case 4: + return new GeonameType.City( + ); + case 5: + return new GeonameType.Other( + ); default: throw new UniFFITypeError("Unknown GeonameType variant"); } } static write(dataStream, value) { - if (value === GeonameType.CITY) { + if (value instanceof GeonameType.Country) { dataStream.writeInt32(1); return; } - if (value === GeonameType.REGION) { + if (value instanceof GeonameType.AdminDivision) { dataStream.writeInt32(2); + FfiConverterU8.write(dataStream, value.level); + return; + } + if (value instanceof GeonameType.AdminDivisionOther) { + dataStream.writeInt32(3); + return; + } + if (value instanceof GeonameType.City) { + dataStream.writeInt32(4); + return; + } + if (value instanceof GeonameType.Other) { + dataStream.writeInt32(5); return; } throw new UniFFITypeError("Unknown GeonameType variant"); } static computeSize(value) { - return 4; + // Size of the Int indicating the variant + let totalSize = 4; + if (value instanceof GeonameType.Country) { + return totalSize; + } + if (value instanceof GeonameType.AdminDivision) { + totalSize += FfiConverterU8.computeSize(value.level); + return totalSize; + } + if (value instanceof GeonameType.AdminDivisionOther) { + return totalSize; + } + if (value instanceof GeonameType.City) { + return totalSize; + } + if (value instanceof GeonameType.Other) { + return totalSize; + } + throw new UniFFITypeError("Unknown GeonameType variant"); } static checkType(value) { - // Check that the value is a valid enum variant - if (!this.#validValues.includes(value)) { - throw new UniFFITypeError(`${value} is not a valid value for GeonameType`); + if (value === undefined || value === null || !(value instanceof GeonameType)) { + throw new UniFFITypeError(`${value} is not a subclass instance of GeonameType`); } } } @@ -2983,18 +3396,10 @@ Suggestion.Mdn = class extends Suggestion{ Suggestion.Weather = class extends Suggestion{ constructor( city, - region, - country, - latitude, - longitude, score ) { super(); this.city = city; - this.region = region; - this.country = country; - this.latitude = latitude; - this.longitude = longitude; this.score = score; } } @@ -3114,11 +3519,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { ); case 7: return new Suggestion.Weather( - FfiConverterOptionalstring.read(dataStream), - FfiConverterOptionalstring.read(dataStream), - FfiConverterOptionalstring.read(dataStream), - FfiConverterOptionalf64.read(dataStream), - FfiConverterOptionalf64.read(dataStream), + FfiConverterOptionalTypeGeoname.read(dataStream), FfiConverterF64.read(dataStream) ); case 8: @@ -3217,11 +3618,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { } if (value instanceof Suggestion.Weather) { dataStream.writeInt32(7); - FfiConverterOptionalstring.write(dataStream, value.city); - FfiConverterOptionalstring.write(dataStream, value.region); - FfiConverterOptionalstring.write(dataStream, value.country); - FfiConverterOptionalf64.write(dataStream, value.latitude); - FfiConverterOptionalf64.write(dataStream, value.longitude); + FfiConverterOptionalTypeGeoname.write(dataStream, value.city); FfiConverterF64.write(dataStream, value.score); return; } @@ -3316,11 +3713,7 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer { return totalSize; } if (value instanceof Suggestion.Weather) { - totalSize += FfiConverterOptionalstring.computeSize(value.city); - totalSize += FfiConverterOptionalstring.computeSize(value.region); - totalSize += FfiConverterOptionalstring.computeSize(value.country); - totalSize += FfiConverterOptionalf64.computeSize(value.latitude); - totalSize += FfiConverterOptionalf64.computeSize(value.longitude); + totalSize += FfiConverterOptionalTypeGeoname.computeSize(value.city); totalSize += FfiConverterF64.computeSize(value.score); return totalSize; } @@ -3576,43 +3969,6 @@ export class FfiConverterOptionali32 extends FfiConverterArrayBuffer { } } -// Export the FFIConverter object to make external types work. -export class FfiConverterOptionalf64 extends FfiConverterArrayBuffer { - static checkType(value) { - if (value !== undefined && value !== null) { - FfiConverterF64.checkType(value) - } - } - - static read(dataStream) { - const code = dataStream.readUint8(0); - switch (code) { - case 0: - return null - case 1: - return FfiConverterF64.read(dataStream) - default: - throw new UniFFIError(`Unexpected code: ${code}`); - } - } - - static write(dataStream, value) { - if (value === null || value === undefined) { - dataStream.writeUint8(0); - return; - } - dataStream.writeUint8(1); - FfiConverterF64.write(dataStream, value) - } - - static computeSize(value) { - if (value === null || value === undefined) { - return 1; - } - return 1 + FfiConverterF64.computeSize(value) - } -} - // Export the FFIConverter object to make external types work. export class FfiConverterOptionalstring extends FfiConverterArrayBuffer { static checkType(value) { @@ -3687,6 +4043,43 @@ export class FfiConverterOptionalbytes extends FfiConverterArrayBuffer { } } +// Export the FFIConverter object to make external types work. +export class FfiConverterOptionalTypeAlternateNames extends FfiConverterArrayBuffer { + static checkType(value) { + if (value !== undefined && value !== null) { + FfiConverterTypeAlternateNames.checkType(value) + } + } + + static read(dataStream) { + const code = dataStream.readUint8(0); + switch (code) { + case 0: + return null + case 1: + return FfiConverterTypeAlternateNames.read(dataStream) + default: + throw new UniFFIError(`Unexpected code: ${code}`); + } + } + + static write(dataStream, value) { + if (value === null || value === undefined) { + dataStream.writeUint8(0); + return; + } + dataStream.writeUint8(1); + FfiConverterTypeAlternateNames.write(dataStream, value) + } + + static computeSize(value) { + if (value === null || value === undefined) { + return 1; + } + return 1 + FfiConverterTypeAlternateNames.computeSize(value) + } +} + // Export the FFIConverter object to make external types work. export class FfiConverterOptionalTypeFtsMatchInfo extends FfiConverterArrayBuffer { static checkType(value) { @@ -3724,6 +4117,43 @@ export class FfiConverterOptionalTypeFtsMatchInfo extends FfiConverterArrayBuffe } } +// Export the FFIConverter object to make external types work. +export class FfiConverterOptionalTypeGeoname extends FfiConverterArrayBuffer { + static checkType(value) { + if (value !== undefined && value !== null) { + FfiConverterTypeGeoname.checkType(value) + } + } + + static read(dataStream) { + const code = dataStream.readUint8(0); + switch (code) { + case 0: + return null + case 1: + return FfiConverterTypeGeoname.read(dataStream) + default: + throw new UniFFIError(`Unexpected code: ${code}`); + } + } + + static write(dataStream, value) { + if (value === null || value === undefined) { + dataStream.writeUint8(0); + return; + } + dataStream.writeUint8(1); + FfiConverterTypeGeoname.write(dataStream, value) + } + + static computeSize(value) { + if (value === null || value === undefined) { + return 1; + } + return 1 + FfiConverterTypeGeoname.computeSize(value) + } +} + // Export the FFIConverter object to make external types work. export class FfiConverterOptionalTypeSuggestionProviderConstraints extends FfiConverterArrayBuffer { static checkType(value) { @@ -3798,43 +4228,6 @@ export class FfiConverterOptionalTypeAmpMatchingStrategy extends FfiConverterArr } } -// Export the FFIConverter object to make external types work. -export class FfiConverterOptionalTypeGeonameType extends FfiConverterArrayBuffer { - static checkType(value) { - if (value !== undefined && value !== null) { - FfiConverterTypeGeonameType.checkType(value) - } - } - - static read(dataStream) { - const code = dataStream.readUint8(0); - switch (code) { - case 0: - return null - case 1: - return FfiConverterTypeGeonameType.read(dataStream) - default: - throw new UniFFIError(`Unexpected code: ${code}`); - } - } - - static write(dataStream, value) { - if (value === null || value === undefined) { - dataStream.writeUint8(0); - return; - } - dataStream.writeUint8(1); - FfiConverterTypeGeonameType.write(dataStream, value) - } - - static computeSize(value) { - if (value === null || value === undefined) { - return 1; - } - return 1 + FfiConverterTypeGeonameType.computeSize(value) - } -} - // Export the FFIConverter object to make external types work. export class FfiConverterOptionalTypeInterruptKind extends FfiConverterArrayBuffer { static checkType(value) { @@ -4321,6 +4714,116 @@ export class FfiConverterSequenceTypeSuggestionProvider extends FfiConverterArra } } +// Export the FFIConverter object to make external types work. +export class FfiConverterMapU8String extends FfiConverterArrayBuffer { + static read(dataStream) { + const len = dataStream.readInt32(); + const map = new Map(); + for (let i = 0; i < len; i++) { + const key = FfiConverterU8.read(dataStream); + const value = FfiConverterString.read(dataStream); + map.set(key, value); + } + + return map; + } + + static write(dataStream, map) { + dataStream.writeInt32(map.size); + for (const [key, value] of map) { + FfiConverterU8.write(dataStream, key); + FfiConverterString.write(dataStream, value); + } + } + + static computeSize(map) { + // The size of the length + let size = 4; + for (const [key, value] of map) { + size += FfiConverterU8.computeSize(key); + size += FfiConverterString.computeSize(value); + } + return size; + } + + static checkType(map) { + for (const [key, value] of map) { + try { + FfiConverterU8.checkType(key); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("(key)"); + } + throw e; + } + + try { + FfiConverterString.checkType(value); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(`[${key}]`); + } + throw e; + } + } + } +} + +// Export the FFIConverter object to make external types work. +export class FfiConverterMapU8TypeAlternateNames extends FfiConverterArrayBuffer { + static read(dataStream) { + const len = dataStream.readInt32(); + const map = new Map(); + for (let i = 0; i < len; i++) { + const key = FfiConverterU8.read(dataStream); + const value = FfiConverterTypeAlternateNames.read(dataStream); + map.set(key, value); + } + + return map; + } + + static write(dataStream, map) { + dataStream.writeInt32(map.size); + for (const [key, value] of map) { + FfiConverterU8.write(dataStream, key); + FfiConverterTypeAlternateNames.write(dataStream, value); + } + } + + static computeSize(map) { + // The size of the length + let size = 4; + for (const [key, value] of map) { + size += FfiConverterU8.computeSize(key); + size += FfiConverterTypeAlternateNames.computeSize(value); + } + return size; + } + + static checkType(map) { + for (const [key, value] of map) { + try { + FfiConverterU8.checkType(key); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart("(key)"); + } + throw e; + } + + try { + FfiConverterTypeAlternateNames.checkType(value); + } catch (e) { + if (e instanceof UniFFITypeError) { + e.addItemDescriptionPart(`[${key}]`); + } + throw e; + } + } + } +} + // Export the FFIConverter object to make external types work. export class FfiConverterTypeJsonValue extends FfiConverter { static lift(buf) { diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs index d3650a6e7801..709f5f61e7ff 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs @@ -448,7 +448,7 @@ export class RemoteCommandStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 62, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command + 63, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command FfiConverterTypeRemoteCommandStore.lower(this), FfiConverterString.lower(deviceId), FfiConverterTypeRemoteCommand.lower(command), @@ -494,7 +494,7 @@ export class RemoteCommandStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 63, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at + 64, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at FfiConverterTypeRemoteCommandStore.lower(this), FfiConverterString.lower(deviceId), FfiConverterTypeRemoteCommand.lower(command), @@ -517,7 +517,7 @@ export class RemoteCommandStore { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 64, // tabs:uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands + 65, // tabs:uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands FfiConverterTypeRemoteCommandStore.lower(this), ) } @@ -554,7 +554,7 @@ export class RemoteCommandStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 65, // tabs:uniffi_tabs_fn_method_remotecommandstore_remove_remote_command + 66, // tabs:uniffi_tabs_fn_method_remotecommandstore_remove_remote_command FfiConverterTypeRemoteCommandStore.lower(this), FfiConverterString.lower(deviceId), FfiConverterTypeRemoteCommand.lower(command), @@ -584,7 +584,7 @@ export class RemoteCommandStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 66, // tabs:uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent + 67, // tabs:uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent FfiConverterTypeRemoteCommandStore.lower(this), FfiConverterTypePendingCommand.lower(command), ) @@ -655,7 +655,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 67, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_apply + 68, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_apply FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -683,7 +683,7 @@ export class TabsBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 68, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id + 69, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id FfiConverterTypeTabsBridgedEngine.lower(this), FfiConverterString.lower(newSyncId), ) @@ -704,7 +704,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 69, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_last_sync + 70, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_last_sync FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -731,7 +731,7 @@ export class TabsBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 70, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync + 71, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync FfiConverterTypeTabsBridgedEngine.lower(this), FfiConverterString.lower(clientData), ) @@ -751,7 +751,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 71, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset + 72, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -771,7 +771,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 72, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id + 73, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -798,7 +798,7 @@ export class TabsBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 73, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync + 74, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync FfiConverterTypeTabsBridgedEngine.lower(this), FfiConverterI64.lower(lastSync), ) @@ -834,7 +834,7 @@ export class TabsBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 74, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded + 75, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded FfiConverterTypeTabsBridgedEngine.lower(this), FfiConverterI64.lower(newTimestamp), FfiConverterSequenceTypeTabsGuid.lower(uploadedIds), @@ -863,7 +863,7 @@ export class TabsBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 75, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_store_incoming + 76, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_store_incoming FfiConverterTypeTabsBridgedEngine.lower(this), FfiConverterSequencestring.lower(incomingEnvelopesAsJson), ) @@ -883,7 +883,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 76, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_finished + 77, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_finished FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -903,7 +903,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 77, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_id + 78, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_id FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -922,7 +922,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 78, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_started + 79, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_started FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -941,7 +941,7 @@ export class TabsBridgedEngine { const liftError = (data) => FfiConverterTypeTabsApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 79, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_wipe + 80, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_wipe FfiConverterTypeTabsBridgedEngine.lower(this), ) } @@ -1016,7 +1016,7 @@ export class TabsStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 86, // tabs:uniffi_tabs_fn_constructor_tabsstore_new + 87, // tabs:uniffi_tabs_fn_constructor_tabsstore_new FfiConverterString.lower(path), ) } @@ -1035,7 +1035,7 @@ export class TabsStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 80, // tabs:uniffi_tabs_fn_method_tabsstore_bridged_engine + 81, // tabs:uniffi_tabs_fn_method_tabsstore_bridged_engine FfiConverterTypeTabsStore.lower(this), ) } @@ -1054,7 +1054,7 @@ export class TabsStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 81, // tabs:uniffi_tabs_fn_method_tabsstore_close_connection + 82, // tabs:uniffi_tabs_fn_method_tabsstore_close_connection FfiConverterTypeTabsStore.lower(this), ) } @@ -1074,7 +1074,7 @@ export class TabsStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 82, // tabs:uniffi_tabs_fn_method_tabsstore_get_all + 83, // tabs:uniffi_tabs_fn_method_tabsstore_get_all FfiConverterTypeTabsStore.lower(this), ) } @@ -1094,7 +1094,7 @@ export class TabsStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 83, // tabs:uniffi_tabs_fn_method_tabsstore_new_remote_command_store + 84, // tabs:uniffi_tabs_fn_method_tabsstore_new_remote_command_store FfiConverterTypeTabsStore.lower(this), ) } @@ -1113,7 +1113,7 @@ export class TabsStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 84, // tabs:uniffi_tabs_fn_method_tabsstore_register_with_sync_manager + 85, // tabs:uniffi_tabs_fn_method_tabsstore_register_with_sync_manager FfiConverterTypeTabsStore.lower(this), ) } @@ -1140,7 +1140,7 @@ export class TabsStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 85, // tabs:uniffi_tabs_fn_method_tabsstore_set_local_tabs + 86, // tabs:uniffi_tabs_fn_method_tabsstore_set_local_tabs FfiConverterTypeTabsStore.lower(this), FfiConverterSequenceTypeRemoteTabRecord.lower(remoteTabs), ) diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs index aba8299ab166..46eaa18fab05 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs @@ -417,7 +417,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 87, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply + 88, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -445,7 +445,7 @@ export class WebExtStorageBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 88, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id + 89, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id FfiConverterTypeWebExtStorageBridgedEngine.lower(this), FfiConverterString.lower(newSyncId), ) @@ -466,7 +466,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 89, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync + 90, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -493,7 +493,7 @@ export class WebExtStorageBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 90, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync + 91, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync FfiConverterTypeWebExtStorageBridgedEngine.lower(this), FfiConverterString.lower(clientData), ) @@ -513,7 +513,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 91, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset + 92, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -533,7 +533,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 92, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id + 93, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -560,7 +560,7 @@ export class WebExtStorageBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 93, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync + 94, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync FfiConverterTypeWebExtStorageBridgedEngine.lower(this), FfiConverterI64.lower(lastSync), ) @@ -596,7 +596,7 @@ export class WebExtStorageBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 94, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded + 95, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded FfiConverterTypeWebExtStorageBridgedEngine.lower(this), FfiConverterI64.lower(serverModifiedMillis), FfiConverterSequenceTypeGuid.lower(guids), @@ -625,7 +625,7 @@ export class WebExtStorageBridgedEngine { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 95, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming + 96, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming FfiConverterTypeWebExtStorageBridgedEngine.lower(this), FfiConverterSequencestring.lower(incoming), ) @@ -645,7 +645,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 96, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished + 97, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -665,7 +665,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 97, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id + 98, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -684,7 +684,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 98, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started + 99, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -703,7 +703,7 @@ export class WebExtStorageBridgedEngine { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 99, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe + 100, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe FfiConverterTypeWebExtStorageBridgedEngine.lower(this), ) } @@ -778,7 +778,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 108, // webextstorage:uniffi_webext_storage_fn_constructor_webextstoragestore_new + 109, // webextstorage:uniffi_webext_storage_fn_constructor_webextstoragestore_new FfiConverterString.lower(path), ) } @@ -797,7 +797,7 @@ export class WebExtStorageStore { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 100, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine + 101, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine FfiConverterTypeWebExtStorageStore.lower(this), ) } @@ -825,7 +825,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 101, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_clear + 102, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_clear FfiConverterTypeWebExtStorageStore.lower(this), FfiConverterString.lower(extId), ) @@ -845,7 +845,7 @@ export class WebExtStorageStore { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 102, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_close + 103, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_close FfiConverterTypeWebExtStorageStore.lower(this), ) } @@ -881,7 +881,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 103, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get + 104, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get FfiConverterTypeWebExtStorageStore.lower(this), FfiConverterString.lower(extId), FfiConverterTypeJsonValue.lower(keys), @@ -919,7 +919,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 104, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use + 105, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use FfiConverterTypeWebExtStorageStore.lower(this), FfiConverterString.lower(extId), FfiConverterTypeJsonValue.lower(keys), @@ -941,7 +941,7 @@ export class WebExtStorageStore { const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 105, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes + 106, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes FfiConverterTypeWebExtStorageStore.lower(this), ) } @@ -977,7 +977,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 106, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_remove + 107, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_remove FfiConverterTypeWebExtStorageStore.lower(this), FfiConverterString.lower(extId), FfiConverterTypeJsonValue.lower(keys), @@ -1015,7 +1015,7 @@ export class WebExtStorageStore { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 107, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_set + 108, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_set FfiConverterTypeWebExtStorageStore.lower(this), FfiConverterString.lower(extId), FfiConverterTypeJsonValue.lower(val), diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs index 39ff545d3083..e51eb56182f0 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs @@ -431,7 +431,7 @@ export function add(a,b) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 109, // arithmetic:uniffi_arithmetical_fn_func_add + 110, // arithmetic:uniffi_arithmetical_fn_func_add FfiConverterU64.lower(a), FfiConverterU64.lower(b), ) @@ -469,7 +469,7 @@ export function div(dividend,divisor) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 110, // arithmetic:uniffi_arithmetical_fn_func_div + 111, // arithmetic:uniffi_arithmetical_fn_func_div FfiConverterU64.lower(dividend), FfiConverterU64.lower(divisor), ) @@ -507,7 +507,7 @@ export function equal(a,b) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 111, // arithmetic:uniffi_arithmetical_fn_func_equal + 112, // arithmetic:uniffi_arithmetical_fn_func_equal FfiConverterU64.lower(a), FfiConverterU64.lower(b), ) @@ -545,7 +545,7 @@ export function sub(a,b) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 112, // arithmetic:uniffi_arithmetical_fn_func_sub + 113, // arithmetic:uniffi_arithmetical_fn_func_sub FfiConverterU64.lower(a), FfiConverterU64.lower(b), ) diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs index 292f2db797d4..839803b7ef1f 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs @@ -857,7 +857,7 @@ export function echoExplicitValue(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 113, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_explicit_value + 114, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_explicit_value FfiConverterTypeExplicitValuedEnum.lower(value), ) } @@ -886,7 +886,7 @@ export function echoGappedValue(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 114, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_gapped_value + 115, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_gapped_value FfiConverterTypeGappedEnum.lower(value), ) } @@ -915,7 +915,7 @@ export function echoSequentialValue(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 115, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_sequential_value + 116, // custom_types:uniffi_uniffi_custom_types_fn_func_echo_sequential_value FfiConverterTypeSequentialEnum.lower(value), ) } @@ -944,7 +944,7 @@ export function getCustomTypesDemo(demo) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 116, // custom_types:uniffi_uniffi_custom_types_fn_func_get_custom_types_demo + 117, // custom_types:uniffi_uniffi_custom_types_fn_func_get_custom_types_demo FfiConverterOptionalTypeCustomTypesDemo.lower(demo), ) } @@ -973,7 +973,7 @@ export function getExplicitDiscriminant(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 117, // custom_types:uniffi_uniffi_custom_types_fn_func_get_explicit_discriminant + 118, // custom_types:uniffi_uniffi_custom_types_fn_func_get_explicit_discriminant FfiConverterTypeExplicitValuedEnum.lower(value), ) } @@ -994,7 +994,7 @@ export function getExplicitEnumValues() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 118, // custom_types:uniffi_uniffi_custom_types_fn_func_get_explicit_enum_values + 119, // custom_types:uniffi_uniffi_custom_types_fn_func_get_explicit_enum_values ) } try { @@ -1022,7 +1022,7 @@ export function getGappedDiscriminant(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 119, // custom_types:uniffi_uniffi_custom_types_fn_func_get_gapped_discriminant + 120, // custom_types:uniffi_uniffi_custom_types_fn_func_get_gapped_discriminant FfiConverterTypeGappedEnum.lower(value), ) } @@ -1043,7 +1043,7 @@ export function getGappedEnumValues() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 120, // custom_types:uniffi_uniffi_custom_types_fn_func_get_gapped_enum_values + 121, // custom_types:uniffi_uniffi_custom_types_fn_func_get_gapped_enum_values ) } try { @@ -1071,7 +1071,7 @@ export function getSequentialDiscriminant(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 121, // custom_types:uniffi_uniffi_custom_types_fn_func_get_sequential_discriminant + 122, // custom_types:uniffi_uniffi_custom_types_fn_func_get_sequential_discriminant FfiConverterTypeSequentialEnum.lower(value), ) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs index c81a1b5a779e..c2231aa6dbce 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs @@ -431,7 +431,7 @@ export function gradient(value) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 122, // external_types:uniffi_uniffi_fixture_external_types_fn_func_gradient + 123, // external_types:uniffi_uniffi_fixture_external_types_fn_func_gradient FfiConverterOptionalTypeLine.lower(value), ) } @@ -468,7 +468,7 @@ export function intersection(ln1,ln2) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 123, // external_types:uniffi_uniffi_fixture_external_types_fn_func_intersection + 124, // external_types:uniffi_uniffi_fixture_external_types_fn_func_intersection FfiConverterTypeLine.lower(ln1), FfiConverterTypeLine.lower(ln2), ) @@ -497,7 +497,7 @@ export function moveSpriteToOrigin(sprite) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 124, // external_types:uniffi_uniffi_fixture_external_types_fn_func_move_sprite_to_origin + 125, // external_types:uniffi_uniffi_fixture_external_types_fn_func_move_sprite_to_origin FfiConverterTypeSprite.lower(sprite), ) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs index 482f231690d3..41305fa69a17 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs @@ -737,7 +737,7 @@ export function callLogRepeat(logger,message,count,exclude) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 125, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_call_log_repeat + 126, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_call_log_repeat FfiConverterTypeLogger.lower(logger), FfiConverterString.lower(message), FfiConverterU32.lower(count), @@ -776,7 +776,7 @@ export function logEvenNumbers(logger,items) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 126, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers + 127, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers FfiConverterTypeLogger.lower(logger), FfiConverterSequencei32.lower(items), ) @@ -813,7 +813,7 @@ export function logEvenNumbersMainThread(logger,items) { throw e; } return UniFFIScaffolding.callSync( - 127, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread + 128, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread FfiConverterTypeLogger.lower(logger), FfiConverterSequencei32.lower(items), ) diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFutures.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFutures.sys.mjs index 4701514b0689..7148d97cf6d6 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFutures.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFutures.sys.mjs @@ -662,7 +662,7 @@ export class FutureTester { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 148, // futures:uniffi_uniffi_fixture_futures_fn_constructor_futuretester_init + 149, // futures:uniffi_uniffi_fixture_futures_fn_constructor_futuretester_init ) } return handleRustResult(functionCall(), liftResult, liftError);} @@ -687,7 +687,7 @@ export class FutureTester { throw e; } return UniFFIScaffolding.callSync( - 145, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_complete_futures + 146, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_complete_futures FfiConverterTypeFutureTester.lower(this), FfiConverterU8.lower(value), ) @@ -704,7 +704,7 @@ export class FutureTester { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsync( - 146, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_make_future + 147, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_make_future FfiConverterTypeFutureTester.lower(this), ) } @@ -724,7 +724,7 @@ export class FutureTester { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 147, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_wake_futures + 148, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_wake_futures FfiConverterTypeFutureTester.lower(this), ) } @@ -787,7 +787,7 @@ export class RustTask { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 149, // futures:uniffi_uniffi_fixture_futures_fn_method_rusttask_run + 150, // futures:uniffi_uniffi_fixture_futures_fn_method_rusttask_run FfiConverterTypeRustTask.lower(this), ) } @@ -858,7 +858,7 @@ export class Traveller { throw e; } return UniFFIScaffolding.callSync( - 151, // futures:uniffi_uniffi_fixture_futures_fn_constructor_traveller_new + 152, // futures:uniffi_uniffi_fixture_futures_fn_constructor_traveller_new FfiConverterString.lower(name), ) } @@ -873,7 +873,7 @@ export class Traveller { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 150, // futures:uniffi_uniffi_fixture_futures_fn_method_traveller_name + 151, // futures:uniffi_uniffi_fixture_futures_fn_method_traveller_name FfiConverterTypeTraveller.lower(this), ) } @@ -950,7 +950,7 @@ export class WorkerQueue { throw e; } return UniFFIScaffolding.callSync( - 152, // futures:uniffi_uniffi_fixture_futures_fn_method_workerqueue_add_task + 153, // futures:uniffi_uniffi_fixture_futures_fn_method_workerqueue_add_task FfiConverterTypeWorkerQueue.lower(this), FfiConverterTypeRustTask.lower(task), ) @@ -1104,7 +1104,7 @@ export function expensiveComputation() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsync( - 128, // futures:uniffi_uniffi_fixture_futures_fn_func_expensive_computation + 129, // futures:uniffi_uniffi_fixture_futures_fn_func_expensive_computation ) } try { @@ -1127,7 +1127,7 @@ export function initializeGeckoGlobalWorkerQueue() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 129, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_gecko_global_worker_queue + 130, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_gecko_global_worker_queue ) } return handleRustResult(functionCall(), liftResult, liftError); @@ -1151,7 +1151,7 @@ export function initializeGlobalWorkerQueue(workerQueue) { throw e; } return UniFFIScaffolding.callSync( - 130, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_global_worker_queue + 131, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_global_worker_queue FfiConverterTypeWorkerQueue.lower(workerQueue), ) } @@ -1176,7 +1176,7 @@ export function roundtripF32(v) { throw e; } return UniFFIScaffolding.callAsync( - 131, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f32 + 132, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f32 FfiConverterF32.lower(v), ) } @@ -1205,7 +1205,7 @@ export function roundtripF64(v) { throw e; } return UniFFIScaffolding.callAsync( - 132, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f64 + 133, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f64 FfiConverterF64.lower(v), ) } @@ -1234,7 +1234,7 @@ export function roundtripI16(v) { throw e; } return UniFFIScaffolding.callAsync( - 133, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i16 + 134, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i16 FfiConverterI16.lower(v), ) } @@ -1263,7 +1263,7 @@ export function roundtripI32(v) { throw e; } return UniFFIScaffolding.callAsync( - 134, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i32 + 135, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i32 FfiConverterI32.lower(v), ) } @@ -1292,7 +1292,7 @@ export function roundtripI64(v) { throw e; } return UniFFIScaffolding.callAsync( - 135, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i64 + 136, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i64 FfiConverterI64.lower(v), ) } @@ -1321,7 +1321,7 @@ export function roundtripI8(v) { throw e; } return UniFFIScaffolding.callAsync( - 136, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i8 + 137, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i8 FfiConverterI8.lower(v), ) } @@ -1350,7 +1350,7 @@ export function roundtripMap(v) { throw e; } return UniFFIScaffolding.callAsync( - 137, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_map + 138, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_map FfiConverterMapStringString.lower(v), ) } @@ -1379,7 +1379,7 @@ export function roundtripObj(v) { throw e; } return UniFFIScaffolding.callAsync( - 138, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_obj + 139, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_obj FfiConverterTypeTraveller.lower(v), ) } @@ -1408,7 +1408,7 @@ export function roundtripString(v) { throw e; } return UniFFIScaffolding.callAsync( - 139, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_string + 140, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_string FfiConverterString.lower(v), ) } @@ -1437,7 +1437,7 @@ export function roundtripU16(v) { throw e; } return UniFFIScaffolding.callAsync( - 140, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u16 + 141, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u16 FfiConverterU16.lower(v), ) } @@ -1466,7 +1466,7 @@ export function roundtripU32(v) { throw e; } return UniFFIScaffolding.callAsync( - 141, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u32 + 142, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u32 FfiConverterU32.lower(v), ) } @@ -1495,7 +1495,7 @@ export function roundtripU64(v) { throw e; } return UniFFIScaffolding.callAsync( - 142, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u64 + 143, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u64 FfiConverterU64.lower(v), ) } @@ -1524,7 +1524,7 @@ export function roundtripU8(v) { throw e; } return UniFFIScaffolding.callAsync( - 143, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u8 + 144, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u8 FfiConverterU8.lower(v), ) } @@ -1553,7 +1553,7 @@ export function roundtripVec(v) { throw e; } return UniFFIScaffolding.callAsync( - 144, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_vec + 145, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_vec FfiConverterSequenceu32.lower(v), ) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs index 82817ef88ccc..6f6fc2cc4e88 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs @@ -542,7 +542,7 @@ export function gradient(ln) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 153, // geometry:uniffi_uniffi_geometry_fn_func_gradient + 154, // geometry:uniffi_uniffi_geometry_fn_func_gradient FfiConverterTypeLine.lower(ln), ) } @@ -579,7 +579,7 @@ export function intersection(ln1,ln2) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 154, // geometry:uniffi_uniffi_geometry_fn_func_intersection + 155, // geometry:uniffi_uniffi_geometry_fn_func_intersection FfiConverterTypeLine.lower(ln1), FfiConverterTypeLine.lower(ln2), ) diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRefcounts.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRefcounts.sys.mjs index be05d7183ccf..3edc3b96b422 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRefcounts.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRefcounts.sys.mjs @@ -371,7 +371,7 @@ export class SingletonObject { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 157, // refcounts:uniffi_uniffi_fixture_refcounts_fn_method_singletonobject_method + 158, // refcounts:uniffi_uniffi_fixture_refcounts_fn_method_singletonobject_method FfiConverterTypeSingletonObject.lower(this), ) } @@ -423,7 +423,7 @@ export function getJsRefcount() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 155, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_js_refcount + 156, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_js_refcount ) } return handleRustResult(functionCall(), liftResult, liftError); @@ -439,7 +439,7 @@ export function getSingleton() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 156, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_singleton + 157, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_singleton ) } return handleRustResult(functionCall(), liftResult, liftError); diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs index 811d4c55c098..f4e42bb57d02 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs @@ -665,7 +665,7 @@ export class Optionneur { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 188, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_optionneur_new + 189, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_optionneur_new ) } try { @@ -691,7 +691,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 163, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_boolean + 164, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_boolean FfiConverterTypeOptionneur.lower(this), FfiConverterBool.lower(value), ) @@ -720,7 +720,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 164, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_enum + 165, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_enum FfiConverterTypeOptionneur.lower(this), FfiConverterTypeEnumeration.lower(value), ) @@ -749,7 +749,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 165, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f32 + 166, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f32 FfiConverterTypeOptionneur.lower(this), FfiConverterF32.lower(value), ) @@ -778,7 +778,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 166, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f64 + 167, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f64 FfiConverterTypeOptionneur.lower(this), FfiConverterF64.lower(value), ) @@ -807,7 +807,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 167, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec + 168, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec FfiConverterTypeOptionneur.lower(this), FfiConverterI16.lower(value), ) @@ -836,7 +836,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 168, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex + 169, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex FfiConverterTypeOptionneur.lower(this), FfiConverterI16.lower(value), ) @@ -865,7 +865,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 169, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec + 170, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec FfiConverterTypeOptionneur.lower(this), FfiConverterI32.lower(value), ) @@ -894,7 +894,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 170, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex + 171, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex FfiConverterTypeOptionneur.lower(this), FfiConverterI32.lower(value), ) @@ -923,7 +923,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 171, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec + 172, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec FfiConverterTypeOptionneur.lower(this), FfiConverterI64.lower(value), ) @@ -952,7 +952,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 172, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex + 173, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex FfiConverterTypeOptionneur.lower(this), FfiConverterI64.lower(value), ) @@ -981,7 +981,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 173, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec + 174, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec FfiConverterTypeOptionneur.lower(this), FfiConverterI8.lower(value), ) @@ -1010,7 +1010,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 174, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex + 175, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex FfiConverterTypeOptionneur.lower(this), FfiConverterI8.lower(value), ) @@ -1039,7 +1039,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 175, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_null + 176, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_null FfiConverterTypeOptionneur.lower(this), FfiConverterOptionalstring.lower(value), ) @@ -1068,7 +1068,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 176, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_sequence + 177, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_sequence FfiConverterTypeOptionneur.lower(this), FfiConverterSequencestring.lower(value), ) @@ -1097,7 +1097,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 177, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_string + 178, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_string FfiConverterTypeOptionneur.lower(this), FfiConverterString.lower(value), ) @@ -1126,7 +1126,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 178, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec + 179, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec FfiConverterTypeOptionneur.lower(this), FfiConverterU16.lower(value), ) @@ -1155,7 +1155,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 179, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex + 180, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex FfiConverterTypeOptionneur.lower(this), FfiConverterU16.lower(value), ) @@ -1184,7 +1184,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 180, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec + 181, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec FfiConverterTypeOptionneur.lower(this), FfiConverterU32.lower(value), ) @@ -1213,7 +1213,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 181, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex + 182, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex FfiConverterTypeOptionneur.lower(this), FfiConverterU32.lower(value), ) @@ -1242,7 +1242,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 182, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct + 183, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct FfiConverterTypeOptionneur.lower(this), FfiConverterU32.lower(value), ) @@ -1271,7 +1271,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 183, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec + 184, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec FfiConverterTypeOptionneur.lower(this), FfiConverterU64.lower(value), ) @@ -1300,7 +1300,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 184, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex + 185, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex FfiConverterTypeOptionneur.lower(this), FfiConverterU64.lower(value), ) @@ -1329,7 +1329,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 185, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec + 186, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec FfiConverterTypeOptionneur.lower(this), FfiConverterU8.lower(value), ) @@ -1358,7 +1358,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 186, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex + 187, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex FfiConverterTypeOptionneur.lower(this), FfiConverterU8.lower(value), ) @@ -1387,7 +1387,7 @@ export class Optionneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 187, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_zero + 188, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_zero FfiConverterTypeOptionneur.lower(this), FfiConverterOptionali32.lower(value), ) @@ -1455,7 +1455,7 @@ export class Retourneur { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 204, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_retourneur_new + 205, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_retourneur_new ) } try { @@ -1481,7 +1481,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 189, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_boolean + 190, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_boolean FfiConverterTypeRetourneur.lower(this), FfiConverterBool.lower(value), ) @@ -1510,7 +1510,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 190, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_double + 191, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_double FfiConverterTypeRetourneur.lower(this), FfiConverterF64.lower(value), ) @@ -1539,7 +1539,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 191, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_float + 192, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_float FfiConverterTypeRetourneur.lower(this), FfiConverterF32.lower(value), ) @@ -1568,7 +1568,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 192, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i16 + 193, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i16 FfiConverterTypeRetourneur.lower(this), FfiConverterI16.lower(value), ) @@ -1597,7 +1597,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 193, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i32 + 194, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i32 FfiConverterTypeRetourneur.lower(this), FfiConverterI32.lower(value), ) @@ -1626,7 +1626,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 194, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i64 + 195, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i64 FfiConverterTypeRetourneur.lower(this), FfiConverterI64.lower(value), ) @@ -1655,7 +1655,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 195, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i8 + 196, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i8 FfiConverterTypeRetourneur.lower(this), FfiConverterI8.lower(value), ) @@ -1684,7 +1684,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 196, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres + 197, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres FfiConverterTypeRetourneur.lower(this), FfiConverterTypeDictionnaireNombres.lower(value), ) @@ -1713,7 +1713,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 197, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes + 198, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes FfiConverterTypeRetourneur.lower(this), FfiConverterTypeDictionnaireNombresSignes.lower(value), ) @@ -1742,7 +1742,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 198, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire + 199, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire FfiConverterTypeRetourneur.lower(this), FfiConverterTypeOptionneurDictionnaire.lower(value), ) @@ -1771,7 +1771,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 199, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_string + 200, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_string FfiConverterTypeRetourneur.lower(this), FfiConverterString.lower(value), ) @@ -1800,7 +1800,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 200, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u16 + 201, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u16 FfiConverterTypeRetourneur.lower(this), FfiConverterU16.lower(value), ) @@ -1829,7 +1829,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 201, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u32 + 202, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u32 FfiConverterTypeRetourneur.lower(this), FfiConverterU32.lower(value), ) @@ -1858,7 +1858,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 202, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u64 + 203, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u64 FfiConverterTypeRetourneur.lower(this), FfiConverterU64.lower(value), ) @@ -1887,7 +1887,7 @@ export class Retourneur { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 203, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u8 + 204, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u8 FfiConverterTypeRetourneur.lower(this), FfiConverterU8.lower(value), ) @@ -1955,7 +1955,7 @@ export class Stringifier { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 217, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_stringifier_new + 218, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_stringifier_new ) } try { @@ -1981,7 +1981,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 205, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_boolean + 206, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_boolean FfiConverterTypeStringifier.lower(this), FfiConverterBool.lower(value), ) @@ -2010,7 +2010,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 206, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_double + 207, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_double FfiConverterTypeStringifier.lower(this), FfiConverterF64.lower(value), ) @@ -2039,7 +2039,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 207, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_float + 208, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_float FfiConverterTypeStringifier.lower(this), FfiConverterF32.lower(value), ) @@ -2068,7 +2068,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 208, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i16 + 209, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i16 FfiConverterTypeStringifier.lower(this), FfiConverterI16.lower(value), ) @@ -2097,7 +2097,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 209, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i32 + 210, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i32 FfiConverterTypeStringifier.lower(this), FfiConverterI32.lower(value), ) @@ -2126,7 +2126,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 210, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i64 + 211, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i64 FfiConverterTypeStringifier.lower(this), FfiConverterI64.lower(value), ) @@ -2155,7 +2155,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 211, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i8 + 212, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i8 FfiConverterTypeStringifier.lower(this), FfiConverterI8.lower(value), ) @@ -2184,7 +2184,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 212, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u16 + 213, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u16 FfiConverterTypeStringifier.lower(this), FfiConverterU16.lower(value), ) @@ -2213,7 +2213,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 213, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u32 + 214, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u32 FfiConverterTypeStringifier.lower(this), FfiConverterU32.lower(value), ) @@ -2242,7 +2242,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 214, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u64 + 215, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u64 FfiConverterTypeStringifier.lower(this), FfiConverterU64.lower(value), ) @@ -2271,7 +2271,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 215, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u8 + 216, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u8 FfiConverterTypeStringifier.lower(this), FfiConverterU8.lower(value), ) @@ -2300,7 +2300,7 @@ export class Stringifier { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 216, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_well_known_string + 217, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_well_known_string FfiConverterTypeStringifier.lower(this), FfiConverterString.lower(value), ) @@ -3686,7 +3686,7 @@ export function copieCarte(c) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 158, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_carte + 159, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_carte FfiConverterMapStringTypeEnumerationAvecDonnees.lower(c), ) } @@ -3715,7 +3715,7 @@ export function copieDictionnaire(d) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 159, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_dictionnaire + 160, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_dictionnaire FfiConverterTypeDictionnaire.lower(d), ) } @@ -3744,7 +3744,7 @@ export function copieEnumeration(e) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 160, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumeration + 161, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumeration FfiConverterTypeEnumeration.lower(e), ) } @@ -3773,7 +3773,7 @@ export function copieEnumerations(e) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 161, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumerations + 162, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumerations FfiConverterSequenceTypeEnumeration.lower(e), ) } @@ -3802,7 +3802,7 @@ export function switcheroo(b) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 162, // rondpoint:uniffi_uniffi_rondpoint_fn_func_switcheroo + 163, // rondpoint:uniffi_uniffi_rondpoint_fn_func_switcheroo FfiConverterBool.lower(b), ) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs index 327b33a6861d..9f2e30682145 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs @@ -370,7 +370,7 @@ export class Sprite { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 222, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new + 223, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new FfiConverterOptionalTypePoint.lower(initialPosition), ) } @@ -404,7 +404,7 @@ export class Sprite { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 223, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new_relative_to + 224, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new_relative_to FfiConverterTypePoint.lower(reference), FfiConverterTypeVector.lower(direction), ) @@ -424,7 +424,7 @@ export class Sprite { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 219, // sprites:uniffi_uniffi_sprites_fn_method_sprite_get_position + 220, // sprites:uniffi_uniffi_sprites_fn_method_sprite_get_position FfiConverterTypeSprite.lower(this), ) } @@ -451,7 +451,7 @@ export class Sprite { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 220, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_by + 221, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_by FfiConverterTypeSprite.lower(this), FfiConverterTypeVector.lower(direction), ) @@ -479,7 +479,7 @@ export class Sprite { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 221, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_to + 222, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_to FfiConverterTypeSprite.lower(this), FfiConverterTypePoint.lower(position), ) @@ -755,7 +755,7 @@ export function translate(p,v) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 218, // sprites:uniffi_uniffi_sprites_fn_func_translate + 219, // sprites:uniffi_uniffi_sprites_fn_func_translate FfiConverterTypePoint.lower(p), FfiConverterTypeVector.lower(v), ) diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs index 85ef746b242e..bb6c57149ef4 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs @@ -343,7 +343,7 @@ export class TodoList { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 238, // todolist:uniffi_uniffi_todolist_fn_constructor_todolist_new + 239, // todolist:uniffi_uniffi_todolist_fn_constructor_todolist_new ) } try { @@ -368,7 +368,7 @@ export class TodoList { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 227, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entries + 228, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entries FfiConverterTypeTodoList.lower(this), FfiConverterSequenceTypeTodoEntry.lower(entries), ) @@ -396,7 +396,7 @@ export class TodoList { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 228, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entry + 229, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entry FfiConverterTypeTodoList.lower(this), FfiConverterTypeTodoEntry.lower(entry), ) @@ -424,7 +424,7 @@ export class TodoList { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 229, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_item + 230, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_item FfiConverterTypeTodoList.lower(this), FfiConverterString.lower(todo), ) @@ -452,7 +452,7 @@ export class TodoList { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 230, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_items + 231, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_items FfiConverterTypeTodoList.lower(this), FfiConverterSequencestring.lower(items), ) @@ -480,7 +480,7 @@ export class TodoList { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 231, // todolist:uniffi_uniffi_todolist_fn_method_todolist_clear_item + 232, // todolist:uniffi_uniffi_todolist_fn_method_todolist_clear_item FfiConverterTypeTodoList.lower(this), FfiConverterString.lower(todo), ) @@ -501,7 +501,7 @@ export class TodoList { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 232, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_entries + 233, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_entries FfiConverterTypeTodoList.lower(this), ) } @@ -521,7 +521,7 @@ export class TodoList { const liftError = (data) => FfiConverterTypeTodoError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 233, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_first + 234, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_first FfiConverterTypeTodoList.lower(this), ) } @@ -541,7 +541,7 @@ export class TodoList { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 234, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_items + 235, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_items FfiConverterTypeTodoList.lower(this), ) } @@ -561,7 +561,7 @@ export class TodoList { const liftError = (data) => FfiConverterTypeTodoError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 235, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last + 236, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last FfiConverterTypeTodoList.lower(this), ) } @@ -581,7 +581,7 @@ export class TodoList { const liftError = (data) => FfiConverterTypeTodoError.lift(data); const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 236, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last_entry + 237, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last_entry FfiConverterTypeTodoList.lower(this), ) } @@ -600,7 +600,7 @@ export class TodoList { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 237, // todolist:uniffi_uniffi_todolist_fn_method_todolist_make_default + 238, // todolist:uniffi_uniffi_todolist_fn_method_todolist_make_default FfiConverterTypeTodoList.lower(this), ) } @@ -992,7 +992,7 @@ export function createEntryWith(todo) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 224, // todolist:uniffi_uniffi_todolist_fn_func_create_entry_with + 225, // todolist:uniffi_uniffi_todolist_fn_func_create_entry_with FfiConverterString.lower(todo), ) } @@ -1013,7 +1013,7 @@ export function getDefaultList() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callAsyncWrapper( - 225, // todolist:uniffi_uniffi_todolist_fn_func_get_default_list + 226, // todolist:uniffi_uniffi_todolist_fn_func_get_default_list ) } try { @@ -1040,7 +1040,7 @@ export function setDefaultList(list) { throw e; } return UniFFIScaffolding.callAsyncWrapper( - 226, // todolist:uniffi_uniffi_todolist_fn_func_set_default_list + 227, // todolist:uniffi_uniffi_todolist_fn_func_set_default_list FfiConverterTypeTodoList.lower(list), ) } diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustUniffiTraitInterfaces.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustUniffiTraitInterfaces.sys.mjs index 23ea21dfd288..fe3b22a60af5 100644 --- a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustUniffiTraitInterfaces.sys.mjs +++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustUniffiTraitInterfaces.sys.mjs @@ -388,7 +388,7 @@ export class Calc { throw e; } return UniFFIScaffolding.callSync( - 241, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_method_calc_add + 242, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_method_calc_add FfiConverterTypeCalc.lower(this), FfiConverterU32.lower(a), FfiConverterU32.lower(b), @@ -442,7 +442,7 @@ export function makeBuggyCalculator() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 239, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_buggy_calculator + 240, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_buggy_calculator ) } return handleRustResult(functionCall(), liftResult, liftError); @@ -458,7 +458,7 @@ export function makeCalculator() { const liftError = null; const functionCall = () => { return UniFFIScaffolding.callSync( - 240, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_calculator + 241, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_calculator ) } return handleRustResult(functionCall(), liftResult, liftError); diff --git a/toolkit/components/uniffi-js/GeneratedScaffolding.cpp b/toolkit/components/uniffi-js/GeneratedScaffolding.cpp index bb8c00f48f7b..04fa45f040b1 100644 --- a/toolkit/components/uniffi-js/GeneratedScaffolding.cpp +++ b/toolkit/components/uniffi-js/GeneratedScaffolding.cpp @@ -505,7 +505,8 @@ extern "C" { void uniffi_suggest_fn_method_suggeststore_dismiss_by_key(void*, RustBuffer, RustCallStatus*); void uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion(void*, RustBuffer, RustCallStatus*); void uniffi_suggest_fn_method_suggeststore_dismiss_suggestion(void*, RustBuffer, RustCallStatus*); - RustBuffer uniffi_suggest_fn_method_suggeststore_fetch_geonames(void*, RustBuffer, int8_t, RustBuffer, RustBuffer, RustCallStatus*); + RustBuffer uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates(void*, RustBuffer, RustCallStatus*); + RustBuffer uniffi_suggest_fn_method_suggeststore_fetch_geonames(void*, RustBuffer, int8_t, RustBuffer, RustCallStatus*); RustBuffer uniffi_suggest_fn_method_suggeststore_fetch_global_config(void*, RustCallStatus*); RustBuffer uniffi_suggest_fn_method_suggeststore_fetch_provider_config(void*, RustBuffer, RustCallStatus*); RustBuffer uniffi_suggest_fn_method_suggeststore_ingest(void*, RustBuffer, RustCallStatus*); @@ -588,6 +589,7 @@ extern "C" { uint16_t uniffi_suggest_checksum_method_suggeststore_dismiss_by_key(); uint16_t uniffi_suggest_checksum_method_suggeststore_dismiss_by_suggestion(); uint16_t uniffi_suggest_checksum_method_suggeststore_dismiss_suggestion(); + uint16_t uniffi_suggest_checksum_method_suggeststore_fetch_geoname_alternates(); uint16_t uniffi_suggest_checksum_method_suggeststore_fetch_geonames(); uint16_t uniffi_suggest_checksum_method_suggeststore_fetch_global_config(); uint16_t uniffi_suggest_checksum_method_suggeststore_fetch_provider_config(); @@ -5592,13 +5594,51 @@ public: virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional& aDest, ErrorResult& aError) override { } }; +class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonameAlternates : public UniffiSyncCallHandler { +private: + // LowerRustArgs stores the resulting arguments in these fields + FfiValueObjectHandleSuggestSuggestStore mPtr{}; + FfiValueRustBuffer mGeoname{}; + + // MakeRustCall stores the result of the call in these fields + FfiValueRustBuffer mUniffiReturnValue{}; + +public: + void LowerRustArgs(const dom::Sequence& aArgs, ErrorResult& aError) override { + mPtr.Lower(aArgs[0], aError); + if (aError.Failed()) { + return; + } + mGeoname.Lower(aArgs[1], aError); + if (aError.Failed()) { + return; + } + } + + void MakeRustCall(RustCallStatus* aOutStatus) override { + mUniffiReturnValue = FfiValueRustBuffer::FromRust( + uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates( + mPtr.IntoRust(), + mGeoname.IntoRust(), + aOutStatus + ) + ); + } + + virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional& aDest, ErrorResult& aError) override { + mUniffiReturnValue.Lift( + aCx, + &aDest.Construct(), + aError + ); + } +}; class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames : public UniffiSyncCallHandler { private: // LowerRustArgs stores the resulting arguments in these fields FfiValueObjectHandleSuggestSuggestStore mPtr{}; FfiValueRustBuffer mQuery{}; FfiValueInt mMatchNamePrefix{}; - FfiValueRustBuffer mGeonameType{}; FfiValueRustBuffer mFilter{}; // MakeRustCall stores the result of the call in these fields @@ -5618,11 +5658,7 @@ public: if (aError.Failed()) { return; } - mGeonameType.Lower(aArgs[3], aError); - if (aError.Failed()) { - return; - } - mFilter.Lower(aArgs[4], aError); + mFilter.Lower(aArgs[3], aError); if (aError.Failed()) { return; } @@ -5634,7 +5670,6 @@ public: mPtr.IntoRust(), mQuery.IntoRust(), mMatchNamePrefix.IntoRust(), - mGeonameType.IntoRust(), mFilter.IntoRust(), aOutStatus ) @@ -12686,551 +12721,554 @@ UniquePtr GetSyncCallHandler(uint64_t aId) { return MakeUnique(); } case 44: { - return MakeUnique(); + return MakeUnique(); } case 45: { - return MakeUnique(); + return MakeUnique(); } case 46: { - return MakeUnique(); + return MakeUnique(); } case 47: { - return MakeUnique(); + return MakeUnique(); } case 48: { - return MakeUnique(); + return MakeUnique(); } case 49: { - return MakeUnique(); + return MakeUnique(); } case 50: { - return MakeUnique(); + return MakeUnique(); } case 51: { - return MakeUnique(); + return MakeUnique(); } case 52: { - return MakeUnique(); + return MakeUnique(); } case 53: { - return MakeUnique(); + return MakeUnique(); } case 54: { - return MakeUnique(); + return MakeUnique(); } case 55: { - return MakeUnique(); + return MakeUnique(); } case 56: { - return MakeUnique(); + return MakeUnique(); } case 57: { - return MakeUnique(); + return MakeUnique(); } case 58: { - return MakeUnique(); + return MakeUnique(); } case 59: { - return MakeUnique(); + return MakeUnique(); } case 60: { - return MakeUnique(); + return MakeUnique(); } case 61: { - return MakeUnique(); + return MakeUnique(); } case 62: { - return MakeUnique(); + return MakeUnique(); } case 63: { - return MakeUnique(); + return MakeUnique(); } case 64: { - return MakeUnique(); + return MakeUnique(); } case 65: { - return MakeUnique(); + return MakeUnique(); } case 66: { - return MakeUnique(); + return MakeUnique(); } case 67: { - return MakeUnique(); + return MakeUnique(); } case 68: { - return MakeUnique(); + return MakeUnique(); } case 69: { - return MakeUnique(); + return MakeUnique(); } case 70: { - return MakeUnique(); + return MakeUnique(); } case 71: { - return MakeUnique(); + return MakeUnique(); } case 72: { - return MakeUnique(); + return MakeUnique(); } case 73: { - return MakeUnique(); + return MakeUnique(); } case 74: { - return MakeUnique(); + return MakeUnique(); } case 75: { - return MakeUnique(); + return MakeUnique(); } case 76: { - return MakeUnique(); + return MakeUnique(); } case 77: { - return MakeUnique(); + return MakeUnique(); } case 78: { - return MakeUnique(); + return MakeUnique(); } case 79: { - return MakeUnique(); + return MakeUnique(); } case 80: { - return MakeUnique(); + return MakeUnique(); } case 81: { - return MakeUnique(); + return MakeUnique(); } case 82: { - return MakeUnique(); + return MakeUnique(); } case 83: { - return MakeUnique(); + return MakeUnique(); } case 84: { - return MakeUnique(); + return MakeUnique(); } case 85: { - return MakeUnique(); + return MakeUnique(); } case 86: { - return MakeUnique(); + return MakeUnique(); } case 87: { - return MakeUnique(); + return MakeUnique(); } case 88: { - return MakeUnique(); + return MakeUnique(); } case 89: { - return MakeUnique(); + return MakeUnique(); } case 90: { - return MakeUnique(); + return MakeUnique(); } case 91: { - return MakeUnique(); + return MakeUnique(); } case 92: { - return MakeUnique(); + return MakeUnique(); } case 93: { - return MakeUnique(); + return MakeUnique(); } case 94: { - return MakeUnique(); + return MakeUnique(); } case 95: { - return MakeUnique(); + return MakeUnique(); } case 96: { - return MakeUnique(); + return MakeUnique(); } case 97: { - return MakeUnique(); + return MakeUnique(); } case 98: { - return MakeUnique(); + return MakeUnique(); } case 99: { - return MakeUnique(); + return MakeUnique(); } case 100: { - return MakeUnique(); + return MakeUnique(); } case 101: { - return MakeUnique(); + return MakeUnique(); } case 102: { - return MakeUnique(); + return MakeUnique(); } case 103: { - return MakeUnique(); + return MakeUnique(); } case 104: { - return MakeUnique(); + return MakeUnique(); } case 105: { - return MakeUnique(); + return MakeUnique(); } case 106: { - return MakeUnique(); + return MakeUnique(); } case 107: { - return MakeUnique(); + return MakeUnique(); } case 108: { + return MakeUnique(); + } + case 109: { return MakeUnique(); } #ifdef MOZ_UNIFFI_FIXTURES - case 109: { + case 110: { return MakeUnique(); } - case 110: { + case 111: { return MakeUnique(); } - case 111: { + case 112: { return MakeUnique(); } - case 112: { + case 113: { return MakeUnique(); } - case 113: { + case 114: { return MakeUnique(); } - case 114: { + case 115: { return MakeUnique(); } - case 115: { + case 116: { return MakeUnique(); } - case 116: { + case 117: { return MakeUnique(); } - case 117: { + case 118: { return MakeUnique(); } - case 118: { + case 119: { return MakeUnique(); } - case 119: { + case 120: { return MakeUnique(); } - case 120: { + case 121: { return MakeUnique(); } - case 121: { + case 122: { return MakeUnique(); } - case 122: { + case 123: { return MakeUnique(); } - case 123: { + case 124: { return MakeUnique(); } - case 124: { + case 125: { return MakeUnique(); } - case 125: { + case 126: { return MakeUnique(); } - case 126: { + case 127: { return MakeUnique(); } - case 127: { + case 128: { return MakeUnique(); } - case 129: { + case 130: { return MakeUnique(); } - case 130: { + case 131: { return MakeUnique(); } - case 145: { + case 146: { return MakeUnique(); } - case 147: { + case 148: { return MakeUnique(); } - case 148: { + case 149: { return MakeUnique(); } - case 149: { + case 150: { return MakeUnique(); } - case 150: { + case 151: { return MakeUnique(); } - case 151: { + case 152: { return MakeUnique(); } - case 152: { + case 153: { return MakeUnique(); } - case 153: { + case 154: { return MakeUnique(); } - case 154: { + case 155: { return MakeUnique(); } - case 155: { + case 156: { return MakeUnique(); } - case 156: { + case 157: { return MakeUnique(); } - case 157: { + case 158: { return MakeUnique(); } - case 158: { + case 159: { return MakeUnique(); } - case 159: { + case 160: { return MakeUnique(); } - case 160: { + case 161: { return MakeUnique(); } - case 161: { + case 162: { return MakeUnique(); } - case 162: { + case 163: { return MakeUnique(); } - case 163: { + case 164: { return MakeUnique(); } - case 164: { + case 165: { return MakeUnique(); } - case 165: { + case 166: { return MakeUnique(); } - case 166: { + case 167: { return MakeUnique(); } - case 167: { + case 168: { return MakeUnique(); } - case 168: { + case 169: { return MakeUnique(); } - case 169: { + case 170: { return MakeUnique(); } - case 170: { + case 171: { return MakeUnique(); } - case 171: { + case 172: { return MakeUnique(); } - case 172: { + case 173: { return MakeUnique(); } - case 173: { + case 174: { return MakeUnique(); } - case 174: { + case 175: { return MakeUnique(); } - case 175: { + case 176: { return MakeUnique(); } - case 176: { + case 177: { return MakeUnique(); } - case 177: { + case 178: { return MakeUnique(); } - case 178: { + case 179: { return MakeUnique(); } - case 179: { + case 180: { return MakeUnique(); } - case 180: { + case 181: { return MakeUnique(); } - case 181: { + case 182: { return MakeUnique(); } - case 182: { + case 183: { return MakeUnique(); } - case 183: { + case 184: { return MakeUnique(); } - case 184: { + case 185: { return MakeUnique(); } - case 185: { + case 186: { return MakeUnique(); } - case 186: { + case 187: { return MakeUnique(); } - case 187: { + case 188: { return MakeUnique(); } - case 188: { + case 189: { return MakeUnique(); } - case 189: { + case 190: { return MakeUnique(); } - case 190: { + case 191: { return MakeUnique(); } - case 191: { + case 192: { return MakeUnique(); } - case 192: { + case 193: { return MakeUnique(); } - case 193: { + case 194: { return MakeUnique(); } - case 194: { + case 195: { return MakeUnique(); } - case 195: { + case 196: { return MakeUnique(); } - case 196: { + case 197: { return MakeUnique(); } - case 197: { + case 198: { return MakeUnique(); } - case 198: { + case 199: { return MakeUnique(); } - case 199: { + case 200: { return MakeUnique(); } - case 200: { + case 201: { return MakeUnique(); } - case 201: { + case 202: { return MakeUnique(); } - case 202: { + case 203: { return MakeUnique(); } - case 203: { + case 204: { return MakeUnique(); } - case 204: { + case 205: { return MakeUnique(); } - case 205: { + case 206: { return MakeUnique(); } - case 206: { + case 207: { return MakeUnique(); } - case 207: { + case 208: { return MakeUnique(); } - case 208: { + case 209: { return MakeUnique(); } - case 209: { + case 210: { return MakeUnique(); } - case 210: { + case 211: { return MakeUnique(); } - case 211: { + case 212: { return MakeUnique(); } - case 212: { + case 213: { return MakeUnique(); } - case 213: { + case 214: { return MakeUnique(); } - case 214: { + case 215: { return MakeUnique(); } - case 215: { + case 216: { return MakeUnique(); } - case 216: { + case 217: { return MakeUnique(); } - case 217: { + case 218: { return MakeUnique(); } - case 218: { + case 219: { return MakeUnique(); } - case 219: { + case 220: { return MakeUnique(); } - case 220: { + case 221: { return MakeUnique(); } - case 221: { + case 222: { return MakeUnique(); } - case 222: { + case 223: { return MakeUnique(); } - case 223: { + case 224: { return MakeUnique(); } - case 224: { + case 225: { return MakeUnique(); } - case 225: { + case 226: { return MakeUnique(); } - case 226: { + case 227: { return MakeUnique(); } - case 227: { + case 228: { return MakeUnique(); } - case 228: { + case 229: { return MakeUnique(); } - case 229: { + case 230: { return MakeUnique(); } - case 230: { + case 231: { return MakeUnique(); } - case 231: { + case 232: { return MakeUnique(); } - case 232: { + case 233: { return MakeUnique(); } - case 233: { + case 234: { return MakeUnique(); } - case 234: { + case 235: { return MakeUnique(); } - case 235: { + case 236: { return MakeUnique(); } - case 236: { + case 237: { return MakeUnique(); } - case 237: { + case 238: { return MakeUnique(); } - case 238: { + case 239: { return MakeUnique(); } - case 239: { + case 240: { return MakeUnique(); } - case 240: { + case 241: { return MakeUnique(); } - case 241: { + case 242: { return MakeUnique(); } #endif /* MOZ_UNIFFI_FIXTURES */ @@ -13245,52 +13283,52 @@ UniquePtr GetAsyncCallHandler(uint64_t aId) { #ifdef MOZ_UNIFFI_FIXTURES - case 128: { + case 129: { return MakeUnique(); } - case 131: { + case 132: { return MakeUnique(); } - case 132: { + case 133: { return MakeUnique(); } - case 133: { + case 134: { return MakeUnique(); } - case 134: { + case 135: { return MakeUnique(); } - case 135: { + case 136: { return MakeUnique(); } - case 136: { + case 137: { return MakeUnique(); } - case 137: { + case 138: { return MakeUnique(); } - case 138: { + case 139: { return MakeUnique(); } - case 139: { + case 140: { return MakeUnique(); } - case 140: { + case 141: { return MakeUnique(); } - case 141: { + case 142: { return MakeUnique(); } - case 142: { + case 143: { return MakeUnique(); } - case 143: { + case 144: { return MakeUnique(); } - case 144: { + case 145: { return MakeUnique(); } - case 146: { + case 147: { return MakeUnique(); } #endif /* MOZ_UNIFFI_FIXTURES */