diff --git a/Jint/Jint.csproj b/Jint/Jint.csproj index 15e2e99349..52e1a8925b 100644 --- a/Jint/Jint.csproj +++ b/Jint/Jint.csproj @@ -38,6 +38,16 @@ + + + + + + + + + + diff --git a/Jint/Native/Intl/Data/CompactPatterns.cs b/Jint/Native/Intl/Data/CompactPatterns.cs new file mode 100644 index 0000000000..3e017b8953 --- /dev/null +++ b/Jint/Native/Intl/Data/CompactPatterns.cs @@ -0,0 +1,229 @@ +using System.IO; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR compact number patterns for locale-aware compact notation. +/// Data is loaded from embedded CompactPatterns.txt resource. +/// +internal static class CompactPatterns +{ + private static readonly object _lock = new object(); + private static Dictionary? _patterns; + private static volatile bool _loaded; + + /// + /// Gets compact patterns for a language code. + /// Falls back to English if not found. + /// + public static LocaleCompactData GetPatterns(string? language) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(language)) + { + // Try exact match first + if (_patterns!.TryGetValue(language!, out var data)) + { + return data; + } + + // Handle Chinese script variants + // zh-TW, zh-Hant-TW, zh-Hant, zh-HK, zh-MO → Traditional Chinese (zh-TW patterns) + // zh-CN, zh-Hans-CN, zh-Hans, zh-SG → Simplified Chinese (zh patterns) + if (language!.StartsWith("zh", StringComparison.OrdinalIgnoreCase)) + { + var isTraditional = language.Contains("-TW", StringComparison.OrdinalIgnoreCase) || + language.Contains("-HK", StringComparison.OrdinalIgnoreCase) || + language.Contains("-MO", StringComparison.OrdinalIgnoreCase) || + language.Contains("-Hant", StringComparison.OrdinalIgnoreCase); + var zhKey = isTraditional ? "zh-TW" : "zh"; + if (_patterns.TryGetValue(zhKey, out data)) + { + return data; + } + } + + // Try base language (e.g., "de" from "de-DE") + var dashIndex = language.IndexOf('-'); + if (dashIndex > 0) + { + var baseLang = language.Substring(0, dashIndex); + if (_patterns.TryGetValue(baseLang, out data)) + { + return data; + } + } + } + + // Fall back to English + return _patterns!.TryGetValue("en", out var enData) ? enData : LocaleCompactData.Default; + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _patterns = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(CompactPatterns).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.CompactPatterns.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentLang = null; + LocaleCompactData? currentData = null; + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + // Save previous locale data + if (currentLang != null && currentData != null) + { + _patterns[currentLang] = currentData; + } + + currentLang = line.Substring(1, line.Length - 2); + currentData = new LocaleCompactData(); + continue; + } + + if (currentData == null) + { + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + switch (key) + { + case "short_thousand": + currentData.ShortThousand = value; + break; + case "short_million": + currentData.ShortMillion = value; + break; + case "short_billion": + currentData.ShortBillion = value; + break; + case "short_trillion": + currentData.ShortTrillion = value; + break; + case "long_thousand": + currentData.LongThousand = value; + break; + case "long_million": + currentData.LongMillion = value; + break; + case "long_billion": + currentData.LongBillion = value; + break; + case "long_trillion": + currentData.LongTrillion = value; + break; + case "threshold": + if (long.TryParse(value, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out var threshold)) + { + currentData.Threshold = threshold; + } + break; + case "threshold_long": + if (long.TryParse(value, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out var thresholdLong)) + { + currentData.ThresholdLong = thresholdLong; + } + break; + case "divisor_million": + if (long.TryParse(value, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out var divMillion)) + { + currentData.DivisorMillion = divMillion; + } + break; + case "divisor_billion": + if (long.TryParse(value, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out var divBillion)) + { + currentData.DivisorBillion = divBillion; + } + break; + case "short_space": + currentData.ShortSpace = !string.Equals(value, "false", StringComparison.OrdinalIgnoreCase); + break; + case "long_space": + currentData.LongSpace = !string.Equals(value, "false", StringComparison.OrdinalIgnoreCase); + break; + } + } + + // Save last locale data + if (currentLang != null && currentData != null) + { + _patterns[currentLang] = currentData; + } + + _loaded = true; + } + } + + internal sealed class LocaleCompactData + { + public string ShortThousand { get; set; } = "K"; + public string ShortMillion { get; set; } = "M"; + public string ShortBillion { get; set; } = "B"; + public string ShortTrillion { get; set; } = "T"; + public string LongThousand { get; set; } = "thousand"; + public string LongMillion { get; set; } = "million"; + public string LongBillion { get; set; } = "billion"; + public string LongTrillion { get; set; } = "trillion"; + public long Threshold { get; set; } = 1000; + public long? ThresholdLong { get; set; } + public long DivisorMillion { get; set; } = 1_000_000; + public long DivisorBillion { get; set; } = 1_000_000_000; + public bool ShortSpace { get; set; } = true; // Default to true (has space) + public bool LongSpace { get; set; } = true; // Default to true (has space) + + /// + /// Gets the threshold to use based on display mode. + /// + public long GetThreshold(bool isLong) + { + if (isLong && ThresholdLong.HasValue) + { + return ThresholdLong.Value; + } + return Threshold; + } + + public static LocaleCompactData Default { get; } = new LocaleCompactData(); + } +} diff --git a/Jint/Native/Intl/Data/CompactPatterns.txt b/Jint/Native/Intl/Data/CompactPatterns.txt new file mode 100644 index 0000000000..db239121ee --- /dev/null +++ b/Jint/Native/Intl/Data/CompactPatterns.txt @@ -0,0 +1,149 @@ +[en] +short_thousand=K +short_million=M +short_billion=B +short_trillion=T +long_thousand=thousand +long_million=million +long_billion=billion +long_trillion=trillion +threshold=1000 +short_space=false + +[de] +short_thousand= +short_million=Mio. +short_billion=Mrd. +short_trillion=Bio. +long_thousand=Tausend +long_million=Millionen +long_billion=Milliarden +long_trillion=Billionen +threshold=1000000 +threshold_long=1000 + +[ja] +short_thousand= +short_million=万 +short_billion=億 +short_trillion=兆 +long_thousand= +long_million=万 +long_billion=億 +long_trillion=兆 +threshold=10000 +divisor_million=10000 +divisor_billion=100000000 +short_space=false +long_space=false + +[ko] +short_thousand=천 +short_million=만 +short_billion=억 +short_trillion=조 +long_thousand=천 +long_million=만 +long_billion=억 +long_trillion=조 +threshold=1000 +divisor_million=10000 +divisor_billion=100000000 +short_space=false +long_space=false + +[zh] +short_thousand= +short_million=万 +short_billion=亿 +short_trillion=兆 +long_thousand= +long_million=万 +long_billion=亿 +long_trillion=兆 +threshold=10000 +divisor_million=10000 +divisor_billion=100000000 +short_space=false +long_space=false + +[zh-TW] +short_thousand= +short_million=萬 +short_billion=億 +short_trillion=兆 +long_thousand= +long_million=萬 +long_billion=億 +long_trillion=兆 +threshold=10000 +divisor_million=10000 +divisor_billion=100000000 +short_space=false +long_space=false + +[fr] +short_thousand=k +short_million=M +short_billion=Md +short_trillion=Bn +long_thousand=millier +long_million=millions +long_billion=milliards +long_trillion=billions +threshold=1000 + +[es] +short_thousand=k +short_million=M +short_billion=mil M +short_trillion=B +long_thousand=mil +long_million=millones +long_billion=mil millones +long_trillion=billones +threshold=1000 + +[it] +short_thousand= +short_million=Mln +short_billion=Mrd +short_trillion=Bln +long_thousand=mila +long_million=milioni +long_billion=miliardi +long_trillion=bilioni +threshold=1000000 + +[pt] +short_thousand=mil +short_million=mi +short_billion=bi +short_trillion=tri +long_thousand=mil +long_million=milhões +long_billion=bilhões +long_trillion=trilhões +threshold=1000 + +[ru] +short_thousand=тыс. +short_million=млн +short_billion=млрд +short_trillion=трлн +long_thousand=тысяч +long_million=миллионов +long_billion=миллиардов +long_trillion=триллионов +threshold=1000 + +[ar] +short_thousand=ألف +short_million=مليون +short_billion=مليار +short_trillion=ترليون +long_thousand=ألف +long_million=مليون +long_billion=مليار +long_trillion=ترليون +threshold=1000 diff --git a/Jint/Native/Intl/Data/LikelySubtags.cs b/Jint/Native/Intl/Data/LikelySubtags.cs new file mode 100644 index 0000000000..a7f4fe1e09 --- /dev/null +++ b/Jint/Native/Intl/Data/LikelySubtags.cs @@ -0,0 +1,336 @@ +namespace Jint.Native.Intl.Data; + +/// +/// Implements CLDR Add Likely Subtags and Remove Likely Subtags algorithms. +/// https://www.unicode.org/reports/tr35/#Likely_Subtags +/// +internal static class LikelySubtags +{ + /// + /// Add Likely Subtags algorithm - maximizes a locale by adding likely script and region. + /// + public static string AddLikelySubtags(string locale) + { + var baseName = ExtractBaseName(locale); + var extension = locale.Length > baseName.Length ? locale.Substring(baseName.Length) : string.Empty; + ParseBaseName(baseName, out var language, out var script, out var region, out var variants); + var variantSuffix = BuildVariantSuffix(variants); + + // If already has all parts and language is not "und", return as-is + if (!RequiresReplacement(language) && !string.IsNullOrEmpty(script) && !string.IsNullOrEmpty(region)) + { + return baseName + extension; + } + + if (!TryResolve(language, script, region, out var resolved)) + { + return baseName + extension; + } + + var maximizedBase = resolved + variantSuffix; + return maximizedBase + extension; + } + + /// + /// Remove Likely Subtags algorithm - minimizes a locale by removing default script and region. + /// + public static string RemoveLikelySubtags(string locale) + { + var baseName = ExtractBaseName(locale); + var extension = locale.Length > baseName.Length ? locale.Substring(baseName.Length) : string.Empty; + ParseBaseName(baseName, out var language, out var script, out var region, out var variants); + var variantSuffix = BuildVariantSuffix(variants); + + // Build the base tag without variants for maximization comparison + var baseTagWithoutVariants = BuildBaseTag(language, script, region); + + // First maximize the locale (without variants for comparison) + var maximized = AddLikelySubtags(baseTagWithoutVariants); + var maximizedBase = ExtractBaseName(maximized); + ParseBaseName(maximizedBase, out var languageMax, out var scriptMax, out var regionMax, out _); + + // Build the maximized base without variants for comparison + var maximizedBaseTag = BuildBaseTag(languageMax, scriptMax, regionMax); + + // Try removing parts and check if re-maximizing gives the same result + foreach (var trial in EnumerateTrials(languageMax, scriptMax, regionMax)) + { + var trialMaximized = AddLikelySubtags(trial); + var trialBase = ExtractBaseName(trialMaximized); + // Parse to get just the base tag (no variants from trial) + ParseBaseName(trialBase, out var trialLang, out var trialScript, out var trialRegion, out _); + var trialBaseTag = BuildBaseTag(trialLang, trialScript, trialRegion); + + if (string.Equals(trialBaseTag, maximizedBaseTag, StringComparison.Ordinal)) + { + return trial + variantSuffix + extension; + } + } + + return maximizedBaseTag + variantSuffix + extension; + } + + private static IEnumerable EnumerateTrials(string? language, string? script, string? region) + { + // Try language only + if (!string.IsNullOrEmpty(language)) + { + yield return BuildBaseTag(language, null, null); + } + + // Try language + region (without script) + if (!string.IsNullOrEmpty(language) && !string.IsNullOrEmpty(region)) + { + yield return BuildBaseTag(language, null, region); + } + + // Try language + script (without region) + if (!string.IsNullOrEmpty(language) && !string.IsNullOrEmpty(script)) + { + yield return BuildBaseTag(language, script, null); + } + } + + private static bool TryResolve(string? language, string? script, string? region, out string resolved) + { + var lookupLanguage = NormalizeLanguage(language); + string? match = null; + + // Try lookup keys in order of specificity + foreach (var key in EnumerateLookupKeys(lookupLanguage, script, region)) + { + if (key is not null && LikelySubtagsData.TryResolve(key, out var candidate)) + { + match = candidate; + break; + } + } + + if (match is null) + { + resolved = string.Empty; + return false; + } + + ParseBaseName(match, out var matchLanguage, out var matchScript, out var matchRegion, out _); + var resolvedLanguage = RequiresReplacement(language) ? matchLanguage : lookupLanguage; + var resolvedScript = string.IsNullOrEmpty(script) ? matchScript : script; + var resolvedRegion = string.IsNullOrEmpty(region) ? matchRegion : region; + + resolved = BuildBaseTag(resolvedLanguage, resolvedScript, resolvedRegion); + return true; + } + + private static IEnumerable EnumerateLookupKeys(string? language, string? script, string? region) + { + // Most specific to least specific + yield return BuildBaseTag(language, script, region); + + if (!string.IsNullOrEmpty(script)) + { + yield return BuildBaseTag(language, script, null); + } + + if (!string.IsNullOrEmpty(region)) + { + yield return BuildBaseTag(language, null, region); + } + + yield return BuildBaseTag(language, null, null); + + // Also try "und" variants for script/region lookup + if (!string.Equals(language, "und", StringComparison.Ordinal)) + { + if (!string.IsNullOrEmpty(script) && !string.IsNullOrEmpty(region)) + { + yield return BuildBaseTag("und", script, region); + } + + if (!string.IsNullOrEmpty(script)) + { + yield return BuildBaseTag("und", script, null); + } + + if (!string.IsNullOrEmpty(region)) + { + yield return BuildBaseTag("und", null, region); + } + } + } + + private static bool RequiresReplacement(string? language) + { + return string.IsNullOrEmpty(language) || string.Equals(language, "und", StringComparison.Ordinal); + } + + private static string NormalizeLanguage(string? language) + { + return RequiresReplacement(language) ? "und" : language!; + } + + /// + /// Extracts the base name from a locale (everything before extensions). + /// + internal static string ExtractBaseName(string locale) + { + // Find the start of extensions (-u-, -t-, -x-, etc.) + var parts = locale.Split('-'); + var baseEndIndex = 0; + var currentPos = 0; + + for (var i = 0; i < parts.Length; i++) + { + if (parts[i].Length == 1 && i > 0) + { + // This is an extension singleton + break; + } + baseEndIndex = currentPos + parts[i].Length; + currentPos = baseEndIndex + 1; // +1 for the hyphen + } + + return locale.Substring(0, baseEndIndex); + } + + /// + /// Parses the base name into language, script, region, and variants. + /// + internal static void ParseBaseName(string baseName, out string? language, out string? script, out string? region, out List variants) + { + language = null; + script = null; + region = null; + variants = new List(); + + var parts = baseName.Split('-'); + if (parts.Length == 0) + { + return; + } + + var index = 0; + + // Language (2-3 or 4-8 letters) + if (index < parts.Length && parts[index].Length >= 2 && parts[index].Length <= 8 && IsAllLetters(parts[index])) + { + language = parts[index].ToLowerInvariant(); + index++; + } + + // Script (4 letters) + if (index < parts.Length && parts[index].Length == 4 && IsAllLetters(parts[index])) + { + script = char.ToUpperInvariant(parts[index][0]) + parts[index].Substring(1).ToLowerInvariant(); + index++; + } + + // Region (2 letters or 3 digits) + if (index < parts.Length && + ((parts[index].Length == 2 && IsAllLetters(parts[index])) || + (parts[index].Length == 3 && IsAllDigits(parts[index])))) + { + region = parts[index].ToUpperInvariant(); + index++; + } + + // Variants (5-8 alphanum or 4 chars starting with digit) + while (index < parts.Length && IsVariantSubtag(parts[index])) + { + variants.Add(parts[index].ToLowerInvariant()); + index++; + } + } + + /// + /// Builds a locale tag from components. + /// + internal static string BuildBaseTag(string? language, string? script, string? region) + { + if (string.IsNullOrEmpty(language)) + { + return string.Empty; + } + + var result = language!; + + if (!string.IsNullOrEmpty(script)) + { + result += "-" + script; + } + + if (!string.IsNullOrEmpty(region)) + { + result += "-" + region; + } + + return result; + } + + private static string BuildVariantSuffix(List variants) + { + if (variants.Count == 0) + { + return string.Empty; + } + + return "-" + string.Join("-", variants); + } + + private static bool IsAllLetters(string s) + { + foreach (var c in s) + { + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + { + return false; + } + } + return true; + } + + private static bool IsAllDigits(string s) + { + foreach (var c in s) + { + if (c < '0' || c > '9') + { + return false; + } + } + return true; + } + + private static bool IsVariantSubtag(string s) + { + if (string.IsNullOrEmpty(s) || s.Length == 1) + { + return false; + } + + // 4 characters starting with digit + if (s.Length == 4 && s[0] >= '0' && s[0] <= '9') + { + return IsAllAlphanumeric(s); + } + + // 5-8 alphanumeric characters + if (s.Length >= 5 && s.Length <= 8) + { + return IsAllAlphanumeric(s); + } + + return false; + } + + private static bool IsAllAlphanumeric(string s) + { + foreach (var c in s) + { + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))) + { + return false; + } + } + return true; + } +} diff --git a/Jint/Native/Intl/Data/LikelySubtags.txt b/Jint/Native/Intl/Data/LikelySubtags.txt new file mode 100644 index 0000000000..f7ce6b6004 --- /dev/null +++ b/Jint/Native/Intl/Data/LikelySubtags.txt @@ -0,0 +1,7745 @@ +aa=aa-Latn-ET +aaa=aaa-Latn-NG +aab=aab-Latn-NG +aac=aac-Latn-PG +aad=aad-Latn-PG +aae=aae-Latn-IT +aaf=aaf-Mlym-IN +aag=aag-Latn-PG +aah=aah-Latn-PG +aai=aai-Latn-PG +aak=aak-Latn-PG +aal=aal-Latn-CM +aan=aan-Latn-BR +aao=aao-Arab-DZ +aap=aap-Latn-BR +aaq=aaq-Latn-US +aas=aas-Latn-TZ +aat=aat-Grek-GR +aau=aau-Latn-PG +aaw=aaw-Latn-PG +aax=aax-Latn-ID +aaz=aaz-Latn-ID +ab=ab-Cyrl-GE +aba=aba-Latn-CI +abb=abb-Latn-CM +abc=abc-Latn-PH +abd=abd-Latn-PH +abe=abe-Latn-CA +abf=abf-Latn-MY +abg=abg-Latn-PG +abh=abh-Arab-TJ +abi=abi-Latn-CI +abl=abl-Rjng-ID +abm=abm-Latn-NG +abn=abn-Latn-NG +abo=abo-Latn-NG +abp=abp-Latn-PH +abr=abr-Latn-GH +abs=abs-Latn-ID +abt=abt-Latn-PG +abu=abu-Latn-CI +abv=abv-Arab-BH +abw=abw-Latn-PG +abx=abx-Latn-PH +aby=aby-Latn-PG +abz=abz-Latn-ID +aca=aca-Latn-CO +acb=acb-Latn-NG +acd=acd-Latn-GH +ace=ace-Latn-ID +acf=acf-Latn-LC +ach=ach-Latn-UG +acm=acm-Arab-IQ +acn=acn-Latn-CN +acp=acp-Latn-NG +acq=acq-Arab-YE +acr=acr-Latn-GT +acs=acs-Latn-BR +act=act-Latn-NL +acu=acu-Latn-EC +acv=acv-Latn-US +acw=acw-Arab-SA +acx=acx-Arab-OM +acy=acy-Latn-CY +acz=acz-Latn-SD +ada=ada-Latn-GH +adb=adb-Latn-TL +add=add-Latn-CM +ade=ade-Latn-TG +adf=adf-Arab-OM +adg=adg-Latn-AU +adh=adh-Latn-UG +adi=adi-Latn-IN +adj=adj-Latn-CI +adl=adl-Latn-IN +adn=adn-Latn-ID +ado=ado-Latn-PG +adq=adq-Latn-GH +adr=adr-Latn-ID +adt=adt-Latn-AU +adu=adu-Latn-NG +adw=adw-Latn-BR +adx=adx-Tibt-CN +ady=ady-Cyrl-RU +adz=adz-Latn-PG +ae=ae-Avst-IR +aea=aea-Latn-AU +aeb=aeb-Arab-TN +aec=aec-Arab-EG +aee=aee-Arab-AF +aek=aek-Latn-NC +ael=ael-Latn-CM +aem=aem-Latn-VN +aeq=aeq-Arab-PK +aer=aer-Latn-AU +aeu=aeu-Latn-CN +aew=aew-Latn-PG +aey=aey-Latn-PG +aez=aez-Latn-PG +af=af-Latn-ZA +afb=afb-Arab-KW +afd=afd-Latn-PG +afe=afe-Latn-NG +afh=afh-Latn-GH +afi=afi-Latn-PG +afk=afk-Latn-PG +afn=afn-Latn-NG +afo=afo-Latn-NG +afp=afp-Latn-PG +afs=afs-Latn-MX +afu=afu-Latn-GH +afz=afz-Latn-ID +aga=aga-Latn-PE +agb=agb-Latn-NG +agc=agc-Latn-NG +agd=agd-Latn-PG +age=age-Latn-PG +agf=agf-Latn-ID +agg=agg-Latn-PG +agh=agh-Latn-CD +agi=agi-Deva-IN +agj=agj-Ethi-ET +agk=agk-Latn-PH +agl=agl-Latn-PG +agm=agm-Latn-PG +agn=agn-Latn-PH +ago=ago-Latn-PG +agq=agq-Latn-CM +agr=agr-Latn-PE +ags=ags-Latn-CM +agt=agt-Latn-PH +agu=agu-Latn-GT +agv=agv-Latn-PH +agw=agw-Latn-SB +agx=agx-Cyrl-RU +agy=agy-Latn-PH +agz=agz-Latn-PH +aha=aha-Latn-GH +ahb=ahb-Latn-VU +ahg=ahg-Ethi-ET +ahh=ahh-Latn-ID +ahi=ahi-Latn-CI +ahk=ahk-Latn-MM +ahl=ahl-Latn-TG +ahm=ahm-Latn-CI +ahn=ahn-Latn-NG +aho=aho-Ahom-IN +ahp=ahp-Latn-CI +ahr=ahr-Deva-IN +ahs=ahs-Latn-NG +aht=aht-Latn-US +aia=aia-Latn-SB +aib=aib-Arab-CN +aic=aic-Latn-PG +aid=aid-Latn-AU +aie=aie-Latn-PG +aif=aif-Latn-PG +aig=aig-Latn-AG +aii=aii-Syrc-IQ +aij=aij-Hebr-IL +aik=aik-Latn-NG +ail=ail-Latn-PG +aim=aim-Latn-IN +ain=ain-Kana-JP +aio=aio-Mymr-IN +aip=aip-Latn-ID +aiq=aiq-Arab-AF +air=air-Latn-ID +ait=ait-Latn-BR +aiw=aiw-Latn-ET +aix=aix-Latn-PG +aiy=aiy-Latn-CF +aja=aja-Latn-SS +ajg=ajg-Latn-BJ +aji=aji-Latn-NC +ajn=ajn-Latn-AU +ajw=ajw-Latn-NG +ajz=ajz-Latn-IN +ak=ak-Latn-GH +akb=akb-Latn-ID +akc=akc-Latn-ID +akd=akd-Latn-NG +ake=ake-Latn-GY +akf=akf-Latn-NG +akg=akg-Latn-ID +akh=akh-Latn-PG +aki=aki-Latn-PG +akk=akk-Xsux-IQ +akl=akl-Latn-PH +ako=ako-Latn-SR +akp=akp-Latn-GH +akq=akq-Latn-PG +akr=akr-Latn-VU +aks=aks-Latn-TG +akt=akt-Latn-PG +aku=aku-Latn-CM +akv=akv-Cyrl-RU +akw=akw-Latn-CG +akz=akz-Latn-US +ala=ala-Latn-NG +alc=alc-Latn-CL +ald=ald-Latn-CI +ale=ale-Latn-US +alf=alf-Latn-NG +alh=alh-Latn-AU +ali=ali-Latn-PG +alj=alj-Latn-PH +alk=alk-Laoo-LA +all=all-Mlym-IN +alm=alm-Latn-VU +aln=aln-Latn-XK +alo=alo-Latn-ID +alp=alp-Latn-ID +alq=alq-Latn-CA +alr=alr-Cyrl-RU +alt=alt-Cyrl-RU +alu=alu-Latn-SB +alw=alw-Ethi-ET +alx=alx-Latn-PG +aly=aly-Latn-AU +alz=alz-Latn-CD +am=am-Ethi-ET +ama=ama-Latn-BR +amb=amb-Latn-NG +amc=amc-Latn-PE +ame=ame-Latn-PE +amf=amf-Latn-ET +amg=amg-Latn-AU +ami=ami-Latn-TW +amj=amj-Latn-TD +amk=amk-Latn-ID +amm=amm-Latn-PG +amn=amn-Latn-PG +amo=amo-Latn-NG +amp=amp-Latn-PG +amq=amq-Latn-ID +amr=amr-Latn-PE +ams=ams-Jpan-JP +amt=amt-Latn-PG +amu=amu-Latn-MX +amv=amv-Latn-ID +amw=amw-Syrc-SY +amx=amx-Latn-AU +amy=amy-Latn-AU +amz=amz-Latn-AU +an=an-Latn-ES +ana=ana-Latn-CO +anb=anb-Latn-PE +anc=anc-Latn-NG +and=and-Latn-ID +ane=ane-Latn-NC +anf=anf-Latn-GH +ang=ang-Latn-GB +anh=anh-Latn-PG +ani=ani-Cyrl-RU +anj=anj-Latn-PG +ank=ank-Latn-NG +anl=anl-Latn-MM +anm=anm-Latn-IN +ann=ann-Latn-NG +ano=ano-Latn-CO +anp=anp-Deva-IN +anq=anq-Deva-IN +anr=anr-Deva-IN +ans=ans-Latn-CO +ant=ant-Latn-AU +anu=anu-Ethi-ET +anv=anv-Latn-CM +anw=anw-Latn-NG +anx=anx-Latn-PG +any=any-Latn-CI +anz=anz-Latn-PG +aoa=aoa-Latn-ST +aob=aob-Latn-PG +aoc=aoc-Latn-VE +aod=aod-Latn-PG +aoe=aoe-Latn-PG +aof=aof-Latn-PG +aog=aog-Latn-PG +aoi=aoi-Latn-AU +aoj=aoj-Latn-PG +aok=aok-Latn-NC +aol=aol-Latn-ID +aom=aom-Latn-PG +aon=aon-Latn-PG +aor=aor-Latn-VU +aos=aos-Latn-ID +aot=aot-Beng-BD +aox=aox-Latn-GY +aoz=aoz-Latn-ID +apb=apb-Latn-SB +apc=apc-Arab-SY +apd=apd-Arab-SD +ape=ape-Latn-PG +apf=apf-Latn-PH +apg=apg-Latn-ID +aph=aph-Deva-NP +api=api-Latn-BR +apj=apj-Latn-US +apk=apk-Latn-US +apl=apl-Latn-US +apm=apm-Latn-US +apn=apn-Latn-BR +apo=apo-Latn-PG +app=app-Latn-VU +apr=apr-Latn-PG +aps=aps-Latn-PG +apt=apt-Latn-IN +apu=apu-Latn-BR +apv=apv-Latn-BR +apw=apw-Latn-US +apx=apx-Latn-ID +apy=apy-Latn-BR +apz=apz-Latn-PG +aqc=aqc-Cyrl-RU +aqd=aqd-Latn-ML +aqg=aqg-Latn-NG +aqk=aqk-Latn-NG +aqm=aqm-Latn-ID +aqn=aqn-Latn-PH +aqr=aqr-Latn-NC +aqt=aqt-Latn-PY +aqz=aqz-Latn-BR +ar=ar-Arab-EG +arc=arc-Armi-IR +arc-Hatr=arc-Hatr-IQ +arc-Nbat=arc-Nbat-JO +arc-Palm=arc-Palm-SY +ard=ard-Latn-AU +are=are-Latn-AU +arh=arh-Latn-CO +ari=ari-Latn-US +arj=arj-Latn-BR +ark=ark-Latn-BR +arl=arl-Latn-PE +arn=arn-Latn-CL +aro=aro-Latn-BO +arp=arp-Latn-US +arq=arq-Arab-DZ +arr=arr-Latn-BR +ars=ars-Arab-SA +aru=aru-Latn-BR +arw=arw-Latn-SR +arx=arx-Latn-BR +ary=ary-Arab-MA +arz=arz-Arab-EG +as=as-Beng-IN +asa=asa-Latn-TZ +asb=asb-Latn-CA +asc=asc-Latn-ID +ase=ase-Sgnw-US +asg=asg-Latn-NG +ash=ash-Latn-PE +asi=asi-Latn-ID +asj=asj-Latn-CM +ask=ask-Arab-AF +asl=asl-Latn-ID +asn=asn-Latn-BR +aso=aso-Latn-PG +asr=asr-Deva-IN +ass=ass-Latn-CM +ast=ast-Latn-ES +asu=asu-Latn-BR +asv=asv-Latn-CD +asx=asx-Latn-PG +asy=asy-Latn-ID +asz=asz-Latn-ID +ata=ata-Latn-PG +atb=atb-Latn-CN +atc=atc-Latn-PE +atd=atd-Latn-PH +ate=ate-Latn-PG +atg=atg-Latn-NG +ati=ati-Latn-CI +atj=atj-Latn-CA +atk=atk-Latn-PH +atl=atl-Latn-PH +atm=atm-Latn-PH +atn=atn-Arab-IR +ato=ato-Latn-CM +atp=atp-Latn-PH +atq=atq-Latn-ID +atr=atr-Latn-BR +ats=ats-Latn-US +att=att-Latn-PH +atu=atu-Latn-SS +atv=atv-Cyrl-RU +atw=atw-Latn-US +atx=atx-Latn-BR +aty=aty-Latn-VU +atz=atz-Latn-PH +aua=aua-Latn-SB +auc=auc-Latn-EC +aud=aud-Latn-SB +aug=aug-Latn-BJ +auh=auh-Latn-ZM +aui=aui-Latn-PG +auj=auj-Arab-LY +auk=auk-Latn-PG +aul=aul-Latn-VU +aum=aum-Latn-NG +aun=aun-Latn-PG +auo=auo-Latn-NG +aup=aup-Latn-PG +auq=auq-Latn-ID +aur=aur-Latn-PG +aut=aut-Latn-PF +auu=auu-Latn-ID +auw=auw-Latn-ID +auy=auy-Latn-PG +auz=auz-Arab-UZ +av=av-Cyrl-RU +avb=avb-Latn-PG +avd=avd-Arab-IR +avi=avi-Latn-CI +avk=avk-Latn-001 +avl=avl-Arab-EG +avm=avm-Latn-AU +avn=avn-Latn-GH +avo=avo-Latn-BR +avs=avs-Latn-PE +avt=avt-Latn-PG +avu=avu-Latn-SS +avv=avv-Latn-BR +awa=awa-Deva-IN +awb=awb-Latn-PG +awc=awc-Latn-NG +awe=awe-Latn-BR +awg=awg-Latn-AU +awh=awh-Latn-ID +awi=awi-Latn-PG +awk=awk-Latn-AU +awm=awm-Latn-PG +awn=awn-Ethi-ET +awo=awo-Latn-NG +awr=awr-Latn-ID +aws=aws-Latn-ID +awt=awt-Latn-BR +awu=awu-Latn-ID +awv=awv-Latn-ID +aww=aww-Latn-PG +awx=awx-Latn-PG +awy=awy-Latn-ID +axb=axb-Latn-AR +axe=axe-Latn-AU +axg=axg-Latn-BR +axk=axk-Latn-CF +axl=axl-Latn-AU +axm=axm-Armn-AM +axx=axx-Latn-NC +ay=ay-Latn-BO +aya=aya-Latn-PG +ayb=ayb-Latn-BJ +ayc=ayc-Latn-PE +ayd=ayd-Latn-AU +aye=aye-Latn-NG +ayg=ayg-Latn-TG +ayh=ayh-Arab-YE +ayi=ayi-Latn-NG +ayk=ayk-Latn-NG +ayl=ayl-Arab-LY +ayn=ayn-Arab-YE +ayo=ayo-Latn-PY +ayp=ayp-Arab-IQ +ayq=ayq-Latn-PG +ays=ays-Latn-PH +ayt=ayt-Latn-PH +ayu=ayu-Latn-NG +ayz=ayz-Latn-ID +az=az-Latn-AZ +az-Arab=az-Arab-IR +az-IQ=az-Arab-IQ +az-IR=az-Arab-IR +az-RU=az-Cyrl-RU +azb=azb-Arab-IR +azd=azd-Latn-MX +azg=azg-Latn-MX +azm=azm-Latn-MX +azn=azn-Latn-MX +azo=azo-Latn-CM +azt=azt-Latn-PH +azz=azz-Latn-MX +ba=ba-Cyrl-RU +baa=baa-Latn-SB +bab=bab-Latn-GW +bac=bac-Latn-ID +bae=bae-Latn-VE +baf=baf-Latn-CM +bag=bag-Latn-CM +bah=bah-Latn-BS +baj=baj-Latn-ID +bal=bal-Arab-PK +ban=ban-Latn-ID +bao=bao-Latn-CO +bap=bap-Deva-NP +bap-Krai=bap-Krai-IN +bar=bar-Latn-AT +bas=bas-Latn-CM +bau=bau-Latn-NG +bav=bav-Latn-CM +baw=baw-Latn-CM +bax=bax-Bamu-CM +bay=bay-Latn-ID +bba=bba-Latn-BJ +bbb=bbb-Latn-PG +bbc=bbc-Latn-ID +bbd=bbd-Latn-PG +bbe=bbe-Latn-CD +bbf=bbf-Latn-PG +bbg=bbg-Latn-GA +bbi=bbi-Latn-CM +bbj=bbj-Latn-CM +bbk=bbk-Latn-CM +bbl=bbl-Geor-GE +bbm=bbm-Latn-CD +bbn=bbn-Latn-PG +bbo=bbo-Latn-BF +bbp=bbp-Latn-CF +bbq=bbq-Latn-CM +bbr=bbr-Latn-PG +bbs=bbs-Latn-NG +bbt=bbt-Latn-NG +bbu=bbu-Latn-NG +bbv=bbv-Latn-PG +bbw=bbw-Latn-CM +bbx=bbx-Latn-CM +bby=bby-Latn-CM +bca=bca-Latn-CN +bcb=bcb-Latn-SN +bcd=bcd-Latn-ID +bce=bce-Latn-CM +bcf=bcf-Latn-PG +bcg=bcg-Latn-GN +bch=bch-Latn-PG +bci=bci-Latn-CI +bcj=bcj-Latn-AU +bck=bck-Latn-AU +bcm=bcm-Latn-PG +bcn=bcn-Latn-NG +bco=bco-Latn-PG +bcp=bcp-Latn-CD +bcq=bcq-Ethi-ET +bcr=bcr-Latn-CA +bcs=bcs-Latn-NG +bct=bct-Latn-CD +bcu=bcu-Latn-PG +bcv=bcv-Latn-NG +bcw=bcw-Latn-CM +bcy=bcy-Latn-NG +bcz=bcz-Latn-SN +bda=bda-Latn-SN +bdb=bdb-Latn-ID +bdc=bdc-Latn-CO +bdd=bdd-Latn-PG +bde=bde-Latn-NG +bdf=bdf-Latn-PG +bdg=bdg-Latn-MY +bdh=bdh-Latn-SS +bdi=bdi-Latn-SD +bdj=bdj-Latn-SS +bdk=bdk-Latn-AZ +bdl=bdl-Latn-ID +bdm=bdm-Latn-TD +bdn=bdn-Latn-CM +bdo=bdo-Latn-TD +bdp=bdp-Latn-TZ +bdq=bdq-Latn-VN +bdr=bdr-Latn-MY +bds=bds-Latn-TZ +bdt=bdt-Latn-CF +bdu=bdu-Latn-CM +bdv=bdv-Orya-IN +bdw=bdw-Latn-ID +bdx=bdx-Latn-ID +bdy=bdy-Latn-AU +bdz=bdz-Arab-PK +be=be-Cyrl-BY +bea=bea-Latn-CA +beb=beb-Latn-CM +bec=bec-Latn-CM +bed=bed-Latn-ID +bee=bee-Deva-IN +bef=bef-Latn-PG +beh=beh-Latn-BJ +bei=bei-Latn-ID +bej=bej-Arab-SD +bek=bek-Latn-PG +bem=bem-Latn-ZM +beo=beo-Latn-PG +bep=bep-Latn-ID +beq=beq-Latn-CG +bes=bes-Latn-TD +bet=bet-Latn-CI +beu=beu-Latn-ID +bev=bev-Latn-CI +bew=bew-Latn-ID +bex=bex-Latn-SS +bey=bey-Latn-PG +bez=bez-Latn-TZ +bfa=bfa-Latn-SS +bfb=bfb-Deva-IN +bfc=bfc-Latn-CN +bfd=bfd-Latn-CM +bfe=bfe-Latn-ID +bff=bff-Latn-CF +bfg=bfg-Latn-ID +bfh=bfh-Latn-PG +bfj=bfj-Latn-CM +bfl=bfl-Latn-CF +bfm=bfm-Latn-CM +bfn=bfn-Latn-TL +bfo=bfo-Latn-BF +bfp=bfp-Latn-CM +bfq=bfq-Taml-IN +bfs=bfs-Latn-CN +bft=bft-Arab-PK +bfu=bfu-Tibt-IN +bfw=bfw-Orya-IN +bfx=bfx-Latn-PH +bfy=bfy-Deva-IN +bfz=bfz-Deva-IN +bg=bg-Cyrl-BG +bga=bga-Latn-NG +bgb=bgb-Latn-ID +bgc=bgc-Deva-IN +bgd=bgd-Deva-IN +bgf=bgf-Latn-CM +bgg=bgg-Latn-IN +bgi=bgi-Latn-PH +bgj=bgj-Latn-CM +bgn=bgn-Arab-PK +bgo=bgo-Latn-GN +bgp=bgp-Arab-PK +bgq=bgq-Deva-IN +bgr=bgr-Latn-IN +bgs=bgs-Latn-PH +bgt=bgt-Latn-SB +bgu=bgu-Latn-NG +bgv=bgv-Latn-ID +bgw=bgw-Deva-IN +bgx=bgx-Grek-TR +bgy=bgy-Latn-ID +bgz=bgz-Latn-ID +bha=bha-Deva-IN +bhb=bhb-Deva-IN +bhc=bhc-Latn-ID +bhd=bhd-Deva-IN +bhe=bhe-Arab-PK +bhf=bhf-Latn-PG +bhg=bhg-Latn-PG +bhh=bhh-Cyrl-IL +bhi=bhi-Deva-IN +bhj=bhj-Deva-NP +bhl=bhl-Latn-PG +bhm=bhm-Arab-OM +bhn=bhn-Syrc-GE +bho=bho-Deva-IN +bhp=bhp-Latn-ID +bhq=bhq-Latn-ID +bhr=bhr-Latn-MG +bhs=bhs-Latn-CM +bht=bht-Deva-IN +bhu=bhu-Deva-IN +bhv=bhv-Latn-ID +bhw=bhw-Latn-ID +bhy=bhy-Latn-CD +bhz=bhz-Latn-ID +bi=bi-Latn-VU +bia=bia-Latn-AU +bib=bib-Latn-BF +bid=bid-Latn-TD +bie=bie-Latn-PG +bif=bif-Latn-GW +big=big-Latn-PG +bik=bik-Latn-PH +bil=bil-Latn-NG +bim=bim-Latn-GH +bin=bin-Latn-NG +bio=bio-Latn-PG +bip=bip-Latn-CD +biq=biq-Latn-PG +bir=bir-Latn-PG +bit=bit-Latn-PG +biu=biu-Latn-IN +biv=biv-Latn-GH +biw=biw-Latn-CM +biy=biy-Deva-IN +biz=biz-Latn-CD +bja=bja-Latn-CD +bjb=bjb-Latn-AU +bjc=bjc-Latn-PG +bjf=bjf-Syrc-IL +bjg=bjg-Latn-GW +bjh=bjh-Latn-PG +bji=bji-Latn-ET +bjj=bjj-Deva-IN +bjk=bjk-Latn-PG +bjl=bjl-Latn-PG +bjm=bjm-Arab-IQ +bjn=bjn-Latn-ID +bjo=bjo-Latn-CF +bjp=bjp-Latn-PG +bjr=bjr-Latn-PG +bjs=bjs-Latn-BB +bjt=bjt-Latn-SN +bju=bju-Latn-CM +bjv=bjv-Latn-TD +bjw=bjw-Latn-CI +bjx=bjx-Latn-PH +bjy=bjy-Latn-AU +bjz=bjz-Latn-PG +bka=bka-Latn-NG +bkc=bkc-Latn-CM +bkd=bkd-Latn-PH +bkf=bkf-Latn-CD +bkg=bkg-Latn-CF +bkh=bkh-Latn-CM +bki=bki-Latn-VU +bkj=bkj-Latn-CF +bkk=bkk-Tibt-IN +bkl=bkl-Latn-ID +bkm=bkm-Latn-CM +bkn=bkn-Latn-ID +bko=bko-Latn-CM +bkp=bkp-Latn-CD +bkq=bkq-Latn-BR +bkr=bkr-Latn-ID +bks=bks-Latn-PH +bkt=bkt-Latn-CD +bku=bku-Latn-PH +bkv=bkv-Latn-NG +bkw=bkw-Latn-CG +bkx=bkx-Latn-TL +bky=bky-Latn-NG +bkz=bkz-Latn-ID +bla=bla-Latn-CA +blb=blb-Latn-SB +blc=blc-Latn-CA +bld=bld-Latn-ID +ble=ble-Latn-GW +blf=blf-Latn-ID +blh=blh-Latn-LR +bli=bli-Latn-CD +blj=blj-Latn-ID +blk=blk-Mymr-MM +blm=blm-Latn-SS +bln=bln-Latn-PH +blo=blo-Latn-BJ +blp=blp-Latn-SB +blq=blq-Latn-PG +blr=blr-Latn-CN +bls=bls-Latn-ID +blt=blt-Tavt-VN +blv=blv-Latn-AO +blw=blw-Latn-PH +blx=blx-Latn-PH +bly=bly-Latn-BJ +blz=blz-Latn-ID +bm=bm-Latn-ML +bma=bma-Latn-NG +bmb=bmb-Latn-CD +bmc=bmc-Latn-PG +bmd=bmd-Latn-GN +bme=bme-Latn-CF +bmf=bmf-Latn-SL +bmg=bmg-Latn-CD +bmh=bmh-Latn-PG +bmi=bmi-Latn-TD +bmj=bmj-Deva-NP +bmk=bmk-Latn-PG +bml=bml-Latn-CD +bmm=bmm-Latn-MG +bmn=bmn-Latn-PG +bmo=bmo-Latn-CM +bmp=bmp-Latn-PG +bmq=bmq-Latn-ML +bmr=bmr-Latn-CO +bms=bms-Latn-NE +bmu=bmu-Latn-PG +bmv=bmv-Latn-CM +bmw=bmw-Latn-CG +bmx=bmx-Latn-PG +bmz=bmz-Latn-PG +bn=bn-Beng-BD +bna=bna-Latn-ID +bnb=bnb-Latn-MY +bnc=bnc-Latn-PH +bnd=bnd-Latn-ID +bne=bne-Latn-ID +bnf=bnf-Latn-ID +bng=bng-Latn-GQ +bni=bni-Latn-CD +bnj=bnj-Latn-PH +bnk=bnk-Latn-VU +bnm=bnm-Latn-GQ +bnn=bnn-Latn-TW +bno=bno-Latn-PH +bnp=bnp-Latn-PG +bnq=bnq-Latn-ID +bnr=bnr-Latn-VU +bns=bns-Deva-IN +bnu=bnu-Latn-ID +bnv=bnv-Latn-ID +bnw=bnw-Latn-PG +bnx=bnx-Latn-CD +bny=bny-Latn-MY +bnz=bnz-Latn-CM +bo=bo-Tibt-CN +boa=boa-Latn-PE +bob=bob-Latn-KE +boe=boe-Latn-CM +bof=bof-Latn-BF +boh=boh-Latn-CD +boj=boj-Latn-PG +bok=bok-Latn-CG +bol=bol-Latn-NG +bom=bom-Latn-NG +bon=bon-Latn-PG +boo=boo-Latn-ML +bop=bop-Latn-PG +boq=boq-Latn-PG +bor=bor-Latn-BR +bot=bot-Latn-SS +bou=bou-Latn-TZ +bov=bov-Latn-GH +bow=bow-Latn-PG +box=box-Latn-BF +boy=boy-Latn-CF +boz=boz-Latn-ML +bpa=bpa-Latn-VU +bpc=bpc-Latn-CM +bpd=bpd-Latn-CF +bpe=bpe-Latn-PG +bpg=bpg-Latn-ID +bph=bph-Cyrl-RU +bpi=bpi-Latn-PG +bpj=bpj-Latn-CD +bpk=bpk-Latn-NC +bpl=bpl-Latn-AU +bpm=bpm-Latn-PG +bpo=bpo-Latn-ID +bpp=bpp-Latn-ID +bpq=bpq-Latn-ID +bpr=bpr-Latn-PH +bps=bps-Latn-PH +bpt=bpt-Latn-AU +bpu=bpu-Latn-PG +bpv=bpv-Latn-ID +bpw=bpw-Latn-PG +bpx=bpx-Deva-IN +bpy=bpy-Beng-IN +bpz=bpz-Latn-ID +bqa=bqa-Latn-BJ +bqb=bqb-Latn-ID +bqc=bqc-Latn-BJ +bqd=bqd-Latn-CM +bqf=bqf-Latn-GN +bqg=bqg-Latn-TG +bqi=bqi-Arab-IR +bqj=bqj-Latn-SN +bqk=bqk-Latn-CF +bql=bql-Latn-PG +bqm=bqm-Latn-CM +bqo=bqo-Latn-CM +bqp=bqp-Latn-NG +bqq=bqq-Latn-ID +bqr=bqr-Latn-ID +bqs=bqs-Latn-PG +bqt=bqt-Latn-CM +bqu=bqu-Latn-CD +bqv=bqv-Latn-CI +bqw=bqw-Latn-NG +bqx=bqx-Latn-NG +bqz=bqz-Latn-CM +br=br-Latn-FR +bra=bra-Deva-IN +brb=brb-Khmr-KH +brc=brc-Latn-GY +brd=brd-Deva-NP +brf=brf-Latn-CD +brg=brg-Latn-BO +brh=brh-Arab-PK +bri=bri-Latn-CM +brj=brj-Latn-VU +brk=brk-Arab-SD +brl=brl-Latn-BW +brm=brm-Latn-CD +brn=brn-Latn-CR +bro=bro-Tibt-BT +brp=brp-Latn-ID +brq=brq-Latn-PG +brr=brr-Latn-SB +brs=brs-Latn-ID +brt=brt-Latn-NG +bru=bru-Latn-VN +brv=brv-Laoo-LA +brw=brw-Knda-IN +brx=brx-Deva-IN +bry=bry-Latn-PG +brz=brz-Latn-PG +bs=bs-Latn-BA +bsa=bsa-Latn-ID +bsb=bsb-Latn-BN +bsc=bsc-Latn-SN +bse=bse-Latn-CM +bsf=bsf-Latn-NG +bsh=bsh-Arab-AF +bsi=bsi-Latn-CM +bsj=bsj-Latn-NG +bsk=bsk-Arab-PK +bsl=bsl-Latn-NG +bsm=bsm-Latn-ID +bsn=bsn-Latn-CO +bso=bso-Latn-TD +bsp=bsp-Latn-GN +bsq=bsq-Bass-LR +bsr=bsr-Latn-NG +bss=bss-Latn-CM +bst=bst-Ethi-ET +bsu=bsu-Latn-ID +bsv=bsv-Latn-GN +bsw=bsw-Latn-ET +bsx=bsx-Latn-NG +bsy=bsy-Latn-MY +bta=bta-Latn-NG +btc=btc-Latn-CM +btd=btd-Batk-ID +bte=bte-Latn-NG +btf=btf-Latn-TD +btg=btg-Latn-CI +bth=bth-Latn-MY +bti=bti-Latn-ID +btj=btj-Latn-ID +btm=btm-Batk-ID +btn=btn-Latn-PH +bto=bto-Latn-PH +btp=btp-Latn-PG +btq=btq-Latn-MY +btr=btr-Latn-VU +bts=bts-Latn-ID +btt=btt-Latn-NG +btu=btu-Latn-NG +btv=btv-Deva-PK +btw=btw-Latn-PH +btx=btx-Latn-ID +bty=bty-Latn-ID +btz=btz-Latn-ID +bua=bua-Cyrl-RU +bub=bub-Latn-TD +buc=buc-Latn-YT +bud=bud-Latn-TG +bue=bue-Latn-CA +buf=buf-Latn-CD +bug=bug-Latn-ID +buh=buh-Latn-CN +bui=bui-Latn-CG +buj=buj-Latn-NG +buk=buk-Latn-PG +bum=bum-Latn-CM +bun=bun-Latn-SL +buo=buo-Latn-PG +bup=bup-Latn-ID +buq=buq-Latn-PG +bus=bus-Latn-NG +but=but-Latn-PG +buu=buu-Latn-CD +buv=buv-Latn-PG +buw=buw-Latn-GA +bux=bux-Latn-NG +buy=buy-Latn-SL +buz=buz-Latn-NG +bva=bva-Latn-TD +bvb=bvb-Latn-GQ +bvc=bvc-Latn-SB +bvd=bvd-Latn-SB +bve=bve-Latn-ID +bvf=bvf-Latn-TD +bvg=bvg-Latn-CM +bvh=bvh-Latn-NG +bvi=bvi-Latn-SS +bvj=bvj-Latn-NG +bvk=bvk-Latn-ID +bvm=bvm-Latn-CM +bvn=bvn-Latn-PG +bvo=bvo-Latn-TD +bvq=bvq-Latn-CF +bvr=bvr-Latn-AU +bvt=bvt-Latn-ID +bvu=bvu-Latn-ID +bvv=bvv-Latn-VE +bvw=bvw-Latn-NG +bvx=bvx-Latn-CG +bvy=bvy-Latn-PH +bvz=bvz-Latn-ID +bwa=bwa-Latn-NC +bwb=bwb-Latn-FJ +bwc=bwc-Latn-ZM +bwd=bwd-Latn-PG +bwe=bwe-Mymr-MM +bwf=bwf-Latn-PG +bwg=bwg-Latn-MZ +bwh=bwh-Latn-CM +bwi=bwi-Latn-VE +bwj=bwj-Latn-BF +bwk=bwk-Latn-PG +bwl=bwl-Latn-CD +bwm=bwm-Latn-PG +bwo=bwo-Latn-ET +bwp=bwp-Latn-ID +bwq=bwq-Latn-BF +bwr=bwr-Latn-NG +bws=bws-Latn-CD +bwt=bwt-Latn-CM +bwu=bwu-Latn-GH +bww=bww-Latn-CD +bwx=bwx-Latn-CN +bwy=bwy-Latn-BF +bwz=bwz-Latn-CG +bxa=bxa-Latn-SB +bxb=bxb-Latn-SS +bxc=bxc-Latn-GQ +bxf=bxf-Latn-PG +bxg=bxg-Latn-CD +bxh=bxh-Latn-PG +bxi=bxi-Latn-AU +bxj=bxj-Latn-AU +bxl=bxl-Latn-BF +bxm=bxm-Cyrl-MN +bxn=bxn-Latn-AU +bxo=bxo-Latn-NG +bxp=bxp-Latn-CM +bxq=bxq-Latn-NG +bxs=bxs-Latn-CM +bxu=bxu-Mong-CN +bxv=bxv-Latn-TD +bxw=bxw-Latn-ML +bxz=bxz-Latn-PG +bya=bya-Latn-PH +byb=byb-Latn-CM +byc=byc-Latn-NG +byd=byd-Latn-ID +bye=bye-Latn-PG +byf=byf-Latn-NG +byh=byh-Deva-NP +byi=byi-Latn-CD +byj=byj-Latn-NG +byk=byk-Latn-CN +byl=byl-Latn-ID +bym=bym-Latn-AU +byn=byn-Ethi-ER +byp=byp-Latn-NG +byr=byr-Latn-PG +bys=bys-Latn-NG +byv=byv-Latn-CM +byw=byw-Deva-NP +byx=byx-Latn-PG +byz=byz-Latn-PG +bza=bza-Latn-LR +bzb=bzb-Latn-ID +bzc=bzc-Latn-MG +bzd=bzd-Latn-CR +bze=bze-Latn-ML +bzf=bzf-Latn-PG +bzh=bzh-Latn-PG +bzi=bzi-Thai-TH +bzj=bzj-Latn-BZ +bzk=bzk-Latn-NI +bzl=bzl-Latn-ID +bzm=bzm-Latn-CD +bzn=bzn-Latn-ID +bzo=bzo-Latn-CD +bzp=bzp-Latn-ID +bzq=bzq-Latn-ID +bzr=bzr-Latn-AU +bzt=bzt-Latn-001 +bzu=bzu-Latn-ID +bzv=bzv-Latn-CM +bzw=bzw-Latn-NG +bzx=bzx-Latn-ML +bzy=bzy-Latn-NG +bzz=bzz-Latn-NG +ca=ca-Latn-ES +caa=caa-Latn-GT +cab=cab-Latn-HN +cac=cac-Latn-GT +cad=cad-Latn-US +cae=cae-Latn-SN +caf=caf-Latn-CA +cag=cag-Latn-PY +cah=cah-Latn-PE +caj=caj-Latn-BO +cak=cak-Latn-GT +cal=cal-Latn-MP +cam=cam-Latn-NC +can=can-Latn-PG +cao=cao-Latn-BO +cap=cap-Latn-BO +caq=caq-Latn-IN +car=car-Latn-VE +cas=cas-Latn-BO +cav=cav-Latn-BO +caw=caw-Latn-BO +cax=cax-Latn-BO +cay=cay-Latn-CA +caz=caz-Latn-BO +cbb=cbb-Latn-CO +cbc=cbc-Latn-CO +cbd=cbd-Latn-CO +cbg=cbg-Latn-CO +cbi=cbi-Latn-EC +cbj=cbj-Latn-BJ +cbk=cbk-Latn-PH +cbl=cbl-Latn-MM +cbn=cbn-Thai-TH +cbo=cbo-Latn-NG +cbq=cbq-Latn-NG +cbr=cbr-Latn-PE +cbs=cbs-Latn-PE +cbt=cbt-Latn-PE +cbu=cbu-Latn-PE +cbv=cbv-Latn-CO +cbw=cbw-Latn-PH +cby=cby-Latn-CO +ccc=ccc-Latn-PE +ccd=ccd-Latn-BR +cce=cce-Latn-MZ +ccg=ccg-Latn-NG +cch=cch-Latn-NG +ccj=ccj-Latn-GW +ccl=ccl-Latn-TZ +ccm=ccm-Latn-MY +cco=cco-Latn-MX +ccp=ccp-Cakm-BD +ccr=ccr-Latn-SV +cde=cde-Telu-IN +cdf=cdf-Latn-IN +cdh=cdh-Deva-IN +cdi=cdi-Gujr-IN +cdj=cdj-Deva-IN +cdm=cdm-Deva-NP +cdo=cdo-Hans-CN +cdr=cdr-Latn-NG +cdz=cdz-Beng-IN +ce=ce-Cyrl-RU +cea=cea-Latn-US +ceb=ceb-Latn-PH +ceg=ceg-Latn-PY +cek=cek-Latn-MM +cen=cen-Latn-NG +cet=cet-Latn-NG +cey=cey-Latn-MM +cfa=cfa-Latn-NG +cfd=cfd-Latn-NG +cfg=cfg-Latn-NG +cfm=cfm-Latn-MM +cga=cga-Latn-PG +cgc=cgc-Latn-PH +cgg=cgg-Latn-UG +cgk=cgk-Tibt-BT +ch=ch-Latn-GU +chb=chb-Latn-CO +chd=chd-Latn-MX +chf=chf-Latn-MX +chg=chg-Arab-TM +chh=chh-Latn-US +chj=chj-Latn-MX +chk=chk-Latn-FM +chl=chl-Latn-US +chm=chm-Cyrl-RU +chn=chn-Latn-US +cho=cho-Latn-US +chp=chp-Latn-CA +chq=chq-Latn-MX +chr=chr-Cher-US +cht=cht-Latn-PE +chw=chw-Latn-MZ +chx=chx-Deva-NP +chy=chy-Latn-US +chz=chz-Latn-MX +cia=cia-Latn-ID +cib=cib-Latn-BJ +cic=cic-Latn-US +cie=cie-Latn-NG +cih=cih-Deva-IN +cim=cim-Latn-IT +cin=cin-Latn-BR +cip=cip-Latn-MX +cir=cir-Latn-NC +ciw=ciw-Latn-US +ciy=ciy-Latn-VE +cja=cja-Arab-KH +cje=cje-Latn-VN +cjh=cjh-Latn-US +cji=cji-Cyrl-RU +cjk=cjk-Latn-AO +cjm=cjm-Cham-VN +cjn=cjn-Latn-PG +cjo=cjo-Latn-PE +cjp=cjp-Latn-CR +cjs=cjs-Latn-RU +cjv=cjv-Latn-PG +cjy=cjy-Hans-CN +ckb=ckb-Arab-IQ +ckl=ckl-Latn-NG +ckm=ckm-Latn-HR +ckn=ckn-Latn-MM +cko=cko-Latn-GH +ckq=ckq-Latn-TD +ckr=ckr-Latn-PG +cks=cks-Latn-NC +ckt=ckt-Cyrl-RU +cku=cku-Latn-US +ckv=ckv-Latn-TW +ckx=ckx-Latn-CM +cky=cky-Latn-NG +ckz=ckz-Latn-GT +cla=cla-Latn-NG +clc=clc-Latn-CA +cle=cle-Latn-MX +clh=clh-Arab-PK +cli=cli-Latn-GH +clj=clj-Latn-MM +clk=clk-Latn-IN +cll=cll-Latn-GH +clm=clm-Latn-US +clo=clo-Latn-MX +clt=clt-Latn-MM +clu=clu-Latn-PH +clw=clw-Cyrl-RU +cly=cly-Latn-MX +cma=cma-Latn-VN +cme=cme-Latn-BF +cmg=cmg-Soyo-MN +cmi=cmi-Latn-CO +cml=cml-Latn-ID +cmo=cmo-Latn-VN +cmr=cmr-Latn-MM +cms=cms-Latn-IT +cmt=cmt-Latn-ZA +cna=cna-Tibt-IN +cnb=cnb-Latn-MM +cnc=cnc-Latn-VN +cng=cng-Latn-CN +cnh=cnh-Latn-MM +cni=cni-Latn-PE +cnk=cnk-Latn-MM +cnl=cnl-Latn-MX +cnp=cnp-Hans-CN +cnq=cnq-Latn-CM +cns=cns-Latn-ID +cnt=cnt-Latn-MX +cnw=cnw-Latn-MM +cnx=cnx-Latn-GB +co=co-Latn-FR +coa=coa-Latn-AU +cob=cob-Latn-MX +coc=coc-Latn-MX +cod=cod-Latn-PE +coe=coe-Latn-CO +cof=cof-Latn-EC +cog=cog-Thai-TH +coh=coh-Latn-KE +coj=coj-Latn-MX +cok=cok-Latn-MX +col=col-Latn-US +com=com-Latn-US +coo=coo-Latn-CA +cop=cop-Copt-EG +coq=coq-Latn-US +cot=cot-Latn-PE +cou=cou-Latn-SN +cox=cox-Latn-PE +coz=coz-Latn-MX +cpa=cpa-Latn-MX +cpb=cpb-Latn-PE +cpc=cpc-Latn-PE +cpg=cpg-Grek-GR +cpi=cpi-Latn-NR +cpn=cpn-Latn-GH +cpo=cpo-Latn-BF +cps=cps-Latn-PH +cpu=cpu-Latn-PE +cpx=cpx-Latn-CN +cpy=cpy-Latn-PE +cqd=cqd-Latn-CN +cr=cr-Cans-CA +cra=cra-Latn-ET +crb=crb-Latn-VC +crc=crc-Latn-VU +crd=crd-Latn-US +crf=crf-Latn-CO +crg=crg-Latn-CA +crh=crh-Cyrl-UA +cri=cri-Latn-ST +crj=crj-Cans-CA +crk=crk-Cans-CA +crl=crl-Cans-CA +crm=crm-Cans-CA +crn=crn-Latn-MX +cro=cro-Latn-US +crq=crq-Latn-AR +crs=crs-Latn-SC +crt=crt-Latn-AR +crv=crv-Latn-IN +crw=crw-Latn-VN +crx=crx-Latn-CA +cry=cry-Latn-NG +crz=crz-Latn-US +cs=cs-Latn-CZ +csa=csa-Latn-MX +csb=csb-Latn-PL +csh=csh-Mymr-MM +csj=csj-Latn-MM +csk=csk-Latn-SN +csm=csm-Latn-US +cso=cso-Latn-MX +csp=csp-Hans-CN +css=css-Latn-US +cst=cst-Latn-US +csv=csv-Latn-MM +csw=csw-Cans-CA +csy=csy-Latn-MM +csz=csz-Latn-US +cta=cta-Latn-MX +ctc=ctc-Latn-US +ctd=ctd-Pauc-MM +cte=cte-Latn-MX +ctg=ctg-Beng-BD +cth=cth-Latn-MM +ctl=ctl-Latn-MX +ctm=ctm-Latn-US +ctn=ctn-Deva-NP +cto=cto-Latn-CO +ctp=ctp-Latn-MX +cts=cts-Latn-PH +ctt=ctt-Taml-IN +ctu=ctu-Latn-MX +cty=cty-Taml-IN +ctz=ctz-Latn-MX +cu=cu-Cyrl-RU +cu-Glag=cu-Glag-BG +cua=cua-Latn-VN +cub=cub-Latn-CO +cuc=cuc-Latn-MX +cuh=cuh-Latn-KE +cui=cui-Latn-CO +cuj=cuj-Latn-PE +cuk=cuk-Latn-PA +cul=cul-Latn-BR +cuo=cuo-Latn-VE +cup=cup-Latn-US +cut=cut-Latn-MX +cuu=cuu-Lana-CN +cuv=cuv-Latn-CM +cux=cux-Latn-MX +cuy=cuy-Latn-MX +cv=cv-Cyrl-RU +cvg=cvg-Latn-IN +cvn=cvn-Latn-MX +cwa=cwa-Latn-TZ +cwb=cwb-Latn-MZ +cwe=cwe-Latn-TZ +cwg=cwg-Latn-MY +cwt=cwt-Latn-SN +cxh=cxh-Latn-NG +cy=cy-Latn-GB +cya=cya-Latn-MX +cyb=cyb-Latn-BO +cyo=cyo-Latn-PH +czh=czh-Hans-CN +czk=czk-Hebr-CZ +czn=czn-Latn-MX +czt=czt-Latn-MM +da=da-Latn-DK +daa=daa-Latn-TD +dac=dac-Latn-PG +dad=dad-Latn-PG +dae=dae-Latn-CM +dag=dag-Latn-GH +dah=dah-Latn-PG +dai=dai-Latn-TD +daj=daj-Latn-SD +dak=dak-Latn-US +dal=dal-Latn-KE +dam=dam-Latn-NG +dao=dao-Latn-MM +daq=daq-Deva-IN +dar=dar-Cyrl-RU +das=das-Latn-CI +dau=dau-Latn-TD +dav=dav-Latn-KE +daw=daw-Latn-PH +dax=dax-Latn-AU +daz=daz-Latn-ID +dba=dba-Latn-ML +dbb=dbb-Latn-NG +dbd=dbd-Latn-NG +dbe=dbe-Latn-ID +dbf=dbf-Latn-ID +dbg=dbg-Latn-ML +dbi=dbi-Latn-NG +dbj=dbj-Latn-MY +dbl=dbl-Latn-AU +dbm=dbm-Latn-NG +dbn=dbn-Latn-ID +dbo=dbo-Latn-NG +dbp=dbp-Latn-NG +dbq=dbq-Latn-CM +dbt=dbt-Latn-ML +dbu=dbu-Latn-ML +dbv=dbv-Latn-NG +dbw=dbw-Latn-ML +dby=dby-Latn-PG +dcc=dcc-Arab-IN +dcr=dcr-Latn-VI +dda=dda-Latn-AU +ddd=ddd-Latn-SS +dde=dde-Latn-CG +ddg=ddg-Latn-TL +ddi=ddi-Latn-PG +ddj=ddj-Latn-AU +ddn=ddn-Latn-BJ +ddo=ddo-Cyrl-RU +ddr=ddr-Latn-AU +dds=dds-Latn-ML +ddw=ddw-Latn-ID +de=de-Latn-DE +dec=dec-Latn-SD +ded=ded-Latn-PG +dee=dee-Latn-LR +def=def-Arab-IR +deg=deg-Latn-NG +deh=deh-Arab-PK +dei=dei-Latn-ID +dek=dek-Latn-CM +del=del-Latn-US +dem=dem-Latn-ID +den=den-Latn-CA +deq=deq-Latn-CF +der=der-Beng-IN +des=des-Latn-BR +dev=dev-Latn-PG +dez=dez-Latn-CD +dga=dga-Latn-GH +dgb=dgb-Latn-ML +dgc=dgc-Latn-PH +dgd=dgd-Latn-BF +dge=dge-Latn-PG +dgg=dgg-Latn-PG +dgh=dgh-Latn-NG +dgi=dgi-Latn-BF +dgk=dgk-Latn-CF +dgl=dgl-Arab-SD +dgn=dgn-Latn-AU +dgr=dgr-Latn-CA +dgs=dgs-Latn-BF +dgt=dgt-Latn-AU +dgw=dgw-Latn-AU +dgx=dgx-Latn-PG +dgz=dgz-Latn-PG +dhg=dhg-Latn-AU +dhi=dhi-Deva-NP +dhl=dhl-Latn-AU +dhm=dhm-Latn-AO +dhn=dhn-Gujr-IN +dho=dho-Deva-IN +dhr=dhr-Latn-AU +dhs=dhs-Latn-TZ +dhu=dhu-Latn-AU +dhv=dhv-Latn-NC +dhw=dhw-Deva-NP +dhx=dhx-Latn-AU +dia=dia-Latn-PG +dib=dib-Latn-SS +dic=dic-Latn-CI +did=did-Latn-SS +dif=dif-Latn-AU +dig=dig-Latn-KE +dih=dih-Latn-MX +dii=dii-Latn-CM +dij=dij-Latn-ID +dil=dil-Latn-SD +din=din-Latn-SS +dio=dio-Latn-NG +dip=dip-Latn-SS +dir=dir-Latn-NG +dis=dis-Latn-IN +diu=diu-Latn-NA +diw=diw-Latn-SS +dix=dix-Latn-VU +diy=diy-Latn-ID +diz=diz-Latn-CD +dja=dja-Latn-AU +djb=djb-Latn-AU +djc=djc-Latn-TD +djd=djd-Latn-AU +dje=dje-Latn-NE +djf=djf-Latn-AU +dji=dji-Latn-AU +djj=djj-Latn-AU +djk=djk-Latn-SR +djm=djm-Latn-ML +djn=djn-Latn-AU +djo=djo-Latn-ID +djr=djr-Latn-AU +dju=dju-Latn-PG +djw=djw-Latn-AU +dka=dka-Tibt-BT +dkg=dkg-Latn-NG +dkk=dkk-Latn-ID +dkr=dkr-Latn-MY +dks=dks-Latn-SS +dkx=dkx-Latn-CM +dlg=dlg-Cyrl-RU +dlm=dlm-Latn-HR +dln=dln-Latn-IN +dma=dma-Latn-GA +dmb=dmb-Latn-ML +dmc=dmc-Latn-PG +dmd=dmd-Latn-AU +dme=dme-Latn-CM +dmf=dmf-Medf-NG +dmg=dmg-Latn-MY +dmk=dmk-Arab-PK +dml=dml-Arab-PK +dmm=dmm-Latn-CM +dmo=dmo-Latn-CM +dmr=dmr-Latn-ID +dms=dms-Latn-ID +dmu=dmu-Latn-ID +dmv=dmv-Latn-MY +dmw=dmw-Latn-AU +dmx=dmx-Latn-MZ +dmy=dmy-Latn-ID +dna=dna-Latn-ID +dnd=dnd-Latn-PG +dne=dne-Latn-TZ +dng=dng-Cyrl-KG +dni=dni-Latn-ID +dnj=dnj-Latn-CI +dnk=dnk-Latn-ID +dnn=dnn-Latn-BF +dno=dno-Latn-CD +dnr=dnr-Latn-PG +dnt=dnt-Latn-ID +dnu=dnu-Mymr-MM +dnv=dnv-Mymr-MM +dnw=dnw-Latn-ID +dny=dny-Latn-BR +doa=doa-Latn-PG +dob=dob-Latn-PG +doc=doc-Latn-CN +doe=doe-Latn-TZ +dof=dof-Latn-PG +doh=doh-Latn-NG +doi=doi-Deva-IN +dok=dok-Latn-ID +dol=dol-Latn-PG +don=don-Latn-PG +doo=doo-Latn-CD +dop=dop-Latn-BJ +dor=dor-Latn-SB +dos=dos-Latn-BF +dot=dot-Latn-NG +dov=dov-Latn-ZW +dow=dow-Latn-CM +dox=dox-Ethi-ET +doy=doy-Latn-GH +dpp=dpp-Latn-MY +drc=drc-Latn-PT +dre=dre-Tibt-NP +drg=drg-Latn-MY +dri=dri-Latn-NG +drl=drl-Latn-AU +drn=drn-Latn-ID +dro=dro-Latn-MY +drq=drq-Deva-NP +drs=drs-Ethi-ET +drt=drt-Latn-NL +dru=dru-Latn-TW +dry=dry-Deva-NP +dsb=dsb-Latn-DE +dsh=dsh-Latn-KE +dsi=dsi-Latn-TD +dsk=dsk-Latn-NG +dsn=dsn-Latn-ID +dso=dso-Orya-IN +dsq=dsq-Latn-ML +dta=dta-Latn-CN +dtb=dtb-Latn-MY +dtd=dtd-Latn-CA +dth=dth-Latn-AU +dti=dti-Latn-ML +dtk=dtk-Latn-ML +dtm=dtm-Latn-ML +dto=dto-Latn-ML +dtp=dtp-Latn-MY +dtr=dtr-Latn-MY +dts=dts-Latn-ML +dtt=dtt-Latn-ML +dtu=dtu-Latn-ML +dty=dty-Deva-NP +dua=dua-Latn-CM +dub=dub-Gujr-IN +duc=duc-Latn-PG +due=due-Latn-PH +duf=duf-Latn-NC +dug=dug-Latn-KE +duh=duh-Deva-IN +dui=dui-Latn-PG +duk=duk-Latn-PG +dul=dul-Latn-PH +dum=dum-Latn-NL +dun=dun-Latn-ID +duo=duo-Latn-PH +dup=dup-Latn-ID +duq=duq-Latn-ID +dur=dur-Latn-CM +dus=dus-Deva-NP +duu=duu-Latn-CN +duv=duv-Latn-ID +duw=duw-Latn-ID +dux=dux-Latn-ML +duy=duy-Latn-PH +duz=duz-Latn-CM +dv=dv-Thaa-MV +dva=dva-Latn-PG +dwa=dwa-Latn-NG +dwk=dwk-Orya-IN +dwr=dwr-Latn-ET +dws=dws-Latn-001 +dwu=dwu-Latn-AU +dww=dww-Latn-PG +dwy=dwy-Latn-AU +dwz=dwz-Deva-NP +dya=dya-Latn-BF +dyb=dyb-Latn-AU +dyd=dyd-Latn-AU +dyg=dyg-Latn-PH +dyi=dyi-Latn-CI +dym=dym-Latn-ML +dyn=dyn-Latn-AU +dyo=dyo-Latn-SN +dyr=dyr-Latn-NG +dyu=dyu-Latn-BF +dyy=dyy-Latn-AU +dz=dz-Tibt-BT +dza=dza-Latn-NG +dzd=dzd-Latn-NG +dze=dze-Latn-AU +dzg=dzg-Latn-TD +dzl=dzl-Tibt-BT +dzn=dzn-Latn-CD +eaa=eaa-Latn-AU +ebc=ebc-Latn-ID +ebg=ebg-Latn-NG +ebk=ebk-Latn-PH +ebo=ebo-Latn-CG +ebr=ebr-Latn-CI +ebu=ebu-Latn-KE +ecr=ecr-Grek-GR +ecy=ecy-Cprt-CY +ee=ee-Latn-GH +efa=efa-Latn-NG +efe=efe-Latn-CD +efi=efi-Latn-NG +ega=ega-Latn-CI +egl=egl-Latn-IT +egm=egm-Latn-TZ +ego=ego-Latn-NG +egy=egy-Egyp-EG +ehu=ehu-Latn-NG +eip=eip-Latn-ID +eit=eit-Latn-PG +eiv=eiv-Latn-PG +eja=eja-Latn-GW +eka=eka-Latn-NG +eke=eke-Latn-NG +ekg=ekg-Latn-ID +eki=eki-Latn-NG +ekl=ekl-Latn-BD +ekm=ekm-Latn-CM +eko=eko-Latn-MZ +ekp=ekp-Latn-NG +ekr=ekr-Latn-NG +eky=eky-Kali-MM +el=el-Grek-GR +ele=ele-Latn-PG +elk=elk-Latn-PG +elm=elm-Latn-NG +elo=elo-Latn-KE +elu=elu-Latn-PG +ema=ema-Latn-NG +emb=emb-Latn-ID +eme=eme-Latn-GF +emg=emg-Deva-NP +emi=emi-Latn-PG +emm=emm-Latn-MX +emn=emn-Latn-CM +emp=emp-Latn-PA +ems=ems-Latn-US +emu=emu-Deva-IN +emw=emw-Latn-ID +emx=emx-Latn-FR +emz=emz-Latn-CM +en=en-Latn-US +en-Shaw=en-Shaw-GB +ena=ena-Latn-PG +enb=enb-Latn-KE +enc=enc-Latn-VN +end=end-Latn-ID +enf=enf-Cyrl-RU +enh=enh-Cyrl-RU +enl=enl-Latn-PY +enm=enm-Latn-GB +enn=enn-Latn-NG +eno=eno-Latn-ID +enq=enq-Latn-PG +enr=enr-Latn-ID +env=env-Latn-NG +enw=enw-Latn-NG +enx=enx-Latn-PY +eo=eo-Latn-001 +eot=eot-Latn-CI +epi=epi-Latn-NG +era=era-Taml-IN +erg=erg-Latn-VU +erh=erh-Latn-NG +eri=eri-Latn-PG +erk=erk-Latn-VU +err=err-Latn-AU +ers=ers-Latn-CN +ert=ert-Latn-ID +erw=erw-Latn-ID +es=es-Latn-ES +ese=ese-Latn-BO +esg=esg-Gonm-IN +esh=esh-Arab-IR +esi=esi-Latn-US +esm=esm-Latn-CI +ess=ess-Latn-US +esu=esu-Latn-US +esy=esy-Latn-PH +et=et-Latn-EE +etb=etb-Latn-NG +etn=etn-Latn-VU +eto=eto-Latn-CM +etr=etr-Latn-PG +ets=ets-Latn-NG +ett=ett-Ital-IT +etu=etu-Latn-NG +etx=etx-Latn-NG +etz=etz-Latn-ID +eu=eu-Latn-ES +eud=eud-Latn-MX +eve=eve-Cyrl-RU +evh=evh-Latn-NG +evn=evn-Cyrl-RU +ewo=ewo-Latn-CM +ext=ext-Latn-ES +eya=eya-Latn-US +eyo=eyo-Latn-KE +eza=eza-Latn-NG +eze=eze-Latn-NG +fa=fa-Arab-IR +faa=faa-Latn-PG +fab=fab-Latn-GQ +fad=fad-Latn-PG +faf=faf-Latn-SB +fag=fag-Latn-PG +fah=fah-Latn-NG +fai=fai-Latn-PG +faj=faj-Latn-PG +fak=fak-Latn-CM +fal=fal-Latn-CM +fam=fam-Latn-NG +fan=fan-Latn-GQ +fap=fap-Latn-SN +far=far-Latn-SB +fau=fau-Latn-ID +fax=fax-Latn-ES +fay=fay-Arab-IR +faz=faz-Arab-IR +fbl=fbl-Latn-PH +fer=fer-Latn-SS +ff=ff-Latn-SN +ff-Adlm=ff-Adlm-GN +ffi=ffi-Latn-PG +ffm=ffm-Latn-ML +fgr=fgr-Latn-TD +fi=fi-Latn-FI +fia=fia-Arab-SD +fie=fie-Latn-NG +fif=fif-Latn-SA +fil=fil-Latn-PH +fip=fip-Latn-TZ +fir=fir-Latn-NG +fit=fit-Latn-SE +fiw=fiw-Latn-PG +fj=fj-Latn-FJ +fkk=fkk-Latn-NG +fkv=fkv-Latn-NO +fla=fla-Latn-US +flh=flh-Latn-ID +fli=fli-Latn-NG +fll=fll-Latn-CM +fln=fln-Latn-AU +flr=flr-Latn-CD +fly=fly-Latn-ZA +fmp=fmp-Latn-CM +fmu=fmu-Deva-IN +fnb=fnb-Latn-VU +fng=fng-Latn-ZA +fni=fni-Latn-TD +fo=fo-Latn-FO +fod=fod-Latn-BJ +foi=foi-Latn-PG +fom=fom-Latn-CD +fon=fon-Latn-BJ +for=for-Latn-PG +fos=fos-Latn-TW +fpe=fpe-Latn-GQ +fqs=fqs-Latn-PG +fr=fr-Latn-FR +frc=frc-Latn-US +frd=frd-Latn-ID +frk=frk-Latn-DE +frm=frm-Latn-FR +fro=fro-Latn-FR +frp=frp-Latn-FR +frq=frq-Latn-PG +frr=frr-Latn-DE +frs=frs-Latn-DE +frt=frt-Latn-VU +fub=fub-Arab-CM +fud=fud-Latn-WF +fue=fue-Latn-BJ +fuf=fuf-Latn-GN +fuh=fuh-Latn-NE +fui=fui-Latn-TD +fum=fum-Latn-NG +fun=fun-Latn-BR +fuq=fuq-Latn-NE +fur=fur-Latn-IT +fut=fut-Latn-VU +fuu=fuu-Latn-CD +fuv=fuv-Latn-NG +fuy=fuy-Latn-PG +fvr=fvr-Latn-SD +fwa=fwa-Latn-NC +fwe=fwe-Latn-NA +fy=fy-Latn-NL +ga=ga-Latn-IE +gaa=gaa-Latn-GH +gab=gab-Latn-TD +gac=gac-Latn-IN +gad=gad-Latn-PH +gae=gae-Latn-VE +gaf=gaf-Latn-PG +gag=gag-Latn-MD +gah=gah-Latn-PG +gai=gai-Latn-PG +gaj=gaj-Latn-PG +gak=gak-Latn-ID +gal=gal-Latn-TL +gam=gam-Latn-PG +gan=gan-Hans-CN +gao=gao-Latn-PG +gap=gap-Latn-PG +gaq=gaq-Orya-IN +gar=gar-Latn-PG +gas=gas-Gujr-IN +gat=gat-Latn-PG +gau=gau-Telu-IN +gaw=gaw-Latn-PG +gax=gax-Latn-ET +gay=gay-Latn-ID +gba=gba-Latn-CF +gbb=gbb-Latn-AU +gbd=gbd-Latn-AU +gbe=gbe-Latn-PG +gbf=gbf-Latn-PG +gbg=gbg-Latn-CF +gbh=gbh-Latn-BJ +gbi=gbi-Latn-ID +gbj=gbj-Orya-IN +gbk=gbk-Deva-IN +gbl=gbl-Gujr-IN +gbm=gbm-Deva-IN +gbn=gbn-Latn-SS +gbp=gbp-Latn-CF +gbq=gbq-Latn-CF +gbr=gbr-Latn-NG +gbs=gbs-Latn-BJ +gbu=gbu-Latn-AU +gbv=gbv-Latn-CF +gbw=gbw-Latn-AU +gbx=gbx-Latn-BJ +gby=gby-Latn-NG +gbz=gbz-Arab-IR +gcc=gcc-Latn-PG +gcd=gcd-Latn-AU +gcf=gcf-Latn-GP +gcl=gcl-Latn-GD +gcn=gcn-Latn-PG +gcr=gcr-Latn-GF +gct=gct-Latn-VE +gd=gd-Latn-GB +gdb=gdb-Orya-IN +gdc=gdc-Latn-AU +gdd=gdd-Latn-PG +gde=gde-Latn-NG +gdf=gdf-Latn-NG +gdg=gdg-Latn-PH +gdh=gdh-Latn-AU +gdi=gdi-Latn-CF +gdj=gdj-Latn-AU +gdk=gdk-Latn-TD +gdl=gdl-Latn-ET +gdm=gdm-Latn-TD +gdn=gdn-Latn-PG +gdo=gdo-Cyrl-RU +gdq=gdq-Latn-YE +gdr=gdr-Latn-PG +gdt=gdt-Latn-AU +gdu=gdu-Latn-NG +gdx=gdx-Deva-IN +gea=gea-Latn-NG +geb=geb-Latn-PG +gec=gec-Latn-LR +ged=ged-Latn-NG +gef=gef-Latn-ID +geg=geg-Latn-NG +geh=geh-Latn-CA +gei=gei-Latn-ID +gej=gej-Latn-TG +gek=gek-Latn-NG +gel=gel-Latn-NG +geq=geq-Latn-CF +ges=ges-Latn-ID +gev=gev-Latn-GA +gew=gew-Latn-NG +gex=gex-Latn-SO +gey=gey-Latn-CD +gez=gez-Ethi-ET +gfk=gfk-Latn-PG +gga=gga-Latn-SB +ggb=ggb-Latn-LR +ggd=ggd-Latn-AU +gge=gge-Latn-AU +ggg=ggg-Arab-PK +ggk=ggk-Latn-AU +ggl=ggl-Latn-PG +ggt=ggt-Latn-PG +ggu=ggu-Latn-CI +ggw=ggw-Latn-PG +gha=gha-Arab-LY +ghc=ghc-Latn-GB +ghe=ghe-Deva-NP +ghk=ghk-Latn-MM +ghn=ghn-Latn-SB +gho=gho-Tfng-MA +ghr=ghr-Arab-PK +ghs=ghs-Latn-PG +ght=ght-Tibt-NP +gia=gia-Latn-AU +gib=gib-Latn-NG +gic=gic-Latn-ZA +gid=gid-Latn-CM +gie=gie-Latn-CI +gig=gig-Arab-PK +gih=gih-Latn-AU +gil=gil-Latn-KI +gim=gim-Latn-PG +gin=gin-Cyrl-RU +gip=gip-Latn-PG +giq=giq-Latn-VN +gir=gir-Latn-VN +gis=gis-Latn-CM +git=git-Latn-CA +gix=gix-Latn-CD +giy=giy-Latn-AU +giz=giz-Latn-CM +gjk=gjk-Arab-PK +gjm=gjm-Latn-AU +gjn=gjn-Latn-GH +gjr=gjr-Latn-AU +gju=gju-Arab-PK +gka=gka-Latn-PG +gkd=gkd-Latn-PG +gke=gke-Latn-CM +gkn=gkn-Latn-NG +gko=gko-Latn-AU +gkp=gkp-Latn-GN +gku=gku-Latn-ZA +gl=gl-Latn-ES +glb=glb-Latn-NG +glc=glc-Latn-TD +gld=gld-Cyrl-RU +glh=glh-Arab-AF +glj=glj-Latn-TD +glk=glk-Arab-IR +gll=gll-Latn-AU +glo=glo-Latn-NG +glr=glr-Latn-LR +glu=glu-Latn-TD +glw=glw-Latn-NG +gma=gma-Latn-AU +gmb=gmb-Latn-SB +gmd=gmd-Latn-NG +gmg=gmg-Latn-PG +gmh=gmh-Latn-DE +gml=gml-Latf-DE +gmm=gmm-Latn-CM +gmn=gmn-Latn-CM +gmr=gmr-Latn-AU +gmu=gmu-Latn-PG +gmv=gmv-Ethi-ET +gmx=gmx-Latn-TZ +gmy=gmy-Linb-GR +gmz=gmz-Latn-NG +gn=gn-Latn-PY +gna=gna-Latn-BF +gnb=gnb-Latn-IN +gnc=gnc-Latn-ES +gnd=gnd-Latn-CM +gne=gne-Latn-NG +gng=gng-Latn-TG +gnh=gnh-Latn-NG +gni=gni-Latn-AU +gnj=gnj-Latn-CI +gnk=gnk-Latn-BW +gnl=gnl-Latn-AU +gnm=gnm-Latn-PG +gnn=gnn-Latn-AU +gnq=gnq-Latn-MY +gnr=gnr-Latn-AU +gnt=gnt-Latn-PG +gnu=gnu-Latn-PG +gnw=gnw-Latn-BO +gnz=gnz-Latn-CF +goa=goa-Latn-CI +gob=gob-Latn-CO +goc=goc-Latn-PG +god=god-Latn-CI +goe=goe-Tibt-BT +gof=gof-Ethi-ET +gog=gog-Latn-TZ +goh=goh-Latn-DE +goi=goi-Latn-PG +goj=goj-Deva-IN +gok=gok-Deva-IN +gol=gol-Latn-LR +gon=gon-Deva-IN +goo=goo-Latn-FJ +gop=gop-Latn-ID +goq=goq-Latn-ID +gor=gor-Latn-ID +gos=gos-Latn-NL +got=got-Goth-UA +gou=gou-Latn-CM +gov=gov-Latn-CI +gow=gow-Latn-TZ +gox=gox-Latn-CD +goy=goy-Latn-TD +gpa=gpa-Latn-NG +gpe=gpe-Latn-GH +gpn=gpn-Latn-PG +gqa=gqa-Latn-NG +gqn=gqn-Latn-BR +gqr=gqr-Latn-TD +gra=gra-Deva-IN +grb=grb-Latn-LR +grc=grc-Grek-GR +grd=grd-Latn-NG +grg=grg-Latn-PG +grh=grh-Latn-NG +gri=gri-Latn-SB +grj=grj-Latn-LR +grm=grm-Latn-MY +grq=grq-Latn-PG +grs=grs-Latn-ID +grt=grt-Beng-IN +gru=gru-Ethi-ET +grv=grv-Latn-LR +grw=grw-Latn-PG +grx=grx-Latn-PG +gry=gry-Latn-LR +grz=grz-Latn-PG +gsl=gsl-Latn-SN +gsn=gsn-Latn-PG +gso=gso-Latn-CF +gsp=gsp-Latn-PG +gsw=gsw-Latn-CH +gta=gta-Latn-BR +gtu=gtu-Latn-AU +gu=gu-Gujr-IN +gua=gua-Latn-NG +gub=gub-Latn-BR +guc=guc-Latn-CO +gud=gud-Latn-CI +gue=gue-Latn-AU +guf=guf-Latn-AU +guh=guh-Latn-CO +gui=gui-Latn-BO +guk=guk-Latn-ET +gul=gul-Latn-US +gum=gum-Latn-CO +gun=gun-Latn-BR +guo=guo-Latn-CO +gup=gup-Latn-AU +guq=guq-Latn-PY +gur=gur-Latn-GH +gut=gut-Latn-CR +guu=guu-Latn-VE +guw=guw-Latn-BJ +gux=gux-Latn-BF +guz=guz-Latn-KE +gv=gv-Latn-IM +gva=gva-Latn-PY +gvc=gvc-Latn-BR +gve=gve-Latn-PG +gvf=gvf-Latn-PG +gvj=gvj-Latn-BR +gvl=gvl-Latn-TD +gvm=gvm-Latn-NG +gvn=gvn-Latn-AU +gvo=gvo-Latn-BR +gvp=gvp-Latn-BR +gvr=gvr-Deva-NP +gvs=gvs-Latn-PG +gvy=gvy-Latn-AU +gwa=gwa-Latn-CI +gwb=gwb-Latn-NG +gwc=gwc-Arab-PK +gwd=gwd-Latn-ET +gwe=gwe-Latn-TZ +gwf=gwf-Arab-PK +gwg=gwg-Latn-NG +gwi=gwi-Latn-CA +gwj=gwj-Latn-BW +gwm=gwm-Latn-AU +gwn=gwn-Latn-NG +gwr=gwr-Latn-UG +gwt=gwt-Arab-AF +gwu=gwu-Latn-AU +gww=gww-Latn-AU +gwx=gwx-Latn-GH +gxx=gxx-Latn-CI +gyb=gyb-Latn-PG +gyd=gyd-Latn-AU +gye=gye-Latn-NG +gyf=gyf-Latn-AU +gyg=gyg-Latn-CF +gyi=gyi-Latn-CM +gyl=gyl-Latn-ET +gym=gym-Latn-PA +gyn=gyn-Latn-GY +gyo=gyo-Deva-NP +gyr=gyr-Latn-BO +gyy=gyy-Latn-AU +gyz=gyz-Latn-NG +gza=gza-Latn-SD +gzi=gzi-Arab-IR +gzn=gzn-Latn-ID +ha=ha-Latn-NG +ha-CM=ha-Arab-CM +ha-SD=ha-Arab-SD +haa=haa-Latn-US +hac=hac-Arab-IR +had=had-Latn-ID +hae=hae-Latn-ET +hag=hag-Latn-GH +hah=hah-Latn-PG +hai=hai-Latn-CA +haj=haj-Latn-IN +hak=hak-Hans-CN +hak-Hant=hak-Hant-TW +hak-TW=hak-Hant-TW +hal=hal-Latn-VN +ham=ham-Latn-PG +han=han-Latn-TZ +hao=hao-Latn-PG +hap=hap-Latn-ID +haq=haq-Latn-TZ +har=har-Ethi-ET +has=has-Latn-CA +hav=hav-Latn-CD +haw=haw-Latn-US +hax=hax-Latn-CA +hay=hay-Latn-TZ +haz=haz-Arab-AF +hba=hba-Latn-CD +hbb=hbb-Latn-NG +hbn=hbn-Latn-SD +hbo=hbo-Hebr-IL +hbu=hbu-Latn-TL +hch=hch-Latn-MX +hdy=hdy-Ethi-ET +he=he-Hebr-IL +hed=hed-Latn-TD +heg=heg-Latn-ID +heh=heh-Latn-TZ +hei=hei-Latn-CA +hem=hem-Latn-CD +hgm=hgm-Latn-NA +hgw=hgw-Latn-PG +hhi=hhi-Latn-PG +hhr=hhr-Latn-SN +hhy=hhy-Latn-PG +hi=hi-Deva-IN +hia=hia-Latn-NG +hib=hib-Latn-PE +hid=hid-Latn-US +hif=hif-Deva-FJ +hig=hig-Latn-NG +hih=hih-Latn-PG +hii=hii-Takr-IN +hij=hij-Latn-CM +hik=hik-Latn-ID +hil=hil-Latn-PH +hio=hio-Latn-BW +hir=hir-Latn-BR +hit=hit-Xsux-TR +hiw=hiw-Latn-VU +hix=hix-Latn-BR +hji=hji-Latn-ID +hka=hka-Latn-TZ +hke=hke-Latn-CD +hkh=hkh-Arab-IN +hkk=hkk-Latn-PG +hla=hla-Latn-PG +hlb=hlb-Deva-IN +hld=hld-Latn-VN +hlt=hlt-Latn-MM +hlu=hlu-Hluw-TR +hma=hma-Latn-CN +hmb=hmb-Latn-ML +hmd=hmd-Plrd-CN +hmf=hmf-Latn-VN +hmj=hmj-Bopo-CN +hmm=hmm-Latn-CN +hmn=hmn-Latn-CN +hmp=hmp-Latn-CN +hmq=hmq-Bopo-CN +hmr=hmr-Latn-IN +hms=hms-Latn-CN +hmt=hmt-Latn-PG +hmu=hmu-Latn-ID +hmv=hmv-Latn-VN +hmw=hmw-Latn-CN +hmy=hmy-Latn-CN +hmz=hmz-Latn-CN +hna=hna-Latn-CM +hnd=hnd-Arab-PK +hne=hne-Deva-IN +hng=hng-Latn-AO +hnh=hnh-Latn-BW +hni=hni-Latn-CN +hnj=hnj-Hmnp-US +hnj-Hmng=hnj-Hmng-LA +hnn=hnn-Latn-PH +hno=hno-Arab-PK +hns=hns-Latn-SR +ho=ho-Latn-PG +hoa=hoa-Latn-SB +hob=hob-Latn-PG +hoc=hoc-Deva-IN +hod=hod-Latn-NG +hoe=hoe-Latn-NG +hoh=hoh-Arab-OM +hoi=hoi-Latn-US +hoj=hoj-Deva-IN +hol=hol-Latn-AO +hom=hom-Latn-SS +hoo=hoo-Latn-CD +hop=hop-Latn-US +hor=hor-Latn-TD +hot=hot-Latn-PG +hov=hov-Latn-ID +how=how-Hani-CN +hoy=hoy-Deva-IN +hpo=hpo-Mymr-MM +hr=hr-Latn-HR +hra=hra-Latn-IN +hrc=hrc-Latn-PG +hre=hre-Latn-VN +hrk=hrk-Latn-ID +hrm=hrm-Latn-CN +hro=hro-Latn-VN +hrp=hrp-Latn-AU +hrt=hrt-Syrc-TR +hru=hru-Latn-IN +hrw=hrw-Latn-PG +hrx=hrx-Latn-BR +hrz=hrz-Arab-IR +hsb=hsb-Latn-DE +hsn=hsn-Hans-CN +hss=hss-Arab-OM +ht=ht-Latn-HT +hti=hti-Latn-ID +hto=hto-Latn-CO +hts=hts-Latn-TZ +htu=htu-Latn-ID +htx=htx-Xsux-TR +hu=hu-Latn-HU +hub=hub-Latn-PE +huc=huc-Latn-BW +hud=hud-Latn-ID +hue=hue-Latn-MX +huf=huf-Latn-PG +hug=hug-Latn-PE +huh=huh-Latn-CL +hui=hui-Latn-PG +huk=huk-Latn-ID +hul=hul-Latn-PG +hum=hum-Latn-CD +hup=hup-Latn-US +hur=hur-Latn-CA +hus=hus-Latn-MX +hut=hut-Deva-NP +huu=huu-Latn-PE +huv=huv-Latn-MX +huw=huw-Latn-ID +hux=hux-Latn-PE +huy=huy-Hebr-IL +huz=huz-Cyrl-RU +hvc=hvc-Latn-HT +hve=hve-Latn-MX +hvk=hvk-Latn-NC +hvn=hvn-Latn-ID +hvv=hvv-Latn-MX +hwa=hwa-Latn-CI +hwc=hwc-Latn-US +hwo=hwo-Latn-NG +hy=hy-Armn-AM +hya=hya-Latn-CM +hyw=hyw-Armn-AM +hz=hz-Latn-NA +ia=ia-Latn-001 +iai=iai-Latn-NC +ian=ian-Latn-PG +iar=iar-Latn-PG +iba=iba-Latn-MY +ibb=ibb-Latn-NG +ibd=ibd-Latn-AU +ibe=ibe-Latn-NG +ibg=ibg-Latn-PH +ibh=ibh-Latn-VN +ibl=ibl-Latn-PH +ibm=ibm-Latn-NG +ibn=ibn-Latn-NG +ibr=ibr-Latn-NG +ibu=ibu-Latn-ID +iby=iby-Latn-NG +ica=ica-Latn-BJ +ich=ich-Latn-NG +icr=icr-Latn-CO +id=id-Latn-ID +ida=ida-Latn-KE +idb=idb-Latn-IN +idc=idc-Latn-NG +idd=idd-Latn-BJ +ide=ide-Latn-NG +idi=idi-Latn-PG +idr=idr-Latn-SS +ids=ids-Latn-NG +idt=idt-Latn-TL +idu=idu-Latn-NG +ie=ie-Latn-EE +ifa=ifa-Latn-PH +ifb=ifb-Latn-PH +ife=ife-Latn-TG +iff=iff-Latn-VU +ifk=ifk-Latn-PH +ifm=ifm-Latn-CG +ifu=ifu-Latn-PH +ify=ify-Latn-PH +ig=ig-Latn-NG +igb=igb-Latn-NG +ige=ige-Latn-NG +igg=igg-Latn-PG +igl=igl-Latn-NG +igm=igm-Latn-PG +ign=ign-Latn-BO +igo=igo-Latn-PG +igs=igs-Latn-001 +igw=igw-Latn-NG +ihb=ihb-Latn-ID +ihi=ihi-Latn-NG +ihp=ihp-Latn-ID +ihw=ihw-Latn-AU +ii=ii-Yiii-CN +iin=iin-Latn-AU +ijc=ijc-Latn-NG +ije=ije-Latn-NG +ijj=ijj-Latn-BJ +ijn=ijn-Latn-NG +ijs=ijs-Latn-NG +ik=ik-Latn-US +ikh=ikh-Latn-NG +iki=iki-Latn-NG +ikk=ikk-Latn-NG +ikl=ikl-Latn-NG +iko=iko-Latn-NG +ikp=ikp-Latn-NG +ikr=ikr-Latn-AU +ikt=ikt-Latn-CA +ikv=ikv-Latn-NG +ikw=ikw-Latn-NG +ikx=ikx-Latn-UG +ikz=ikz-Latn-TZ +ila=ila-Latn-ID +ilb=ilb-Latn-ZM +ilg=ilg-Latn-AU +ili=ili-Latn-CN +ilk=ilk-Latn-PH +ilm=ilm-Latn-MY +ilo=ilo-Latn-PH +ilp=ilp-Latn-PH +ilu=ilu-Latn-ID +ilv=ilv-Latn-NG +imi=imi-Latn-PG +iml=iml-Latn-US +imn=imn-Latn-PG +imo=imo-Latn-PG +imr=imr-Latn-ID +ims=ims-Latn-IT +imt=imt-Latn-SS +imy=imy-Lyci-TR +in=in-Latn-ID +inb=inb-Latn-CO +ing=ing-Latn-US +inh=inh-Cyrl-RU +inj=inj-Latn-CO +inn=inn-Latn-PH +ino=ino-Latn-PG +inp=inp-Latn-PE +int=int-Mymr-MM +io=io-Latn-001 +ior=ior-Ethi-ET +iou=iou-Latn-PG +iow=iow-Latn-US +ipi=ipi-Latn-PG +ipo=ipo-Latn-PG +iqu=iqu-Latn-PE +iqw=iqw-Latn-NG +ire=ire-Latn-ID +irh=irh-Latn-ID +iri=iri-Latn-NG +irk=irk-Latn-TZ +irn=irn-Latn-BR +iru=iru-Taml-IN +irx=irx-Latn-ID +iry=iry-Latn-PH +is=is-Latn-IS +isa=isa-Latn-PG +isc=isc-Latn-PE +isd=isd-Latn-PH +ish=ish-Latn-NG +isi=isi-Latn-NG +isk=isk-Arab-AF +ism=ism-Latn-ID +isn=isn-Latn-TZ +iso=iso-Latn-NG +ist=ist-Latn-HR +isu=isu-Latn-CM +it=it-Latn-IT +itb=itb-Latn-PH +itd=itd-Latn-ID +ite=ite-Latn-BO +iti=iti-Latn-PH +itk=itk-Hebr-IT +itl=itl-Cyrl-RU +itm=itm-Latn-NG +ito=ito-Latn-BO +itr=itr-Latn-PG +its=its-Latn-NG +itt=itt-Latn-PH +itv=itv-Latn-PH +itw=itw-Latn-NG +itx=itx-Latn-ID +ity=ity-Latn-PH +itz=itz-Latn-GT +iu=iu-Cans-CA +ium=ium-Latn-CN +ivb=ivb-Latn-PH +ivv=ivv-Latn-PH +iw=iw-Hebr-IL +iwk=iwk-Latn-PH +iwm=iwm-Latn-PG +iwo=iwo-Latn-ID +iws=iws-Latn-PG +ixc=ixc-Latn-MX +ixl=ixl-Latn-GT +iya=iya-Latn-NG +iyo=iyo-Latn-CM +iyx=iyx-Latn-CG +izh=izh-Latn-RU +izm=izm-Latn-NG +izr=izr-Latn-NG +izz=izz-Latn-NG +ja=ja-Jpan-JP +jaa=jaa-Latn-BR +jab=jab-Latn-NG +jac=jac-Latn-GT +jad=jad-Arab-GN +jae=jae-Latn-PG +jaf=jaf-Latn-NG +jah=jah-Latn-MY +jaj=jaj-Latn-SB +jak=jak-Latn-MY +jal=jal-Latn-ID +jam=jam-Latn-JM +jan=jan-Latn-AU +jao=jao-Latn-AU +jaq=jaq-Latn-ID +jas=jas-Latn-NC +jat=jat-Arab-AF +jau=jau-Latn-ID +jax=jax-Latn-ID +jay=jay-Latn-AU +jaz=jaz-Latn-NC +jbe=jbe-Hebr-IL +jbi=jbi-Latn-AU +jbj=jbj-Latn-ID +jbk=jbk-Latn-PG +jbm=jbm-Latn-NG +jbn=jbn-Arab-LY +jbo=jbo-Latn-001 +jbr=jbr-Latn-ID +jbt=jbt-Latn-BR +jbu=jbu-Latn-CM +jbw=jbw-Latn-AU +jct=jct-Cyrl-UA +jda=jda-Tibt-IN +jdg=jdg-Arab-PK +jdt=jdt-Cyrl-RU +jeb=jeb-Latn-PE +jee=jee-Deva-NP +jeh=jeh-Latn-VN +jei=jei-Latn-ID +jek=jek-Latn-CI +jel=jel-Latn-ID +jen=jen-Latn-NG +jer=jer-Latn-NG +jet=jet-Latn-PG +jeu=jeu-Latn-TD +jgb=jgb-Latn-CD +jge=jge-Geor-GE +jgk=jgk-Latn-NG +jgo=jgo-Latn-CM +jhi=jhi-Latn-MY +ji=ji-Hebr-UA +jia=jia-Latn-CM +jib=jib-Latn-NG +jic=jic-Latn-HN +jid=jid-Latn-NG +jie=jie-Latn-NG +jig=jig-Latn-AU +jil=jil-Latn-PG +jim=jim-Latn-CM +jit=jit-Latn-TZ +jiu=jiu-Latn-CN +jiv=jiv-Latn-EC +jiy=jiy-Latn-CN +jje=jje-Hang-KR +jjr=jjr-Latn-NG +jka=jka-Latn-ID +jkm=jkm-Mymr-MM +jko=jko-Latn-PG +jku=jku-Latn-NG +jle=jle-Latn-SD +jma=jma-Latn-PG +jmb=jmb-Latn-NG +jmc=jmc-Latn-TZ +jmd=jmd-Latn-ID +jmi=jmi-Latn-NG +jml=jml-Deva-NP +jmn=jmn-Latn-MM +jmr=jmr-Latn-GH +jms=jms-Latn-NG +jmw=jmw-Latn-PG +jmx=jmx-Latn-MX +jna=jna-Takr-IN +jnd=jnd-Arab-PK +jng=jng-Latn-AU +jni=jni-Latn-NG +jnj=jnj-Latn-ET +jnl=jnl-Deva-IN +jns=jns-Deva-IN +job=job-Latn-CD +jod=jod-Latn-CI +jog=jog-Arab-PK +jor=jor-Latn-BO +jow=jow-Latn-ML +jpa=jpa-Hebr-PS +jpr=jpr-Hebr-IL +jqr=jqr-Latn-PE +jra=jra-Latn-VN +jrb=jrb-Hebr-IL +jrr=jrr-Latn-NG +jrt=jrt-Latn-NG +jru=jru-Latn-VE +jua=jua-Latn-BR +jub=jub-Latn-NG +jud=jud-Latn-CI +juh=juh-Latn-NG +jui=jui-Latn-AU +juk=juk-Latn-NG +jul=jul-Deva-NP +jum=jum-Latn-SD +jun=jun-Orya-IN +juo=juo-Latn-NG +jup=jup-Latn-BR +jur=jur-Latn-BR +jut=jut-Latn-DK +juu=juu-Latn-NG +juw=juw-Latn-NG +juy=juy-Orya-IN +jv=jv-Latn-ID +jvd=jvd-Latn-ID +jvn=jvn-Latn-SR +jw=jw-Latn-ID +jwi=jwi-Latn-GH +jya=jya-Tibt-CN +jye=jye-Hebr-IL +jyy=jyy-Latn-TD +ka=ka-Geor-GE +kaa=kaa-Cyrl-UZ +kab=kab-Latn-DZ +kac=kac-Latn-MM +kad=kad-Latn-NG +kag=kag-Latn-MY +kah=kah-Latn-CF +kai=kai-Latn-NG +kaj=kaj-Latn-NG +kak=kak-Latn-PH +kam=kam-Latn-KE +kao=kao-Latn-ML +kap=kap-Cyrl-RU +kaq=kaq-Latn-PE +kav=kav-Latn-BR +kaw=kaw-Bali-ID +kax=kax-Latn-ID +kay=kay-Latn-BR +kba=kba-Latn-AU +kbb=kbb-Latn-BR +kbc=kbc-Latn-BR +kbd=kbd-Cyrl-RU +kbe=kbe-Latn-AU +kbg=kbg-Tibt-IN +kbh=kbh-Latn-CO +kbi=kbi-Latn-ID +kbj=kbj-Latn-CD +kbk=kbk-Latn-PG +kbl=kbl-Latn-TD +kbm=kbm-Latn-PG +kbn=kbn-Latn-CF +kbo=kbo-Latn-SS +kbp=kbp-Latn-TG +kbq=kbq-Latn-PG +kbr=kbr-Latn-ET +kbs=kbs-Latn-GA +kbt=kbt-Latn-PG +kbu=kbu-Arab-PK +kbv=kbv-Latn-ID +kbw=kbw-Latn-PG +kbx=kbx-Latn-PG +kby=kby-Arab-NE +kbz=kbz-Latn-NG +kca=kca-Cyrl-RU +kcb=kcb-Latn-PG +kcc=kcc-Latn-NG +kcd=kcd-Latn-ID +kce=kce-Latn-NG +kcf=kcf-Latn-NG +kcg=kcg-Latn-NG +kch=kch-Latn-NG +kci=kci-Latn-NG +kcj=kcj-Latn-GW +kck=kck-Latn-ZW +kcl=kcl-Latn-PG +kcm=kcm-Latn-CF +kcn=kcn-Latn-UG +kco=kco-Latn-PG +kcp=kcp-Latn-SD +kcq=kcq-Latn-NG +kcs=kcs-Latn-NG +kct=kct-Latn-PG +kcu=kcu-Latn-TZ +kcv=kcv-Latn-CD +kcw=kcw-Latn-CD +kcy=kcy-Arab-DZ +kcz=kcz-Latn-TZ +kda=kda-Latn-AU +kdc=kdc-Latn-TZ +kdd=kdd-Latn-AU +kde=kde-Latn-TZ +kdf=kdf-Latn-PG +kdg=kdg-Latn-CD +kdh=kdh-Latn-TG +kdi=kdi-Latn-UG +kdj=kdj-Latn-UG +kdk=kdk-Latn-NC +kdl=kdl-Latn-NG +kdm=kdm-Latn-NG +kdn=kdn-Latn-ZW +kdp=kdp-Latn-NG +kdq=kdq-Beng-IN +kdr=kdr-Latn-LT +kdt=kdt-Thai-TH +kdw=kdw-Latn-ID +kdx=kdx-Latn-NG +kdy=kdy-Latn-ID +kdz=kdz-Latn-CM +kea=kea-Latn-CV +keb=keb-Latn-GA +kec=kec-Latn-SD +ked=ked-Latn-TZ +kee=kee-Latn-US +kef=kef-Latn-TG +keg=keg-Latn-SD +keh=keh-Latn-PG +kei=kei-Latn-ID +kek=kek-Latn-GT +kel=kel-Latn-CD +kem=kem-Latn-TL +ken=ken-Latn-CM +keo=keo-Latn-UG +ker=ker-Latn-TD +kes=kes-Latn-NG +ket=ket-Cyrl-RU +keu=keu-Latn-TG +kev=kev-Mlym-IN +kew=kew-Latn-PG +kex=kex-Deva-IN +key=key-Telu-IN +kez=kez-Latn-NG +kfa=kfa-Knda-IN +kfb=kfb-Deva-IN +kfc=kfc-Telu-IN +kfd=kfd-Knda-IN +kfe=kfe-Taml-IN +kff=kff-Latn-IN +kfg=kfg-Knda-IN +kfh=kfh-Mlym-IN +kfi=kfi-Taml-IN +kfk=kfk-Deva-IN +kfl=kfl-Latn-CM +kfm=kfm-Arab-IR +kfn=kfn-Latn-CM +kfo=kfo-Latn-CI +kfp=kfp-Deva-IN +kfq=kfq-Deva-IN +kfr=kfr-Deva-IN +kfs=kfs-Deva-IN +kfu=kfu-Deva-IN +kfv=kfv-Latn-IN +kfw=kfw-Latn-IN +kfx=kfx-Deva-IN +kfy=kfy-Deva-IN +kfz=kfz-Latn-BF +kg=kg-Latn-CD +kga=kga-Latn-CI +kgb=kgb-Latn-ID +kge=kge-Latn-ID +kgf=kgf-Latn-PG +kgj=kgj-Deva-NP +kgk=kgk-Latn-BR +kgl=kgl-Latn-AU +kgo=kgo-Latn-SD +kgp=kgp-Latn-BR +kgq=kgq-Latn-ID +kgr=kgr-Latn-ID +kgs=kgs-Latn-AU +kgt=kgt-Latn-NG +kgu=kgu-Latn-PG +kgv=kgv-Latn-ID +kgw=kgw-Latn-ID +kgx=kgx-Latn-ID +kgy=kgy-Deva-NP +kha=kha-Latn-IN +khb=khb-Talu-CN +khc=khc-Latn-ID +khd=khd-Latn-ID +khe=khe-Latn-ID +khf=khf-Thai-LA +khg=khg-Tibt-CN +khh=khh-Latn-ID +khj=khj-Latn-NG +khl=khl-Latn-PG +khn=khn-Deva-IN +kho=kho-Brah-IR +khp=khp-Latn-ID +khq=khq-Latn-ML +khr=khr-Latn-IN +khs=khs-Latn-PG +kht=kht-Mymr-IN +khu=khu-Latn-AO +khv=khv-Cyrl-RU +khw=khw-Arab-PK +khx=khx-Latn-CD +khy=khy-Latn-CD +khz=khz-Latn-PG +ki=ki-Latn-KE +kia=kia-Latn-TD +kib=kib-Latn-SD +kic=kic-Latn-US +kid=kid-Latn-CM +kie=kie-Latn-TD +kif=kif-Deva-NP +kig=kig-Latn-ID +kih=kih-Latn-PG +kij=kij-Latn-PG +kil=kil-Latn-NG +kim=kim-Cyrl-RU +kio=kio-Latn-US +kip=kip-Deva-NP +kiq=kiq-Latn-ID +kis=kis-Latn-PG +kit=kit-Latn-PG +kiu=kiu-Latn-TR +kiv=kiv-Latn-TZ +kiw=kiw-Latn-PG +kix=kix-Latn-IN +kiy=kiy-Latn-ID +kiz=kiz-Latn-TZ +kj=kj-Latn-NA +kja=kja-Latn-ID +kjb=kjb-Latn-GT +kjc=kjc-Latn-ID +kjd=kjd-Latn-PG +kje=kje-Latn-ID +kjg=kjg-Laoo-LA +kjh=kjh-Cyrl-RU +kji=kji-Latn-SB +kjj=kjj-Latn-AZ +kjk=kjk-Latn-ID +kjl=kjl-Deva-NP +kjm=kjm-Latn-VN +kjn=kjn-Latn-AU +kjo=kjo-Deva-IN +kjp=kjp-Mymr-MM +kjq=kjq-Latn-US +kjr=kjr-Latn-ID +kjs=kjs-Latn-PG +kjt=kjt-Thai-TH +kju=kju-Latn-US +kjx=kjx-Latn-PG +kjy=kjy-Latn-PG +kjz=kjz-Tibt-BT +kk=kk-Cyrl-KZ +kk-AF=kk-Arab-AF +kk-Arab=kk-Arab-CN +kk-CN=kk-Arab-CN +kk-IR=kk-Arab-IR +kk-MN=kk-Arab-MN +kka=kka-Latn-NG +kkb=kkb-Latn-ID +kkc=kkc-Latn-PG +kkd=kkd-Latn-NG +kke=kke-Latn-GN +kkf=kkf-Tibt-IN +kkg=kkg-Latn-PH +kkh=kkh-Lana-MM +kki=kki-Latn-TZ +kkj=kkj-Latn-CM +kkk=kkk-Latn-SB +kkl=kkl-Latn-ID +kkm=kkm-Latn-NG +kko=kko-Latn-SD +kkp=kkp-Latn-AU +kkq=kkq-Latn-CD +kkr=kkr-Latn-NG +kks=kks-Latn-NG +kkt=kkt-Deva-NP +kku=kku-Latn-NG +kkv=kkv-Latn-ID +kkw=kkw-Latn-CG +kkx=kkx-Latn-ID +kky=kky-Latn-AU +kkz=kkz-Latn-CA +kl=kl-Latn-GL +kla=kla-Latn-US +klb=klb-Latn-MX +klc=klc-Latn-CM +kld=kld-Latn-AU +kle=kle-Deva-NP +klf=klf-Latn-TD +klg=klg-Latn-PH +klh=klh-Latn-PG +kli=kli-Latn-ID +klj=klj-Arab-IR +klk=klk-Latn-NG +kll=kll-Latn-PH +klm=klm-Latn-PG +kln=kln-Latn-KE +klo=klo-Latn-NG +klp=klp-Latn-PG +klq=klq-Latn-PG +klr=klr-Deva-NP +kls=kls-Latn-PK +klt=klt-Latn-PG +klu=klu-Latn-LR +klv=klv-Latn-VU +klw=klw-Latn-ID +klx=klx-Latn-PG +kly=kly-Latn-ID +klz=klz-Latn-ID +km=km-Khmr-KH +kma=kma-Latn-GH +kmb=kmb-Latn-AO +kmc=kmc-Latn-CN +kmd=kmd-Latn-PH +kme=kme-Latn-CM +kmf=kmf-Latn-PG +kmg=kmg-Latn-PG +kmh=kmh-Latn-PG +kmi=kmi-Latn-NG +kmj=kmj-Deva-IN +kmk=kmk-Latn-PH +kml=kml-Latn-PH +kmm=kmm-Latn-IN +kmn=kmn-Latn-PG +kmo=kmo-Latn-PG +kmp=kmp-Latn-CM +kmq=kmq-Latn-ET +kms=kms-Latn-PG +kmt=kmt-Latn-ID +kmu=kmu-Latn-PG +kmv=kmv-Latn-BR +kmw=kmw-Latn-CD +kmx=kmx-Latn-PG +kmy=kmy-Latn-NG +kmz=kmz-Arab-IR +kn=kn-Knda-IN +kna=kna-Latn-NG +knb=knb-Latn-PH +knd=knd-Latn-ID +kne=kne-Latn-PH +knf=knf-Latn-GW +kni=kni-Latn-NG +knj=knj-Latn-GT +knk=knk-Latn-SL +knl=knl-Latn-ID +knm=knm-Latn-BR +knn=knn-Deva-IN +kno=kno-Latn-SL +knp=knp-Latn-CM +knq=knq-Latn-MY +knr=knr-Latn-PG +kns=kns-Latn-MY +knt=knt-Latn-BR +knu=knu-Latn-GN +knv=knv-Latn-PG +knw=knw-Latn-NA +knx=knx-Latn-ID +kny=kny-Latn-CD +knz=knz-Latn-BF +ko=ko-Kore-KR +koa=koa-Latn-PG +koc=koc-Latn-NG +kod=kod-Latn-ID +koe=koe-Latn-SS +kof=kof-Latn-NG +kog=kog-Latn-CO +koh=koh-Latn-CG +koi=koi-Cyrl-RU +kok=kok-Deva-IN +kol=kol-Latn-PG +koo=koo-Latn-UG +kop=kop-Latn-PG +koq=koq-Latn-GA +kos=kos-Latn-FM +kot=kot-Latn-CM +kou=kou-Latn-TD +kov=kov-Latn-NG +kow=kow-Latn-NG +koy=koy-Latn-US +koz=koz-Latn-PG +kpa=kpa-Latn-NG +kpc=kpc-Latn-CO +kpd=kpd-Latn-ID +kpe=kpe-Latn-LR +kpf=kpf-Latn-PG +kpg=kpg-Latn-FM +kph=kph-Latn-GH +kpi=kpi-Latn-ID +kpj=kpj-Latn-BR +kpk=kpk-Latn-NG +kpl=kpl-Latn-CD +kpm=kpm-Latn-VN +kpn=kpn-Latn-BR +kpo=kpo-Latn-TG +kpq=kpq-Latn-ID +kpr=kpr-Latn-PG +kps=kps-Latn-ID +kpt=kpt-Cyrl-RU +kpu=kpu-Latn-ID +kpw=kpw-Latn-PG +kpx=kpx-Latn-PG +kpy=kpy-Cyrl-RU +kpz=kpz-Latn-UG +kqa=kqa-Latn-PG +kqb=kqb-Latn-PG +kqc=kqc-Latn-PG +kqd=kqd-Syrc-IQ +kqe=kqe-Latn-PH +kqf=kqf-Latn-PG +kqg=kqg-Latn-BF +kqh=kqh-Latn-TZ +kqi=kqi-Latn-PG +kqj=kqj-Latn-PG +kqk=kqk-Latn-BJ +kql=kql-Latn-PG +kqm=kqm-Latn-CI +kqn=kqn-Latn-ZM +kqo=kqo-Latn-LR +kqp=kqp-Latn-TD +kqq=kqq-Latn-BR +kqr=kqr-Latn-MY +kqs=kqs-Latn-GN +kqt=kqt-Latn-MY +kqu=kqu-Latn-ZA +kqv=kqv-Latn-ID +kqw=kqw-Latn-PG +kqx=kqx-Latn-CM +kqy=kqy-Ethi-ET +kqz=kqz-Latn-ZA +kr=kr-Latn-NG +kra=kra-Deva-NP +krb=krb-Latn-US +krc=krc-Cyrl-RU +krd=krd-Latn-TL +kre=kre-Latn-BR +krf=krf-Latn-VU +krh=krh-Latn-NG +kri=kri-Latn-SL +krj=krj-Latn-PH +krk=krk-Cyrl-RU +krl=krl-Latn-RU +krn=krn-Latn-LR +krp=krp-Latn-NG +krr=krr-Khmr-KH +krs=krs-Latn-SS +krt=krt-Latn-NE +kru=kru-Deva-IN +krv=krv-Khmr-KH +krw=krw-Latn-LR +krx=krx-Latn-SN +kry=kry-Latn-AZ +krz=krz-Latn-ID +ks=ks-Arab-IN +ksb=ksb-Latn-TZ +ksc=ksc-Latn-PH +ksd=ksd-Latn-PG +kse=kse-Latn-PG +ksf=ksf-Latn-CM +ksg=ksg-Latn-SB +ksh=ksh-Latn-DE +ksi=ksi-Latn-PG +ksj=ksj-Latn-PG +ksk=ksk-Latn-US +ksl=ksl-Latn-PG +ksm=ksm-Latn-NG +ksn=ksn-Latn-PH +kso=kso-Latn-NG +ksp=ksp-Latn-CF +ksq=ksq-Latn-NG +ksr=ksr-Latn-PG +kss=kss-Latn-LR +kst=kst-Latn-BF +ksu=ksu-Mymr-IN +ksv=ksv-Latn-CD +ksw=ksw-Mymr-MM +ksx=ksx-Latn-ID +ksz=ksz-Deva-IN +kta=kta-Latn-VN +ktb=ktb-Ethi-ET +ktc=ktc-Latn-NG +ktd=ktd-Latn-AU +kte=kte-Deva-NP +ktf=ktf-Latn-CD +ktg=ktg-Latn-AU +kth=kth-Latn-TD +kti=kti-Latn-ID +ktj=ktj-Latn-CI +ktk=ktk-Latn-PG +ktl=ktl-Arab-IR +ktm=ktm-Latn-PG +ktn=ktn-Latn-BR +kto=kto-Latn-PG +ktp=ktp-Plrd-CN +ktq=ktq-Latn-PH +kts=kts-Latn-ID +ktt=ktt-Latn-ID +ktu=ktu-Latn-CD +ktv=ktv-Latn-VN +ktw=ktw-Latn-US +ktx=ktx-Latn-BR +kty=kty-Latn-CD +ktz=ktz-Latn-NA +ku=ku-Latn-TR +ku-Arab=ku-Arab-IQ +ku-LB=ku-Arab-LB +ku-Yezi=ku-Yezi-GE +kub=kub-Latn-NG +kuc=kuc-Latn-ID +kud=kud-Latn-PG +kue=kue-Latn-PG +kuf=kuf-Laoo-LA +kug=kug-Latn-NG +kuh=kuh-Latn-NG +kui=kui-Latn-BR +kuj=kuj-Latn-TZ +kuk=kuk-Latn-ID +kul=kul-Latn-NG +kum=kum-Cyrl-RU +kun=kun-Latn-ER +kuo=kuo-Latn-PG +kup=kup-Latn-PG +kuq=kuq-Latn-BR +kus=kus-Latn-GH +kut=kut-Latn-CA +kuu=kuu-Latn-US +kuv=kuv-Latn-ID +kuw=kuw-Latn-CF +kux=kux-Latn-AU +kuy=kuy-Latn-AU +kuz=kuz-Latn-CL +kv=kv-Cyrl-RU +kva=kva-Cyrl-RU +kvb=kvb-Latn-ID +kvc=kvc-Latn-PG +kvd=kvd-Latn-ID +kve=kve-Latn-MY +kvf=kvf-Latn-TD +kvg=kvg-Latn-PG +kvh=kvh-Latn-ID +kvi=kvi-Latn-TD +kvj=kvj-Latn-CM +kvl=kvl-Latn-MM +kvm=kvm-Latn-CM +kvn=kvn-Latn-CO +kvo=kvo-Latn-ID +kvp=kvp-Latn-ID +kvq=kvq-Mymr-MM +kvr=kvr-Latn-ID +kvt=kvt-Mymr-MM +kvv=kvv-Latn-ID +kvw=kvw-Latn-ID +kvx=kvx-Arab-PK +kvy=kvy-Kali-MM +kvz=kvz-Latn-ID +kw=kw-Latn-GB +kwa=kwa-Latn-BR +kwb=kwb-Latn-NG +kwc=kwc-Latn-CG +kwd=kwd-Latn-SB +kwe=kwe-Latn-ID +kwf=kwf-Latn-SB +kwg=kwg-Latn-TD +kwh=kwh-Latn-ID +kwi=kwi-Latn-CO +kwj=kwj-Latn-PG +kwk=kwk-Latn-CA +kwl=kwl-Latn-NG +kwm=kwm-Latn-NA +kwn=kwn-Latn-NA +kwo=kwo-Latn-PG +kwp=kwp-Latn-CI +kwr=kwr-Latn-ID +kws=kws-Latn-CD +kwt=kwt-Latn-ID +kwu=kwu-Latn-CM +kwv=kwv-Latn-TD +kww=kww-Latn-SR +kwy=kwy-Latn-AO +kwz=kwz-Latn-AO +kxa=kxa-Latn-PG +kxb=kxb-Latn-CI +kxc=kxc-Latn-ET +kxd=kxd-Latn-BN +kxf=kxf-Mymr-MM +kxi=kxi-Latn-MY +kxj=kxj-Latn-TD +kxk=kxk-Mymr-MM +kxm=kxm-Thai-TH +kxn=kxn-Latn-MY +kxo=kxo-Latn-BR +kxp=kxp-Arab-PK +kxq=kxq-Latn-ID +kxr=kxr-Latn-PG +kxt=kxt-Latn-PG +kxv=kxv-Latn-IN +kxw=kxw-Latn-PG +kxx=kxx-Latn-CG +kxy=kxy-Latn-VN +kxz=kxz-Latn-PG +ky=ky-Cyrl-KG +ky-Arab=ky-Arab-CN +ky-CN=ky-Arab-CN +ky-Latn=ky-Latn-TR +ky-TR=ky-Latn-TR +kya=kya-Latn-TZ +kyb=kyb-Latn-PH +kyc=kyc-Latn-PG +kyd=kyd-Latn-ID +kye=kye-Latn-GH +kyf=kyf-Latn-CI +kyg=kyg-Latn-PG +kyh=kyh-Latn-US +kyi=kyi-Latn-MY +kyj=kyj-Latn-PH +kyk=kyk-Latn-PH +kyl=kyl-Latn-US +kym=kym-Latn-CF +kyn=kyn-Latn-PH +kyo=kyo-Latn-ID +kyq=kyq-Latn-TD +kyr=kyr-Latn-BR +kys=kys-Latn-MY +kyt=kyt-Latn-ID +kyu=kyu-Kali-MM +kyv=kyv-Deva-NP +kyw=kyw-Deva-IN +kyx=kyx-Latn-PG +kyy=kyy-Latn-PG +kyz=kyz-Latn-BR +kza=kza-Latn-BF +kzb=kzb-Latn-ID +kzc=kzc-Latn-CI +kzd=kzd-Latn-ID +kze=kze-Latn-PG +kzf=kzf-Latn-ID +kzi=kzi-Latn-MY +kzk=kzk-Latn-SB +kzl=kzl-Latn-ID +kzm=kzm-Latn-ID +kzn=kzn-Latn-MW +kzo=kzo-Latn-GA +kzp=kzp-Latn-ID +kzr=kzr-Latn-CM +kzs=kzs-Latn-MY +kzu=kzu-Latn-ID +kzv=kzv-Latn-ID +kzw=kzw-Latn-BR +kzx=kzx-Latn-ID +kzy=kzy-Latn-CD +kzz=kzz-Latn-ID +la=la-Latn-VA +laa=laa-Latn-PH +lab=lab-Lina-GR +lac=lac-Latn-MX +lad=lad-Hebr-IL +lae=lae-Deva-IN +lag=lag-Latn-TZ +lah=lah-Arab-PK +lai=lai-Latn-MW +laj=laj-Latn-UG +lal=lal-Latn-CD +lam=lam-Latn-ZM +lan=lan-Latn-NG +lap=lap-Latn-TD +laq=laq-Latn-VN +lar=lar-Latn-GH +las=las-Latn-TG +lau=lau-Latn-ID +law=law-Latn-ID +lax=lax-Latn-IN +laz=laz-Latn-PG +lb=lb-Latn-LU +lbb=lbb-Latn-PG +lbe=lbe-Cyrl-RU +lbf=lbf-Deva-IN +lbi=lbi-Latn-CM +lbj=lbj-Tibt-IN +lbl=lbl-Latn-PH +lbm=lbm-Deva-IN +lbn=lbn-Latn-LA +lbo=lbo-Laoo-LA +lbq=lbq-Latn-PG +lbr=lbr-Deva-NP +lbt=lbt-Latn-VN +lbu=lbu-Latn-PG +lbv=lbv-Latn-PG +lbw=lbw-Latn-ID +lbx=lbx-Latn-ID +lby=lby-Latn-AU +lbz=lbz-Latn-AU +lcc=lcc-Latn-ID +lcd=lcd-Latn-ID +lce=lce-Latn-ID +lcf=lcf-Latn-ID +lch=lch-Latn-AO +lcl=lcl-Latn-ID +lcm=lcm-Latn-PG +lcp=lcp-Thai-CN +lcq=lcq-Latn-ID +lcs=lcs-Latn-ID +lda=lda-Latn-CI +ldb=ldb-Latn-NG +ldd=ldd-Latn-NG +ldg=ldg-Latn-NG +ldh=ldh-Latn-NG +ldi=ldi-Latn-CG +ldj=ldj-Latn-NG +ldk=ldk-Latn-NG +ldl=ldl-Latn-NG +ldm=ldm-Latn-GN +ldn=ldn-Latn-001 +ldo=ldo-Latn-NG +ldp=ldp-Latn-NG +ldq=ldq-Latn-NG +lea=lea-Latn-CD +leb=leb-Latn-ZM +lec=lec-Latn-BO +led=led-Latn-CD +lee=lee-Latn-BF +lef=lef-Latn-GH +leh=leh-Latn-ZM +lei=lei-Latn-PG +lej=lej-Latn-CD +lek=lek-Latn-PG +lel=lel-Latn-CD +lem=lem-Latn-CM +len=len-Latn-SV +leo=leo-Latn-CM +lep=lep-Lepc-IN +leq=leq-Latn-PG +ler=ler-Latn-PG +les=les-Latn-CD +let=let-Latn-PG +leu=leu-Latn-PG +lev=lev-Latn-ID +lew=lew-Latn-ID +lex=lex-Latn-ID +ley=ley-Latn-ID +lez=lez-Cyrl-RU +lfa=lfa-Latn-CM +lfn=lfn-Latn-001 +lg=lg-Latn-UG +lga=lga-Latn-SB +lgb=lgb-Latn-SB +lgg=lgg-Latn-UG +lgh=lgh-Latn-VN +lgi=lgi-Latn-ID +lgk=lgk-Latn-VU +lgl=lgl-Latn-SB +lgm=lgm-Latn-CD +lgn=lgn-Latn-ET +lgo=lgo-Latn-SS +lgq=lgq-Latn-GH +lgr=lgr-Latn-SB +lgt=lgt-Latn-PG +lgu=lgu-Latn-SB +lgz=lgz-Latn-CD +lha=lha-Latn-VN +lhh=lhh-Latn-ID +lhi=lhi-Latn-CN +lhm=lhm-Deva-NP +lhn=lhn-Latn-MY +lhs=lhs-Syrc-SY +lht=lht-Latn-VU +lhu=lhu-Latn-CN +li=li-Latn-NL +lia=lia-Latn-SL +lib=lib-Latn-PG +lic=lic-Latn-CN +lid=lid-Latn-PG +lie=lie-Latn-CD +lif=lif-Deva-NP +lif-Limb=lif-Limb-IN +lig=lig-Latn-GH +lih=lih-Latn-PG +lij=lij-Latn-IT +lik=lik-Latn-CD +lil=lil-Latn-CA +lio=lio-Latn-ID +lip=lip-Latn-GH +liq=liq-Latn-ET +lir=lir-Latn-LR +lis=lis-Lisu-CN +liu=liu-Latn-SD +liv=liv-Latn-LV +liw=liw-Latn-ID +lix=lix-Latn-ID +liy=liy-Latn-CF +liz=liz-Latn-CD +lja=lja-Latn-AU +lje=lje-Latn-ID +lji=lji-Latn-ID +ljl=ljl-Latn-ID +ljp=ljp-Latn-ID +ljw=ljw-Latn-AU +ljx=ljx-Latn-AU +lka=lka-Latn-TL +lkb=lkb-Latn-KE +lkc=lkc-Latn-VN +lkd=lkd-Latn-BR +lke=lke-Latn-UG +lkh=lkh-Tibt-BT +lki=lki-Arab-IR +lkj=lkj-Latn-MY +lkl=lkl-Latn-PG +lkm=lkm-Latn-AU +lkn=lkn-Latn-VU +lko=lko-Latn-KE +lkr=lkr-Latn-SS +lks=lks-Latn-KE +lkt=lkt-Latn-US +lku=lku-Latn-AU +lky=lky-Latn-SS +lla=lla-Latn-NG +llb=llb-Latn-MZ +llc=llc-Latn-GN +lld=lld-Latn-IT +lle=lle-Latn-PG +llf=llf-Latn-PG +llg=llg-Latn-ID +lli=lli-Latn-CG +llj=llj-Latn-AU +llk=llk-Latn-MY +lll=lll-Latn-PG +llm=llm-Latn-ID +lln=lln-Latn-TD +llp=llp-Latn-VU +llq=llq-Latn-ID +llu=llu-Latn-SB +llx=llx-Latn-FJ +lma=lma-Latn-GN +lmb=lmb-Latn-VU +lmc=lmc-Latn-AU +lmd=lmd-Latn-SD +lme=lme-Latn-TD +lmf=lmf-Latn-ID +lmg=lmg-Latn-PG +lmh=lmh-Deva-NP +lmi=lmi-Latn-CD +lmj=lmj-Latn-ID +lmk=lmk-Latn-IN +lml=lml-Latn-VU +lmn=lmn-Telu-IN +lmo=lmo-Latn-IT +lmp=lmp-Latn-CM +lmq=lmq-Latn-ID +lmr=lmr-Latn-ID +lmu=lmu-Latn-VU +lmv=lmv-Latn-FJ +lmw=lmw-Latn-US +lmx=lmx-Latn-CM +lmy=lmy-Latn-ID +ln=ln-Latn-CD +lna=lna-Latn-CF +lnb=lnb-Latn-NA +lnd=lnd-Latn-ID +lng=lng-Latn-HU +lnh=lnh-Latn-MY +lni=lni-Latn-PG +lnj=lnj-Latn-AU +lnl=lnl-Latn-CF +lnm=lnm-Latn-PG +lnn=lnn-Latn-VU +lns=lns-Latn-CM +lnu=lnu-Latn-NG +lnw=lnw-Latn-AU +lnz=lnz-Latn-CD +lo=lo-Laoo-LA +loa=loa-Latn-ID +lob=lob-Latn-BF +loc=loc-Latn-PH +loe=loe-Latn-ID +log=log-Latn-CD +loh=loh-Latn-SS +loi=loi-Latn-CI +loj=loj-Latn-PG +lok=lok-Latn-SL +lol=lol-Latn-CD +lom=lom-Latn-LR +lon=lon-Latn-MW +loo=loo-Latn-CD +lop=lop-Latn-NG +loq=loq-Latn-CD +lor=lor-Latn-CI +los=los-Latn-PG +lot=lot-Latn-SS +lou=lou-Latn-US +low=low-Latn-MY +lox=lox-Latn-ID +loy=loy-Deva-NP +loz=loz-Latn-ZM +lpa=lpa-Latn-VU +lpe=lpe-Latn-ID +lpn=lpn-Latn-MM +lpo=lpo-Plrd-CN +lpx=lpx-Latn-SS +lqr=lqr-Latn-SS +lra=lra-Latn-MY +lrc=lrc-Arab-IR +lrg=lrg-Latn-AU +lri=lri-Latn-KE +lrk=lrk-Arab-PK +lrl=lrl-Arab-IR +lrm=lrm-Latn-KE +lrn=lrn-Latn-ID +lro=lro-Latn-SD +lrt=lrt-Latn-ID +lrv=lrv-Latn-VU +lrz=lrz-Latn-VU +lsa=lsa-Arab-IR +lsd=lsd-Hebr-IL +lse=lse-Latn-CD +lsi=lsi-Latn-MM +lsm=lsm-Latn-UG +lsr=lsr-Latn-PG +lss=lss-Arab-PK +lt=lt-Latn-LT +ltc=ltc-Hant-CN +ltg=ltg-Latn-LV +lth=lth-Latn-UG +lti=lti-Latn-ID +ltn=ltn-Latn-BR +lto=lto-Latn-KE +lts=lts-Latn-KE +ltu=ltu-Latn-ID +lu=lu-Latn-CD +lua=lua-Latn-CD +luc=luc-Latn-UG +lud=lud-Latn-RU +lue=lue-Latn-ZM +luf=luf-Latn-PG +lui=lui-Latn-US +luj=luj-Latn-CD +luk=luk-Tibt-BT +lul=lul-Latn-SS +lum=lum-Latn-AO +lun=lun-Latn-ZM +luo=luo-Latn-KE +lup=lup-Latn-GA +luq=luq-Latn-CU +lur=lur-Latn-ID +lus=lus-Latn-IN +lut=lut-Latn-US +luu=luu-Deva-NP +luv=luv-Arab-OM +luw=luw-Latn-CM +luy=luy-Latn-KE +luz=luz-Arab-IR +lv=lv-Latn-LV +lva=lva-Latn-TL +lvi=lvi-Latn-LA +lvk=lvk-Latn-SB +lvl=lvl-Latn-CD +lvu=lvu-Latn-ID +lwa=lwa-Latn-CD +lwe=lwe-Latn-ID +lwg=lwg-Latn-KE +lwh=lwh-Latn-VN +lwl=lwl-Thai-TH +lwm=lwm-Thai-CN +lwo=lwo-Latn-SS +lwt=lwt-Latn-ID +lww=lww-Latn-VU +lxm=lxm-Latn-PG +lya=lya-Tibt-BT +lyn=lyn-Latn-ZM +lzh=lzh-Hans-CN +lzl=lzl-Latn-VU +lzn=lzn-Latn-MM +lzz=lzz-Latn-TR +lzz-GE=lzz-Geor-GE +lzz-Geor=lzz-Geor-GE +maa=maa-Latn-MX +mab=mab-Latn-MX +mad=mad-Latn-ID +mae=mae-Latn-NG +maf=maf-Latn-CM +mag=mag-Deva-IN +mai=mai-Deva-IN +maj=maj-Latn-MX +mak=mak-Latn-ID +mam=mam-Latn-GT +man=man-Latn-GM +man-Nkoo=man-Nkoo-GN +maq=maq-Latn-MX +mas=mas-Latn-KE +mat=mat-Latn-MX +mau=mau-Latn-MX +mav=mav-Latn-BR +maw=maw-Latn-GH +max=max-Latn-ID +maz=maz-Latn-MX +mba=mba-Latn-PH +mbb=mbb-Latn-PH +mbc=mbc-Latn-BR +mbd=mbd-Latn-PH +mbf=mbf-Latn-SG +mbh=mbh-Latn-PG +mbi=mbi-Latn-PH +mbj=mbj-Latn-BR +mbk=mbk-Latn-PG +mbl=mbl-Latn-BR +mbm=mbm-Latn-CG +mbn=mbn-Latn-CO +mbo=mbo-Latn-CM +mbp=mbp-Latn-CO +mbq=mbq-Latn-PG +mbr=mbr-Latn-CO +mbs=mbs-Latn-PH +mbt=mbt-Latn-PH +mbu=mbu-Latn-NG +mbv=mbv-Latn-GN +mbw=mbw-Latn-PG +mbx=mbx-Latn-PG +mby=mby-Arab-PK +mbz=mbz-Latn-MX +mca=mca-Latn-PY +mcb=mcb-Latn-PE +mcc=mcc-Latn-PG +mcd=mcd-Latn-PE +mce=mce-Latn-MX +mcf=mcf-Latn-PE +mcg=mcg-Latn-VE +mch=mch-Latn-VE +mci=mci-Latn-PG +mcj=mcj-Latn-NG +mck=mck-Latn-AO +mcl=mcl-Latn-CO +mcm=mcm-Latn-MY +mcn=mcn-Latn-TD +mco=mco-Latn-MX +mcp=mcp-Latn-CM +mcq=mcq-Latn-PG +mcr=mcr-Latn-PG +mcs=mcs-Latn-CM +mct=mct-Latn-CM +mcu=mcu-Latn-CM +mcv=mcv-Latn-PG +mcw=mcw-Latn-TD +mcx=mcx-Latn-CF +mcy=mcy-Latn-PG +mcz=mcz-Latn-PG +mda=mda-Latn-NG +mdb=mdb-Latn-PG +mdc=mdc-Latn-PG +mdd=mdd-Latn-CM +mde=mde-Arab-TD +mdf=mdf-Cyrl-RU +mdg=mdg-Latn-TD +mdh=mdh-Latn-PH +mdi=mdi-Latn-CD +mdj=mdj-Latn-CD +mdk=mdk-Latn-CD +mdm=mdm-Latn-CD +mdn=mdn-Latn-CF +mdp=mdp-Latn-CD +mdq=mdq-Latn-CD +mdr=mdr-Latn-ID +mds=mds-Latn-PG +mdt=mdt-Latn-CG +mdu=mdu-Latn-CG +mdv=mdv-Latn-MX +mdw=mdw-Latn-CG +mdx=mdx-Ethi-ET +mdy=mdy-Ethi-ET +mdz=mdz-Latn-BR +mea=mea-Latn-CM +meb=meb-Latn-PG +mec=mec-Latn-AU +med=med-Latn-PG +mee=mee-Latn-PG +meh=meh-Latn-MX +mej=mej-Latn-ID +mek=mek-Latn-PG +mel=mel-Latn-MY +mem=mem-Latn-AU +men=men-Latn-SL +meo=meo-Latn-MY +mep=mep-Latn-AU +meq=meq-Latn-CM +mer=mer-Latn-KE +mes=mes-Latn-TD +met=met-Latn-PG +meu=meu-Latn-PG +mev=mev-Latn-LR +mew=mew-Latn-NG +mey=mey-Latn-SN +mez=mez-Latn-US +mfa=mfa-Arab-TH +mfb=mfb-Latn-ID +mfc=mfc-Latn-CD +mfd=mfd-Latn-CM +mfe=mfe-Latn-MU +mff=mff-Latn-CM +mfg=mfg-Latn-GN +mfh=mfh-Latn-CM +mfi=mfi-Arab-CM +mfj=mfj-Latn-CM +mfk=mfk-Latn-CM +mfl=mfl-Latn-NG +mfm=mfm-Latn-NG +mfn=mfn-Latn-NG +mfo=mfo-Latn-NG +mfp=mfp-Latn-ID +mfq=mfq-Latn-TG +mfr=mfr-Latn-AU +mft=mft-Latn-PG +mfu=mfu-Latn-AO +mfv=mfv-Latn-SN +mfw=mfw-Latn-PG +mfx=mfx-Latn-ET +mfy=mfy-Latn-MX +mfz=mfz-Latn-SS +mg=mg-Latn-MG +mga=mga-Latg-IE +mgb=mgb-Latn-TD +mgc=mgc-Latn-SS +mgd=mgd-Latn-SS +mge=mge-Latn-TD +mgf=mgf-Latn-ID +mgg=mgg-Latn-CM +mgh=mgh-Latn-MZ +mgi=mgi-Latn-NG +mgj=mgj-Latn-NG +mgk=mgk-Latn-ID +mgl=mgl-Latn-PG +mgm=mgm-Latn-TL +mgn=mgn-Latn-CF +mgo=mgo-Latn-CM +mgp=mgp-Deva-NP +mgq=mgq-Latn-TZ +mgr=mgr-Latn-ZM +mgs=mgs-Latn-TZ +mgt=mgt-Latn-PG +mgu=mgu-Latn-PG +mgv=mgv-Latn-TZ +mgw=mgw-Latn-TZ +mgy=mgy-Latn-TZ +mgz=mgz-Latn-TZ +mh=mh-Latn-MH +mhb=mhb-Latn-GA +mhc=mhc-Latn-MX +mhd=mhd-Latn-TZ +mhe=mhe-Latn-MY +mhf=mhf-Latn-PG +mhg=mhg-Latn-AU +mhi=mhi-Latn-UG +mhj=mhj-Arab-AF +mhk=mhk-Latn-CM +mhl=mhl-Latn-PG +mhm=mhm-Latn-MZ +mhn=mhn-Latn-IT +mho=mho-Latn-ZM +mhp=mhp-Latn-ID +mhq=mhq-Latn-US +mhs=mhs-Latn-ID +mht=mht-Latn-VE +mhu=mhu-Latn-IN +mhw=mhw-Latn-BW +mhx=mhx-Latn-MM +mhy=mhy-Latn-ID +mhz=mhz-Latn-ID +mi=mi-Latn-NZ +mia=mia-Latn-US +mib=mib-Latn-MX +mic=mic-Latn-CA +mid=mid-Mand-IQ +mie=mie-Latn-MX +mif=mif-Latn-CM +mig=mig-Latn-MX +mih=mih-Latn-MX +mii=mii-Latn-MX +mij=mij-Latn-CM +mik=mik-Latn-US +mil=mil-Latn-MX +mim=mim-Latn-MX +min=min-Latn-ID +mio=mio-Latn-MX +mip=mip-Latn-MX +miq=miq-Latn-NI +mir=mir-Latn-MX +mit=mit-Latn-MX +miu=miu-Latn-MX +miw=miw-Latn-PG +mix=mix-Latn-MX +miy=miy-Latn-MX +miz=miz-Latn-MX +mjb=mjb-Latn-TL +mjc=mjc-Latn-MX +mjd=mjd-Latn-US +mje=mje-Latn-TD +mjg=mjg-Latn-CN +mjh=mjh-Latn-TZ +mji=mji-Latn-CN +mjj=mjj-Latn-PG +mjk=mjk-Latn-PG +mjl=mjl-Deva-IN +mjm=mjm-Latn-PG +mjn=mjn-Latn-PG +mjq=mjq-Mlym-IN +mjr=mjr-Mlym-IN +mjs=mjs-Latn-NG +mjt=mjt-Deva-IN +mju=mju-Telu-IN +mjv=mjv-Mlym-IN +mjw=mjw-Latn-IN +mjx=mjx-Latn-BD +mjy=mjy-Latn-US +mjz=mjz-Deva-NP +mk=mk-Cyrl-MK +mka=mka-Latn-CI +mkb=mkb-Deva-IN +mkc=mkc-Latn-PG +mke=mke-Deva-IN +mkf=mkf-Latn-NG +mki=mki-Arab-PK +mkj=mkj-Latn-FM +mkk=mkk-Latn-CM +mkl=mkl-Latn-BJ +mkm=mkm-Thai-TH +mkn=mkn-Latn-ID +mko=mko-Latn-NG +mkp=mkp-Latn-PG +mkr=mkr-Latn-PG +mks=mks-Latn-MX +mkt=mkt-Latn-NC +mku=mku-Latn-GN +mkv=mkv-Latn-VU +mkw=mkw-Latn-CG +mkx=mkx-Latn-PH +mky=mky-Latn-ID +mkz=mkz-Latn-TL +ml=ml-Mlym-IN +mla=mla-Latn-VU +mlb=mlb-Latn-CM +mlc=mlc-Latn-VN +mle=mle-Latn-PG +mlf=mlf-Thai-LA +mlh=mlh-Latn-PG +mli=mli-Latn-ID +mlj=mlj-Latn-TD +mlk=mlk-Latn-KE +mll=mll-Latn-VU +mln=mln-Latn-SB +mlo=mlo-Latn-SN +mlp=mlp-Latn-PG +mlq=mlq-Latn-SN +mlr=mlr-Latn-CM +mls=mls-Latn-SD +mlu=mlu-Latn-SB +mlv=mlv-Latn-VU +mlw=mlw-Latn-CM +mlx=mlx-Latn-VU +mlz=mlz-Latn-PH +mma=mma-Latn-NG +mmb=mmb-Latn-ID +mmc=mmc-Latn-MX +mmd=mmd-Latn-CN +mme=mme-Latn-VU +mmf=mmf-Latn-NG +mmg=mmg-Latn-VU +mmh=mmh-Latn-BR +mmi=mmi-Latn-PG +mmm=mmm-Latn-VU +mmn=mmn-Latn-PH +mmo=mmo-Latn-PG +mmp=mmp-Latn-PG +mmq=mmq-Latn-PG +mmr=mmr-Latn-CN +mmt=mmt-Latn-PG +mmu=mmu-Latn-CM +mmv=mmv-Latn-BR +mmw=mmw-Latn-VU +mmx=mmx-Latn-PG +mmy=mmy-Latn-TD +mmz=mmz-Latn-CD +mn=mn-Cyrl-MN +mn-CN=mn-Mong-CN +mn-Mong=mn-Mong-CN +mna=mna-Latn-PG +mnb=mnb-Latn-ID +mnc=mnc-Mong-CN +mnd=mnd-Latn-BR +mne=mne-Latn-TD +mnf=mnf-Latn-CM +mng=mng-Latn-VN +mnh=mnh-Latn-CD +mni=mni-Beng-IN +mnj=mnj-Arab-AF +mnl=mnl-Latn-VU +mnm=mnm-Latn-PG +mnn=mnn-Latn-VN +mnp=mnp-Latn-CN +mnq=mnq-Latn-MY +mnr=mnr-Latn-US +mns=mns-Cyrl-RU +mnu=mnu-Latn-ID +mnv=mnv-Latn-SB +mnw=mnw-Mymr-MM +mnx=mnx-Latn-ID +mny=mny-Latn-MZ +mnz=mnz-Latn-ID +mo=mo-Latn-RO +moa=moa-Latn-CI +moc=moc-Latn-AR +mod=mod-Latn-US +moe=moe-Latn-CA +mog=mog-Latn-ID +moh=moh-Latn-CA +moi=moi-Latn-NG +moj=moj-Latn-CG +mok=mok-Latn-ID +mom=mom-Latn-NI +moo=moo-Latn-VN +mop=mop-Latn-BZ +moq=moq-Latn-ID +mor=mor-Latn-SD +mos=mos-Latn-BF +mot=mot-Latn-CO +mou=mou-Latn-TD +mov=mov-Latn-US +mow=mow-Latn-CG +mox=mox-Latn-PG +moy=moy-Latn-ET +moz=moz-Latn-TD +mpa=mpa-Latn-TZ +mpb=mpb-Latn-AU +mpc=mpc-Latn-AU +mpd=mpd-Latn-BR +mpe=mpe-Latn-ET +mpg=mpg-Latn-TD +mph=mph-Latn-AU +mpi=mpi-Latn-CM +mpj=mpj-Latn-AU +mpk=mpk-Latn-TD +mpl=mpl-Latn-PG +mpm=mpm-Latn-MX +mpn=mpn-Latn-PG +mpo=mpo-Latn-PG +mpp=mpp-Latn-PG +mpq=mpq-Latn-BR +mpr=mpr-Latn-SB +mps=mps-Latn-PG +mpt=mpt-Latn-PG +mpu=mpu-Latn-BR +mpv=mpv-Latn-PG +mpw=mpw-Latn-BR +mpx=mpx-Latn-PG +mpy=mpy-Latn-ID +mpz=mpz-Thai-TH +mqa=mqa-Latn-ID +mqb=mqb-Latn-CM +mqc=mqc-Latn-ID +mqe=mqe-Latn-PG +mqf=mqf-Latn-ID +mqg=mqg-Latn-ID +mqh=mqh-Latn-MX +mqi=mqi-Latn-ID +mqj=mqj-Latn-ID +mqk=mqk-Latn-PH +mql=mql-Latn-BJ +mqm=mqm-Latn-PF +mqn=mqn-Latn-ID +mqo=mqo-Latn-ID +mqp=mqp-Latn-ID +mqq=mqq-Latn-MY +mqr=mqr-Latn-ID +mqs=mqs-Latn-ID +mqu=mqu-Latn-SS +mqv=mqv-Latn-PG +mqw=mqw-Latn-PG +mqx=mqx-Latn-ID +mqy=mqy-Latn-ID +mqz=mqz-Latn-PG +mr=mr-Deva-IN +mra=mra-Thai-TH +mrb=mrb-Latn-VU +mrc=mrc-Latn-US +mrd=mrd-Deva-NP +mrf=mrf-Latn-ID +mrg=mrg-Latn-IN +mrh=mrh-Latn-IN +mrj=mrj-Cyrl-RU +mrk=mrk-Latn-NC +mrl=mrl-Latn-FM +mrm=mrm-Latn-VU +mrn=mrn-Latn-SB +mro=mro-Mroo-BD +mrp=mrp-Latn-VU +mrq=mrq-Latn-PF +mrr=mrr-Deva-IN +mrs=mrs-Latn-VU +mrt=mrt-Latn-NG +mru=mru-Latn-CM +mrv=mrv-Latn-PF +mrw=mrw-Latn-PH +mrx=mrx-Latn-ID +mry=mry-Latn-PH +mrz=mrz-Latn-ID +ms=ms-Latn-MY +ms-CC=ms-Arab-CC +msb=msb-Latn-PH +msc=msc-Latn-GN +mse=mse-Latn-TD +msf=msf-Latn-ID +msg=msg-Latn-ID +msh=msh-Latn-MG +msi=msi-Latn-MY +msj=msj-Latn-CD +msk=msk-Latn-PH +msl=msl-Latn-ID +msm=msm-Latn-PH +msn=msn-Latn-VU +mso=mso-Latn-ID +msp=msp-Latn-BR +msq=msq-Latn-NC +mss=mss-Latn-ID +msu=msu-Latn-PG +msv=msv-Latn-CM +msw=msw-Latn-GW +msx=msx-Latn-PG +msy=msy-Latn-PG +msz=msz-Latn-PG +mt=mt-Latn-MT +mta=mta-Latn-PH +mtb=mtb-Latn-CI +mtc=mtc-Latn-PG +mtd=mtd-Latn-ID +mte=mte-Latn-SB +mtf=mtf-Latn-PG +mtg=mtg-Latn-ID +mth=mth-Latn-ID +mti=mti-Latn-PG +mtj=mtj-Latn-ID +mtk=mtk-Latn-CM +mtl=mtl-Latn-NG +mtm=mtm-Cyrl-RU +mtn=mtn-Latn-NI +mto=mto-Latn-MX +mtp=mtp-Latn-BO +mtq=mtq-Latn-VN +mtr=mtr-Deva-IN +mts=mts-Latn-PE +mtt=mtt-Latn-VU +mtu=mtu-Latn-MX +mtv=mtv-Latn-PG +mtw=mtw-Latn-PH +mtx=mtx-Latn-MX +mty=mty-Latn-PG +mua=mua-Latn-CM +mub=mub-Latn-TD +muc=muc-Latn-CM +mud=mud-Cyrl-RU +mue=mue-Latn-EC +mug=mug-Latn-CM +muh=muh-Latn-SS +mui=mui-Latn-ID +muj=muj-Latn-TD +muk=muk-Tibt-NP +mum=mum-Latn-PG +muo=muo-Latn-CM +muq=muq-Latn-CN +mur=mur-Latn-SS +mus=mus-Latn-US +mut=mut-Deva-IN +muu=muu-Latn-KE +muv=muv-Taml-IN +mux=mux-Latn-PG +muy=muy-Latn-CM +muz=muz-Ethi-ET +mva=mva-Latn-PG +mvd=mvd-Latn-ID +mve=mve-Arab-PK +mvf=mvf-Mong-CN +mvg=mvg-Latn-MX +mvh=mvh-Latn-TD +mvk=mvk-Latn-PG +mvl=mvl-Latn-AU +mvn=mvn-Latn-PG +mvo=mvo-Latn-SB +mvp=mvp-Latn-ID +mvq=mvq-Latn-PG +mvr=mvr-Latn-ID +mvs=mvs-Latn-ID +mvt=mvt-Latn-VU +mvu=mvu-Latn-TD +mvv=mvv-Latn-MY +mvw=mvw-Latn-TZ +mvx=mvx-Latn-ID +mvy=mvy-Arab-PK +mvz=mvz-Ethi-ET +mwa=mwa-Latn-PG +mwb=mwb-Latn-PG +mwc=mwc-Latn-PG +mwe=mwe-Latn-TZ +mwf=mwf-Latn-AU +mwg=mwg-Latn-PG +mwh=mwh-Latn-PG +mwi=mwi-Latn-VU +mwk=mwk-Latn-ML +mwl=mwl-Latn-PT +mwm=mwm-Latn-TD +mwn=mwn-Latn-ZM +mwo=mwo-Latn-VU +mwp=mwp-Latn-AU +mwq=mwq-Latn-MM +mwr=mwr-Deva-IN +mws=mws-Latn-KE +mwt=mwt-Mymr-MM +mwu=mwu-Latn-SS +mwv=mwv-Latn-ID +mww=mww-Hmnp-US +mwz=mwz-Latn-CD +mxa=mxa-Latn-MX +mxb=mxb-Latn-MX +mxc=mxc-Latn-ZW +mxd=mxd-Latn-ID +mxe=mxe-Latn-VU +mxf=mxf-Latn-CM +mxg=mxg-Latn-AO +mxh=mxh-Latn-CD +mxi=mxi-Latn-ES +mxj=mxj-Latn-IN +mxk=mxk-Latn-PG +mxl=mxl-Latn-BJ +mxm=mxm-Latn-PG +mxn=mxn-Latn-ID +mxo=mxo-Latn-ZM +mxp=mxp-Latn-MX +mxq=mxq-Latn-MX +mxr=mxr-Latn-MY +mxs=mxs-Latn-MX +mxt=mxt-Latn-MX +mxu=mxu-Latn-CM +mxv=mxv-Latn-MX +mxw=mxw-Latn-PG +mxx=mxx-Latn-CI +mxy=mxy-Latn-MX +mxz=mxz-Latn-ID +my=my-Mymr-MM +myb=myb-Latn-TD +myc=myc-Latn-CD +mye=mye-Latn-GA +myf=myf-Latn-ET +myg=myg-Latn-CM +myh=myh-Latn-US +myj=myj-Latn-SS +myk=myk-Latn-ML +myl=myl-Latn-ID +mym=mym-Ethi-ET +myp=myp-Latn-BR +myr=myr-Latn-PE +myu=myu-Latn-BR +myv=myv-Cyrl-RU +myw=myw-Latn-PG +myx=myx-Latn-UG +myy=myy-Latn-CO +myz=myz-Mand-IR +mza=mza-Latn-MX +mzd=mzd-Latn-CM +mze=mze-Latn-PG +mzh=mzh-Latn-AR +mzi=mzi-Latn-MX +mzj=mzj-Latn-LR +mzk=mzk-Latn-NG +mzl=mzl-Latn-MX +mzm=mzm-Latn-NG +mzn=mzn-Arab-IR +mzo=mzo-Latn-BR +mzp=mzp-Latn-BO +mzq=mzq-Latn-ID +mzr=mzr-Latn-BR +mzt=mzt-Latn-MY +mzu=mzu-Latn-PG +mzv=mzv-Latn-CF +mzw=mzw-Latn-GH +mzx=mzx-Latn-GY +mzz=mzz-Latn-PG +na=na-Latn-NR +naa=naa-Latn-ID +nab=nab-Latn-BR +nac=nac-Latn-PG +nae=nae-Latn-ID +naf=naf-Latn-PG +nag=nag-Latn-IN +naj=naj-Latn-GN +nak=nak-Latn-PG +nal=nal-Latn-PG +nam=nam-Latn-AU +nan=nan-Hans-CN +nan-Hant=nan-Hant-TW +nan-TW=nan-Hant-TW +nao=nao-Deva-NP +nap=nap-Latn-IT +naq=naq-Latn-NA +nar=nar-Latn-NG +nas=nas-Latn-PG +nat=nat-Latn-NG +naw=naw-Latn-GH +nax=nax-Latn-PG +nay=nay-Latn-AU +naz=naz-Latn-MX +nb=nb-Latn-NO +nba=nba-Latn-AO +nbb=nbb-Latn-NG +nbc=nbc-Latn-IN +nbd=nbd-Latn-CD +nbe=nbe-Latn-IN +nbh=nbh-Latn-NG +nbi=nbi-Latn-IN +nbj=nbj-Latn-AU +nbk=nbk-Latn-PG +nbm=nbm-Latn-CF +nbn=nbn-Latn-ID +nbo=nbo-Latn-NG +nbp=nbp-Latn-NG +nbq=nbq-Latn-ID +nbr=nbr-Latn-NG +nbt=nbt-Latn-IN +nbu=nbu-Latn-IN +nbv=nbv-Latn-CM +nbw=nbw-Latn-CD +nby=nby-Latn-PG +nca=nca-Latn-PG +ncb=ncb-Latn-IN +ncc=ncc-Latn-PG +ncd=ncd-Deva-NP +nce=nce-Latn-PG +ncf=ncf-Latn-PG +ncg=ncg-Latn-CA +nch=nch-Latn-MX +nci=nci-Latn-MX +ncj=ncj-Latn-MX +nck=nck-Latn-AU +ncl=ncl-Latn-MX +ncm=ncm-Latn-PG +ncn=ncn-Latn-PG +nco=nco-Latn-PG +ncq=ncq-Laoo-LA +ncr=ncr-Latn-CM +nct=nct-Latn-IN +ncu=ncu-Latn-GH +ncx=ncx-Latn-MX +ncz=ncz-Latn-US +nd=nd-Latn-ZW +nda=nda-Latn-CG +ndb=ndb-Latn-CM +ndc=ndc-Latn-MZ +ndd=ndd-Latn-NG +ndf=ndf-Cyrl-RU +ndg=ndg-Latn-TZ +ndh=ndh-Latn-TZ +ndi=ndi-Latn-NG +ndj=ndj-Latn-TZ +ndk=ndk-Latn-CD +ndl=ndl-Latn-CD +ndm=ndm-Latn-TD +ndn=ndn-Latn-CG +ndp=ndp-Latn-UG +ndq=ndq-Latn-AO +ndr=ndr-Latn-NG +nds=nds-Latn-DE +ndt=ndt-Latn-CD +ndu=ndu-Latn-CM +ndv=ndv-Latn-SN +ndw=ndw-Latn-CD +ndx=ndx-Latn-ID +ndy=ndy-Latn-CF +ndz=ndz-Latn-SS +ne=ne-Deva-NP +nea=nea-Latn-ID +neb=neb-Latn-CI +nec=nec-Latn-ID +ned=ned-Latn-NG +nee=nee-Latn-NC +neg=neg-Cyrl-RU +neh=neh-Tibt-BT +nei=nei-Xsux-TR +nej=nej-Latn-PG +nek=nek-Latn-NC +nem=nem-Latn-NC +nen=nen-Latn-NC +neo=neo-Latn-VN +neq=neq-Latn-MX +ner=ner-Latn-ID +net=net-Latn-PG +neu=neu-Latn-001 +new=new-Deva-NP +nex=nex-Latn-PG +ney=ney-Latn-CI +nez=nez-Latn-US +nfa=nfa-Latn-ID +nfd=nfd-Latn-NG +nfl=nfl-Latn-SB +nfr=nfr-Latn-GH +nfu=nfu-Latn-CM +ng=ng-Latn-NA +nga=nga-Latn-CD +ngb=ngb-Latn-CD +ngc=ngc-Latn-CD +ngd=ngd-Latn-CF +nge=nge-Latn-CM +ngg=ngg-Latn-CF +ngh=ngh-Latn-ZA +ngi=ngi-Latn-NG +ngj=ngj-Latn-CM +ngk=ngk-Latn-AU +ngl=ngl-Latn-MZ +ngm=ngm-Latn-FM +ngn=ngn-Latn-CM +ngp=ngp-Latn-TZ +ngq=ngq-Latn-TZ +ngr=ngr-Latn-SB +ngs=ngs-Latn-NG +ngt=ngt-Laoo-LA +ngu=ngu-Latn-MX +ngv=ngv-Latn-CM +ngw=ngw-Latn-NG +ngx=ngx-Latn-NG +ngy=ngy-Latn-CM +ngz=ngz-Latn-CG +nha=nha-Latn-AU +nhb=nhb-Latn-CI +nhc=nhc-Latn-MX +nhd=nhd-Latn-PY +nhe=nhe-Latn-MX +nhf=nhf-Latn-AU +nhg=nhg-Latn-MX +nhi=nhi-Latn-MX +nhk=nhk-Latn-MX +nhm=nhm-Latn-MX +nhn=nhn-Latn-MX +nho=nho-Latn-PG +nhp=nhp-Latn-MX +nhq=nhq-Latn-MX +nhr=nhr-Latn-BW +nht=nht-Latn-MX +nhu=nhu-Latn-CM +nhv=nhv-Latn-MX +nhw=nhw-Latn-MX +nhx=nhx-Latn-MX +nhy=nhy-Latn-MX +nhz=nhz-Latn-MX +nia=nia-Latn-ID +nib=nib-Latn-PG +nid=nid-Latn-AU +nie=nie-Latn-TD +nif=nif-Latn-PG +nig=nig-Latn-AU +nih=nih-Latn-TZ +nii=nii-Latn-PG +nij=nij-Latn-ID +nil=nil-Latn-ID +nim=nim-Latn-TZ +nin=nin-Latn-NG +nio=nio-Cyrl-RU +niq=niq-Latn-KE +nir=nir-Latn-ID +nis=nis-Latn-PG +nit=nit-Telu-IN +niu=niu-Latn-NU +niv=niv-Cyrl-RU +niw=niw-Latn-PG +nix=nix-Latn-CD +niy=niy-Latn-CD +niz=niz-Latn-PG +nja=nja-Latn-NG +njb=njb-Latn-IN +njd=njd-Latn-TZ +njh=njh-Latn-IN +nji=nji-Latn-AU +njj=njj-Latn-CM +njl=njl-Latn-SS +njm=njm-Latn-IN +njn=njn-Latn-IN +njo=njo-Latn-IN +njr=njr-Latn-NG +njs=njs-Latn-ID +njt=njt-Latn-SR +nju=nju-Latn-AU +njx=njx-Latn-CG +njy=njy-Latn-CM +njz=njz-Latn-IN +nka=nka-Latn-ZM +nkb=nkb-Latn-IN +nkc=nkc-Latn-CM +nkd=nkd-Latn-IN +nke=nke-Latn-SB +nkf=nkf-Latn-IN +nkg=nkg-Latn-PG +nkh=nkh-Latn-IN +nki=nki-Latn-IN +nkj=nkj-Latn-ID +nkk=nkk-Latn-VU +nkm=nkm-Latn-PG +nkn=nkn-Latn-AO +nko=nko-Latn-GH +nkq=nkq-Latn-GH +nkr=nkr-Latn-FM +nks=nks-Latn-ID +nkt=nkt-Latn-TZ +nku=nku-Latn-CI +nkv=nkv-Latn-MW +nkw=nkw-Latn-CD +nkx=nkx-Latn-NG +nkz=nkz-Latn-NG +nl=nl-Latn-NL +nla=nla-Latn-CM +nlc=nlc-Latn-ID +nle=nle-Latn-KE +nlg=nlg-Latn-SB +nli=nli-Arab-AF +nlj=nlj-Latn-CD +nlk=nlk-Latn-ID +nlm=nlm-Arab-PK +nlo=nlo-Latn-CD +nlq=nlq-Latn-MM +nlu=nlu-Latn-GH +nlv=nlv-Latn-MX +nlw=nlw-Latn-AU +nlx=nlx-Deva-IN +nly=nly-Latn-AU +nlz=nlz-Latn-SB +nma=nma-Latn-IN +nmb=nmb-Latn-VU +nmc=nmc-Latn-TD +nmd=nmd-Latn-GA +nme=nme-Latn-IN +nmf=nmf-Latn-IN +nmg=nmg-Latn-CM +nmh=nmh-Latn-IN +nmi=nmi-Latn-NG +nmj=nmj-Latn-CF +nmk=nmk-Latn-VU +nml=nml-Latn-CM +nmm=nmm-Deva-NP +nmn=nmn-Latn-BW +nmo=nmo-Latn-IN +nmp=nmp-Latn-AU +nmq=nmq-Latn-ZW +nmr=nmr-Latn-CM +nms=nms-Latn-VU +nmt=nmt-Latn-FM +nmu=nmu-Latn-US +nmv=nmv-Latn-AU +nmw=nmw-Latn-PG +nmx=nmx-Latn-PG +nmz=nmz-Latn-TG +nn=nn-Latn-NO +nna=nna-Latn-AU +nnb=nnb-Latn-CD +nnc=nnc-Latn-TD +nnd=nnd-Latn-VU +nne=nne-Latn-AO +nnf=nnf-Latn-PG +nng=nng-Latn-IN +nnh=nnh-Latn-CM +nni=nni-Latn-ID +nnj=nnj-Latn-ET +nnk=nnk-Latn-PG +nnl=nnl-Latn-IN +nnm=nnm-Latn-PG +nnn=nnn-Latn-TD +nnp=nnp-Wcho-IN +nnq=nnq-Latn-TZ +nnr=nnr-Latn-AU +nnt=nnt-Latn-US +nnu=nnu-Latn-GH +nnv=nnv-Latn-AU +nnw=nnw-Latn-BF +nny=nny-Latn-AU +nnz=nnz-Latn-CM +no=no-Latn-NO +noa=noa-Latn-CO +noc=noc-Latn-PG +nod=nod-Lana-TH +noe=noe-Deva-IN +nof=nof-Latn-PG +nog=nog-Cyrl-RU +noh=noh-Latn-PG +noi=noi-Deva-IN +noj=noj-Latn-CO +nok=nok-Latn-US +non=non-Runr-SE +nop=nop-Latn-PG +noq=noq-Latn-CD +nos=nos-Yiii-CN +not=not-Latn-PE +nou=nou-Latn-PG +nov=nov-Latn-001 +now=now-Latn-TZ +noy=noy-Latn-TD +npb=npb-Tibt-BT +npg=npg-Latn-MM +nph=nph-Latn-IN +npl=npl-Latn-MX +npn=npn-Latn-PG +npo=npo-Latn-IN +nps=nps-Latn-ID +npu=npu-Latn-IN +npx=npx-Latn-SB +npy=npy-Latn-ID +nqg=nqg-Latn-BJ +nqk=nqk-Latn-BJ +nql=nql-Latn-AO +nqm=nqm-Latn-ID +nqn=nqn-Latn-PG +nqo=nqo-Nkoo-GN +nqq=nqq-Latn-MM +nqt=nqt-Latn-NG +nqy=nqy-Latn-MM +nr=nr-Latn-ZA +nra=nra-Latn-GA +nrb=nrb-Latn-ER +nre=nre-Latn-IN +nrf=nrf-Latn-JE +nrg=nrg-Latn-VU +nri=nri-Latn-IN +nrk=nrk-Latn-AU +nrl=nrl-Latn-AU +nrm=nrm-Latn-MY +nrn=nrn-Runr-GB +nrp=nrp-Latn-IT +nru=nru-Latn-CN +nrx=nrx-Latn-AU +nrz=nrz-Latn-PG +nsa=nsa-Latn-IN +nsb=nsb-Latn-ZA +nsc=nsc-Latn-NG +nsd=nsd-Yiii-CN +nse=nse-Latn-ZM +nsf=nsf-Yiii-CN +nsg=nsg-Latn-TZ +nsh=nsh-Latn-CM +nsk=nsk-Cans-CA +nsm=nsm-Latn-IN +nsn=nsn-Latn-PG +nso=nso-Latn-ZA +nsq=nsq-Latn-US +nss=nss-Latn-PG +nst=nst-Tnsa-IN +nsu=nsu-Latn-MX +nsv=nsv-Yiii-CN +nsw=nsw-Latn-VU +nsx=nsx-Latn-AO +nsy=nsy-Latn-ID +nsz=nsz-Latn-US +ntd=ntd-Latn-MY +nte=nte-Latn-MZ +ntg=ntg-Latn-AU +nti=nti-Latn-BF +ntj=ntj-Latn-AU +ntk=ntk-Latn-TZ +ntm=ntm-Latn-BJ +nto=nto-Latn-CD +ntp=ntp-Latn-MX +ntr=ntr-Latn-GH +ntu=ntu-Latn-SB +ntx=ntx-Latn-MM +nty=nty-Yiii-VN +ntz=ntz-Arab-IR +nua=nua-Latn-NC +nuc=nuc-Latn-BR +nud=nud-Latn-PG +nue=nue-Latn-CD +nuf=nuf-Latn-CN +nug=nug-Latn-AU +nuh=nuh-Latn-NG +nui=nui-Latn-GQ +nuj=nuj-Latn-UG +nuk=nuk-Latn-CA +num=num-Latn-TO +nun=nun-Latn-MM +nuo=nuo-Latn-VN +nup=nup-Latn-NG +nuq=nuq-Latn-PG +nur=nur-Latn-PG +nus=nus-Latn-SS +nut=nut-Latn-VN +nuu=nuu-Latn-CD +nuv=nuv-Latn-BF +nuw=nuw-Latn-FM +nux=nux-Latn-PG +nuy=nuy-Latn-AU +nuz=nuz-Latn-MX +nv=nv-Latn-US +nvh=nvh-Latn-VU +nvm=nvm-Latn-PG +nvo=nvo-Latn-CM +nwb=nwb-Latn-CI +nwc=nwc-Newa-NP +nwe=nwe-Latn-CM +nwg=nwg-Latn-AU +nwi=nwi-Latn-VU +nwm=nwm-Latn-SS +nwo=nwo-Latn-AU +nwr=nwr-Latn-PG +nww=nww-Latn-TZ +nwx=nwx-Deva-NP +nxa=nxa-Latn-TL +nxd=nxd-Latn-CD +nxe=nxe-Latn-ID +nxg=nxg-Latn-ID +nxi=nxi-Latn-TZ +nxl=nxl-Latn-ID +nxn=nxn-Latn-AU +nxo=nxo-Latn-GA +nxq=nxq-Latn-CN +nxr=nxr-Latn-PG +nxx=nxx-Latn-ID +ny=ny-Latn-MW +nyb=nyb-Latn-GH +nyc=nyc-Latn-CD +nyd=nyd-Latn-KE +nye=nye-Latn-AO +nyf=nyf-Latn-KE +nyg=nyg-Latn-CD +nyh=nyh-Latn-AU +nyi=nyi-Latn-SD +nyj=nyj-Latn-CD +nyk=nyk-Latn-AO +nyl=nyl-Thai-TH +nym=nym-Latn-TZ +nyn=nyn-Latn-UG +nyo=nyo-Latn-UG +nyp=nyp-Latn-UG +nyq=nyq-Arab-IR +nyr=nyr-Latn-MW +nys=nys-Latn-AU +nyt=nyt-Latn-AU +nyu=nyu-Latn-MZ +nyv=nyv-Latn-AU +nyw=nyw-Thai-TH +nyx=nyx-Latn-AU +nyy=nyy-Latn-TZ +nza=nza-Latn-CM +nzb=nzb-Latn-GA +nzd=nzd-Latn-CD +nzi=nzi-Latn-GH +nzk=nzk-Latn-CF +nzm=nzm-Latn-IN +nzr=nzr-Latn-NG +nzu=nzu-Latn-CG +nzy=nzy-Latn-TD +nzz=nzz-Latn-ML +oaa=oaa-Cyrl-RU +oac=oac-Cyrl-RU +oar=oar-Syrc-SY +oav=oav-Geor-GE +obi=obi-Latn-US +obk=obk-Latn-PH +obl=obl-Latn-CM +obm=obm-Phnx-JO +obo=obo-Latn-PH +obr=obr-Mymr-MM +obt=obt-Latn-FR +obu=obu-Latn-NG +oc=oc-Latn-FR +oca=oca-Latn-PE +oco=oco-Latn-GB +ocu=ocu-Latn-MX +oda=oda-Latn-NG +odk=odk-Arab-PK +odt=odt-Latn-NL +odu=odu-Latn-NG +ofs=ofs-Latn-NL +ofu=ofu-Latn-NG +ogb=ogb-Latn-NG +ogc=ogc-Latn-NG +ogg=ogg-Latn-NG +ogo=ogo-Latn-NG +ogu=ogu-Latn-NG +oht=oht-Xsux-TR +ohu=ohu-Latn-HU +oia=oia-Latn-ID +oie=oie-Latn-SS +oin=oin-Latn-PG +oj=oj-Cans-CA +ojb=ojb-Latn-CA +ojc=ojc-Latn-CA +ojs=ojs-Cans-CA +ojv=ojv-Latn-SB +ojw=ojw-Latn-CA +oka=oka-Latn-CA +okb=okb-Latn-NG +okc=okc-Latn-CD +okd=okd-Latn-NG +oke=oke-Latn-NG +okg=okg-Latn-AU +oki=oki-Latn-KE +okk=okk-Latn-PG +okm=okm-Hang-KR +oko=oko-Hani-KR +okr=okr-Latn-NG +oks=oks-Latn-NG +oku=oku-Latn-CM +okv=okv-Latn-PG +okx=okx-Latn-NG +okz=okz-Khmr-KH +ola=ola-Deva-NP +old=old-Latn-TZ +ole=ole-Tibt-BT +olk=olk-Latn-AU +olm=olm-Latn-NG +olo=olo-Latn-RU +olr=olr-Latn-VU +olt=olt-Latn-LT +olu=olu-Latn-AO +om=om-Latn-ET +oma=oma-Latn-US +omb=omb-Latn-VU +omc=omc-Latn-PE +omg=omg-Latn-PE +omi=omi-Latn-CD +omk=omk-Cyrl-RU +oml=oml-Latn-CD +omo=omo-Latn-PG +omp=omp-Mtei-IN +omr=omr-Modi-IN +omt=omt-Latn-KE +omu=omu-Latn-PE +omw=omw-Latn-PG +omx=omx-Mymr-MM +ona=ona-Latn-AR +one=one-Latn-CA +ong=ong-Latn-PG +oni=oni-Latn-ID +onj=onj-Latn-PG +onk=onk-Latn-PG +onn=onn-Latn-PG +ono=ono-Latn-CA +onp=onp-Latn-IN +onr=onr-Latn-PG +ons=ons-Latn-PG +ont=ont-Latn-PG +onu=onu-Latn-VU +onx=onx-Latn-ID +ood=ood-Latn-US +oon=oon-Deva-IN +oor=oor-Latn-ZA +opa=opa-Latn-NG +opk=opk-Latn-ID +opm=opm-Latn-PG +opo=opo-Latn-PG +opt=opt-Latn-MX +opy=opy-Latn-BR +or=or-Orya-IN +ora=ora-Latn-SB +orc=orc-Latn-KE +ore=ore-Latn-PE +org=org-Latn-NG +orn=orn-Latn-MY +oro=oro-Latn-PG +orr=orr-Latn-NG +ors=ors-Latn-MY +ort=ort-Telu-IN +oru=oru-Arab-PK +orv=orv-Cyrl-RU +orw=orw-Latn-BR +orx=orx-Latn-NG +orz=orz-Latn-ID +os=os-Cyrl-GE +osa=osa-Osge-US +osc=osc-Ital-IT +osi=osi-Java-ID +oso=oso-Latn-NG +osp=osp-Latn-ES +ost=ost-Latn-CM +osu=osu-Latn-PG +osx=osx-Latn-DE +ota=ota-Arab-TR +otb=otb-Tibt-CN +otd=otd-Latn-ID +ote=ote-Latn-MX +oti=oti-Latn-BR +otk=otk-Orkh-MN +otl=otl-Latn-MX +otm=otm-Latn-MX +otn=otn-Latn-MX +otq=otq-Latn-MX +otr=otr-Latn-SD +ots=ots-Latn-MX +ott=ott-Latn-MX +otu=otu-Latn-BR +otw=otw-Latn-CA +otx=otx-Latn-MX +oty=oty-Gran-IN +otz=otz-Latn-MX +oub=oub-Latn-LR +oue=oue-Latn-PG +oui=oui-Ougr-CN +oum=oum-Latn-PG +ovd=ovd-Latn-SE +owi=owi-Latn-PG +owl=owl-Latn-GB +oyd=oyd-Latn-ET +oym=oym-Latn-BR +oyy=oyy-Latn-PG +ozm=ozm-Latn-CM +pa=pa-Guru-IN +pa-Arab=pa-Arab-PK +pa-PK=pa-Arab-PK +pab=pab-Latn-BR +pac=pac-Latn-VN +pad=pad-Latn-BR +pae=pae-Latn-CD +paf=paf-Latn-BR +pag=pag-Latn-PH +pah=pah-Latn-BR +pai=pai-Latn-NG +pak=pak-Latn-BR +pal=pal-Phli-IR +pal-Phlp=pal-Phlp-CN +pam=pam-Latn-PH +pao=pao-Latn-US +pap=pap-Latn-CW +paq=paq-Cyrl-TJ +par=par-Latn-US +pas=pas-Latn-ID +pau=pau-Latn-PW +pav=pav-Latn-BR +paw=paw-Latn-US +pax=pax-Latn-BR +pay=pay-Latn-HN +paz=paz-Latn-BR +pbb=pbb-Latn-CO +pbc=pbc-Latn-GY +pbe=pbe-Latn-MX +pbf=pbf-Latn-MX +pbg=pbg-Latn-VE +pbh=pbh-Latn-VE +pbi=pbi-Latn-CM +pbl=pbl-Latn-NG +pbm=pbm-Latn-MX +pbn=pbn-Latn-NG +pbo=pbo-Latn-GW +pbp=pbp-Latn-GN +pbr=pbr-Latn-TZ +pbs=pbs-Latn-MX +pbt=pbt-Arab-AF +pbv=pbv-Latn-IN +pby=pby-Latn-PG +pca=pca-Latn-MX +pcb=pcb-Khmr-KH +pcc=pcc-Latn-CN +pcd=pcd-Latn-FR +pce=pce-Mymr-MM +pcf=pcf-Mlym-IN +pcg=pcg-Mlym-IN +pch=pch-Deva-IN +pci=pci-Deva-IN +pcj=pcj-Telu-IN +pck=pck-Latn-IN +pcm=pcm-Latn-NG +pcn=pcn-Latn-NG +pcp=pcp-Latn-BO +pcw=pcw-Latn-NG +pda=pda-Latn-PG +pdc=pdc-Latn-US +pdn=pdn-Latn-ID +pdo=pdo-Latn-ID +pdt=pdt-Latn-CA +pdu=pdu-Latn-MM +pea=pea-Latn-ID +peb=peb-Latn-US +ped=ped-Latn-PG +pee=pee-Latn-ID +peg=peg-Orya-IN +pei=pei-Latn-MX +pek=pek-Latn-PG +pel=pel-Latn-ID +pem=pem-Latn-CD +peo=peo-Xpeo-IR +pep=pep-Latn-PG +peq=peq-Latn-US +pev=pev-Latn-VE +pex=pex-Latn-PG +pey=pey-Latn-ID +pez=pez-Latn-MY +pfa=pfa-Latn-FM +pfe=pfe-Latn-CM +pfl=pfl-Latn-DE +pga=pga-Latn-SS +pgd=pgd-Khar-PK +pgg=pgg-Deva-IN +pgi=pgi-Latn-PG +pgk=pgk-Latn-VU +pgl=pgl-Ogam-IE +pgn=pgn-Ital-IT +pgs=pgs-Latn-NG +pgu=pgu-Latn-ID +phd=phd-Deva-IN +phg=phg-Latn-VN +phh=phh-Latn-VN +phk=phk-Mymr-IN +phl=phl-Arab-PK +phm=phm-Latn-MZ +phn=phn-Phnx-LB +pho=pho-Laoo-LA +phr=phr-Arab-PK +pht=pht-Thai-TH +phu=phu-Thai-TH +phv=phv-Arab-AF +phw=phw-Deva-NP +pi=pi-Sinh-IN +pia=pia-Latn-MX +pib=pib-Latn-PE +pic=pic-Latn-GA +pid=pid-Latn-VE +pif=pif-Latn-FM +pig=pig-Latn-PE +pih=pih-Latn-NF +pij=pij-Latn-CO +pil=pil-Latn-BJ +pim=pim-Latn-US +pin=pin-Latn-PG +pio=pio-Latn-CO +pip=pip-Latn-NG +pir=pir-Latn-BR +pis=pis-Latn-SB +pit=pit-Latn-AU +piu=piu-Latn-AU +piv=piv-Latn-SB +piw=piw-Latn-TZ +pix=pix-Latn-PG +piy=piy-Latn-NG +piz=piz-Latn-NC +pjt=pjt-Latn-AU +pka=pka-Brah-IN +pkb=pkb-Latn-KE +pkg=pkg-Latn-PG +pkh=pkh-Latn-BD +pkn=pkn-Latn-AU +pko=pko-Latn-KE +pkp=pkp-Latn-CK +pkr=pkr-Mlym-IN +pku=pku-Latn-ID +pl=pl-Latn-PL +pla=pla-Latn-PG +plb=plb-Latn-VU +plc=plc-Latn-PH +pld=pld-Latn-GB +ple=ple-Latn-ID +plg=plg-Latn-AR +plh=plh-Latn-ID +plk=plk-Arab-PK +pll=pll-Mymr-MM +pln=pln-Latn-CO +plo=plo-Latn-MX +plr=plr-Latn-CI +pls=pls-Latn-MX +plu=plu-Latn-BR +plv=plv-Latn-PH +plw=plw-Latn-PH +plz=plz-Latn-MY +pma=pma-Latn-VU +pmb=pmb-Latn-CD +pmd=pmd-Latn-AU +pme=pme-Latn-NC +pmf=pmf-Latn-ID +pmh=pmh-Brah-IN +pmi=pmi-Latn-CN +pmj=pmj-Latn-CN +pml=pml-Latn-TN +pmm=pmm-Latn-CM +pmn=pmn-Latn-CM +pmo=pmo-Latn-ID +pmq=pmq-Latn-MX +pmr=pmr-Latn-PG +pms=pms-Latn-IT +pmt=pmt-Latn-PF +pmw=pmw-Latn-US +pmx=pmx-Latn-IN +pmy=pmy-Latn-ID +pmz=pmz-Latn-MX +pna=pna-Latn-MY +pnc=pnc-Latn-ID +pnd=pnd-Latn-AO +pne=pne-Latn-MY +png=png-Latn-NG +pnh=pnh-Latn-CK +pni=pni-Latn-ID +pnj=pnj-Latn-AU +pnk=pnk-Latn-BO +pnl=pnl-Latn-BF +pnm=pnm-Latn-MY +pnn=pnn-Latn-PG +pno=pno-Latn-PE +pnp=pnp-Latn-ID +pnq=pnq-Latn-BF +pnr=pnr-Latn-PG +pns=pns-Latn-ID +pnt=pnt-Grek-GR +pnt-Cyrl=pnt-Cyrl-RU +pnt-Latn=pnt-Latn-TR +pnt-RU=pnt-Cyrl-RU +pnt-TR=pnt-Latn-TR +pnv=pnv-Latn-AU +pnw=pnw-Latn-AU +pny=pny-Latn-CM +pnz=pnz-Latn-CF +poc=poc-Latn-GT +poe=poe-Latn-MX +pof=pof-Latn-CD +pog=pog-Latn-BR +poh=poh-Latn-GT +poi=poi-Latn-MX +pok=pok-Latn-BR +pom=pom-Latn-US +pon=pon-Latn-FM +poo=poo-Latn-US +pop=pop-Latn-NC +poq=poq-Latn-MX +pos=pos-Latn-MX +pot=pot-Latn-US +pov=pov-Latn-GW +pow=pow-Latn-MX +poy=poy-Latn-TZ +ppe=ppe-Latn-PG +ppi=ppi-Latn-MX +ppk=ppk-Latn-ID +ppl=ppl-Latn-SV +ppm=ppm-Latn-ID +ppn=ppn-Latn-PG +ppo=ppo-Latn-PG +ppp=ppp-Latn-CD +ppq=ppq-Latn-PG +pps=pps-Latn-MX +ppt=ppt-Latn-PG +pqa=pqa-Latn-NG +pqm=pqm-Latn-CA +pra=pra-Khar-PK +prc=prc-Arab-AF +prd=prd-Arab-IR +pre=pre-Latn-ST +prf=prf-Latn-PH +prg=prg-Latn-PL +prh=prh-Latn-PH +pri=pri-Latn-NC +prk=prk-Latn-MM +prm=prm-Latn-PG +pro=pro-Latn-FR +prq=prq-Latn-PE +prr=prr-Latn-BR +prt=prt-Thai-TH +pru=pru-Latn-ID +prw=prw-Latn-PG +prx=prx-Arab-IN +ps=ps-Arab-AF +psa=psa-Latn-ID +pse=pse-Latn-ID +psh=psh-Arab-AF +psi=psi-Arab-AF +psm=psm-Latn-BO +psn=psn-Latn-ID +psq=psq-Latn-PG +pss=pss-Latn-PG +pst=pst-Arab-PK +psu=psu-Brah-IN +psw=psw-Latn-VU +pt=pt-Latn-BR +pta=pta-Latn-PY +pth=pth-Latn-BR +pti=pti-Latn-AU +ptn=ptn-Latn-ID +pto=pto-Latn-BR +ptp=ptp-Latn-PG +ptr=ptr-Latn-VU +ptt=ptt-Latn-ID +ptu=ptu-Latn-ID +ptv=ptv-Latn-VU +pua=pua-Latn-MX +pub=pub-Latn-IN +puc=puc-Latn-ID +pud=pud-Latn-ID +pue=pue-Latn-AR +puf=puf-Latn-ID +pug=pug-Latn-BF +pui=pui-Latn-CO +puj=puj-Latn-ID +pum=pum-Deva-NP +puo=puo-Latn-VN +pup=pup-Latn-PG +puq=puq-Latn-BO +pur=pur-Latn-BR +put=put-Latn-ID +puu=puu-Latn-GA +puw=puw-Latn-FM +pux=pux-Latn-PG +puy=puy-Latn-US +pwa=pwa-Latn-PG +pwb=pwb-Latn-NG +pwg=pwg-Latn-PG +pwm=pwm-Latn-PH +pwn=pwn-Latn-TW +pwo=pwo-Mymr-MM +pwr=pwr-Deva-IN +pww=pww-Thai-TH +pxm=pxm-Latn-MX +pye=pye-Latn-CI +pym=pym-Latn-NG +pyn=pyn-Latn-BR +pyu=pyu-Latn-TW +pyx=pyx-Mymr-MM +pyy=pyy-Latn-MM +pze=pze-Latn-NG +pzh=pzh-Latn-TW +pzn=pzn-Latn-MM +qu=qu-Latn-PE +qua=qua-Latn-US +qub=qub-Latn-PE +quc=quc-Latn-GT +qud=qud-Latn-EC +quf=quf-Latn-PE +qug=qug-Latn-EC +qui=qui-Latn-US +quk=quk-Latn-PE +qul=qul-Latn-BO +qum=qum-Latn-GT +qun=qun-Latn-US +qup=qup-Latn-PE +quq=quq-Latn-ES +qur=qur-Latn-PE +qus=qus-Latn-AR +quv=quv-Latn-GT +quw=quw-Latn-EC +qux=qux-Latn-PE +quy=quy-Latn-PE +qva=qva-Latn-PE +qvc=qvc-Latn-PE +qve=qve-Latn-PE +qvh=qvh-Latn-PE +qvi=qvi-Latn-EC +qvj=qvj-Latn-EC +qvl=qvl-Latn-PE +qvm=qvm-Latn-PE +qvn=qvn-Latn-PE +qvo=qvo-Latn-PE +qvp=qvp-Latn-PE +qvs=qvs-Latn-PE +qvw=qvw-Latn-PE +qvz=qvz-Latn-EC +qwa=qwa-Latn-PE +qwc=qwc-Latn-PE +qwh=qwh-Latn-PE +qwm=qwm-Latn-HU +qws=qws-Latn-PE +qwt=qwt-Latn-US +qxa=qxa-Latn-PE +qxc=qxc-Latn-PE +qxh=qxh-Latn-PE +qxl=qxl-Latn-EC +qxn=qxn-Latn-PE +qxo=qxo-Latn-PE +qxp=qxp-Latn-PE +qxq=qxq-Arab-IR +qxr=qxr-Latn-EC +qxt=qxt-Latn-PE +qxu=qxu-Latn-PE +qxw=qxw-Latn-PE +qya=qya-Latn-001 +qyp=qyp-Latn-US +raa=raa-Deva-NP +rab=rab-Deva-NP +rac=rac-Latn-ID +rad=rad-Latn-VN +raf=raf-Deva-NP +rag=rag-Latn-KE +rah=rah-Beng-IN +rai=rai-Latn-PG +raj=raj-Deva-IN +rak=rak-Latn-PG +ram=ram-Latn-BR +ran=ran-Latn-ID +rao=rao-Latn-PG +rap=rap-Latn-CL +rar=rar-Latn-CK +rav=rav-Deva-NP +raw=raw-Latn-MM +rax=rax-Latn-NG +ray=ray-Latn-PF +raz=raz-Latn-ID +rbb=rbb-Mymr-MM +rbk=rbk-Latn-PH +rbl=rbl-Latn-PH +rbp=rbp-Latn-AU +rcf=rcf-Latn-RE +rdb=rdb-Arab-IR +rea=rea-Latn-PG +reb=reb-Latn-ID +ree=ree-Latn-MY +reg=reg-Latn-TZ +rei=rei-Orya-IN +rej=rej-Latn-ID +rel=rel-Latn-KE +rem=rem-Latn-PE +ren=ren-Latn-VN +res=res-Latn-NG +ret=ret-Latn-ID +rey=rey-Latn-BO +rga=rga-Latn-VU +rgn=rgn-Latn-IT +rgr=rgr-Latn-PE +rgs=rgs-Latn-VN +rgu=rgu-Latn-ID +rhg=rhg-Rohg-MM +rhp=rhp-Latn-PG +ria=ria-Latn-IN +rif=rif-Latn-MA +ril=ril-Latn-MM +rim=rim-Latn-TZ +rin=rin-Latn-NG +rir=rir-Latn-ID +rit=rit-Latn-AU +riu=riu-Latn-ID +rjg=rjg-Latn-ID +rji=rji-Deva-NP +rjs=rjs-Deva-NP +rka=rka-Khmr-KH +rkb=rkb-Latn-BR +rkh=rkh-Latn-CK +rki=rki-Mymr-MM +rkm=rkm-Latn-BF +rkt=rkt-Beng-BD +rkw=rkw-Latn-AU +rm=rm-Latn-CH +rma=rma-Latn-NI +rmb=rmb-Latn-AU +rmc=rmc-Latn-SK +rmd=rmd-Latn-DK +rme=rme-Latn-GB +rmf=rmf-Latn-FI +rmg=rmg-Latn-NO +rmh=rmh-Latn-ID +rmi=rmi-Armn-AM +rmk=rmk-Latn-PG +rml=rml-Latn-PL +rmm=rmm-Latn-ID +rmn=rmn-Latn-RS +rmo=rmo-Latn-CH +rmp=rmp-Latn-PG +rmq=rmq-Latn-ES +rmt=rmt-Arab-IR +rmu=rmu-Latn-SE +rmw=rmw-Latn-GB +rmx=rmx-Latn-VN +rmz=rmz-Mymr-IN +rn=rn-Latn-BI +rnd=rnd-Latn-CD +rng=rng-Latn-MZ +rnl=rnl-Latn-IN +rnn=rnn-Latn-ID +rnr=rnr-Latn-AU +rnw=rnw-Latn-TZ +ro=ro-Latn-RO +rob=rob-Latn-ID +roc=roc-Latn-VN +rod=rod-Latn-NG +roe=roe-Latn-PG +rof=rof-Latn-TZ +rog=rog-Latn-VN +rol=rol-Latn-PH +rom=rom-Latn-RO +roo=roo-Latn-PG +rop=rop-Latn-AU +ror=ror-Latn-ID +rou=rou-Latn-TD +row=row-Latn-ID +rpn=rpn-Latn-VU +rpt=rpt-Latn-PG +rri=rri-Latn-SB +rrm=rrm-Latn-NZ +rro=rro-Latn-PG +rrt=rrt-Latn-AU +rsk=rsk-Cyrl-RS +rsw=rsw-Latn-NG +rtc=rtc-Latn-MM +rth=rth-Latn-ID +rtm=rtm-Latn-FJ +rtw=rtw-Deva-IN +ru=ru-Cyrl-RU +rub=rub-Latn-UG +ruc=ruc-Latn-UG +rue=rue-Cyrl-UA +ruf=ruf-Latn-TZ +rug=rug-Latn-SB +rui=rui-Latn-TZ +ruk=ruk-Latn-NG +ruo=ruo-Latn-HR +rup=rup-Latn-RO +ruq=ruq-Latn-GR +rut=rut-Cyrl-RU +ruu=ruu-Latn-MY +ruy=ruy-Latn-NG +ruz=ruz-Latn-NG +rw=rw-Latn-RW +rwa=rwa-Latn-PG +rwk=rwk-Latn-TZ +rwl=rwl-Latn-TZ +rwm=rwm-Latn-UG +rwo=rwo-Latn-PG +rwr=rwr-Deva-IN +rxd=rxd-Latn-AU +rxw=rxw-Latn-AU +ryu=ryu-Kana-JP +sa=sa-Deva-IN +saa=saa-Latn-TD +sab=sab-Latn-PA +sac=sac-Latn-US +sad=sad-Latn-TZ +sae=sae-Latn-BR +saf=saf-Latn-GH +sah=sah-Cyrl-RU +saj=saj-Latn-ID +sak=sak-Latn-GA +sam=sam-Samr-PS +sao=sao-Latn-ID +saq=saq-Latn-KE +sar=sar-Latn-BO +sas=sas-Latn-ID +sat=sat-Olck-IN +sau=sau-Latn-ID +sav=sav-Latn-SN +saw=saw-Latn-ID +sax=sax-Latn-VU +say=say-Latn-NG +saz=saz-Saur-IN +sba=sba-Latn-TD +sbb=sbb-Latn-SB +sbc=sbc-Latn-PG +sbd=sbd-Latn-BF +sbe=sbe-Latn-PG +sbg=sbg-Latn-ID +sbh=sbh-Latn-PG +sbi=sbi-Latn-PG +sbj=sbj-Latn-TD +sbk=sbk-Latn-TZ +sbl=sbl-Latn-PH +sbm=sbm-Latn-TZ +sbn=sbn-Arab-PK +sbo=sbo-Latn-MY +sbp=sbp-Latn-TZ +sbq=sbq-Latn-PG +sbr=sbr-Latn-ID +sbs=sbs-Latn-NA +sbt=sbt-Latn-ID +sbu=sbu-Tibt-IN +sbv=sbv-Latn-IT +sbw=sbw-Latn-GA +sbx=sbx-Latn-ID +sby=sby-Latn-ZM +sbz=sbz-Latn-CF +sc=sc-Latn-IT +scb=scb-Latn-VN +sce=sce-Latn-CN +scf=scf-Latn-PA +scg=scg-Latn-ID +sch=sch-Latn-IN +sci=sci-Latn-LK +sck=sck-Deva-IN +scl=scl-Arab-PK +scn=scn-Latn-IT +sco=sco-Latn-GB +scp=scp-Deva-NP +scs=scs-Latn-CA +sct=sct-Laoo-LA +scu=scu-Takr-IN +scv=scv-Latn-NG +scw=scw-Latn-NG +scx=scx-Grek-IT +sd=sd-Arab-PK +sd-Deva=sd-Deva-IN +sd-IN=sd-Deva-IN +sd-Khoj=sd-Khoj-IN +sd-Sind=sd-Sind-IN +sda=sda-Latn-ID +sdb=sdb-Arab-IQ +sdc=sdc-Latn-IT +sde=sde-Latn-NG +sdf=sdf-Arab-IQ +sdg=sdg-Arab-AF +sdh=sdh-Arab-IR +sdj=sdj-Latn-CG +sdk=sdk-Latn-PG +sdn=sdn-Latn-IT +sdo=sdo-Latn-MY +sdq=sdq-Latn-ID +sdr=sdr-Beng-BD +sds=sds-Arab-TN +sdu=sdu-Latn-ID +sdx=sdx-Latn-MY +se=se-Latn-NO +sea=sea-Latn-MY +seb=seb-Latn-CI +sec=sec-Latn-CA +sed=sed-Latn-VN +see=see-Latn-US +sef=sef-Latn-CI +seg=seg-Latn-TZ +seh=seh-Latn-MZ +sei=sei-Latn-MX +sej=sej-Latn-PG +sek=sek-Latn-CA +sel=sel-Cyrl-RU +sen=sen-Latn-BF +seo=seo-Latn-PG +sep=sep-Latn-BF +seq=seq-Latn-BF +ser=ser-Latn-US +ses=ses-Latn-ML +set=set-Latn-ID +seu=seu-Latn-ID +sev=sev-Latn-CI +sew=sew-Latn-PG +sey=sey-Latn-EC +sez=sez-Latn-MM +sfe=sfe-Latn-PH +sfm=sfm-Plrd-CN +sfw=sfw-Latn-GH +sg=sg-Latn-CF +sga=sga-Latn-IE +sgb=sgb-Latn-PH +sgc=sgc-Latn-KE +sgd=sgd-Latn-PH +sge=sge-Latn-ID +sgh=sgh-Cyrl-TJ +sgi=sgi-Latn-CM +sgj=sgj-Deva-IN +sgm=sgm-Latn-KE +sgp=sgp-Latn-IN +sgr=sgr-Arab-IR +sgs=sgs-Latn-LT +sgt=sgt-Tibt-BT +sgu=sgu-Latn-ID +sgw=sgw-Ethi-ET +sgy=sgy-Arab-AF +sgz=sgz-Latn-PG +sha=sha-Latn-NG +shb=shb-Latn-BR +shc=shc-Latn-CD +shd=shd-Arab-PK +she=she-Latn-ET +shg=shg-Latn-BW +shh=shh-Latn-US +shi=shi-Tfng-MA +shj=shj-Latn-SD +shk=shk-Latn-SS +shm=shm-Arab-IR +shn=shn-Mymr-MM +sho=sho-Latn-NG +shp=shp-Latn-PE +shq=shq-Latn-ZM +shr=shr-Latn-CD +shs=shs-Latn-CA +sht=sht-Latn-US +shu=shu-Arab-TD +shv=shv-Arab-OM +shw=shw-Latn-SD +shy=shy-Latn-DZ +shz=shz-Latn-ML +si=si-Sinh-LK +sia=sia-Cyrl-RU +sib=sib-Latn-MY +sid=sid-Latn-ET +sie=sie-Latn-ZM +sif=sif-Latn-BF +sig=sig-Latn-GH +sih=sih-Latn-NC +sii=sii-Latn-IN +sij=sij-Latn-PG +sik=sik-Latn-BR +sil=sil-Latn-GH +sim=sim-Latn-PG +sip=sip-Tibt-IN +siq=siq-Latn-PG +sir=sir-Latn-NG +sis=sis-Latn-US +siu=siu-Latn-PG +siv=siv-Latn-PG +siw=siw-Latn-PG +six=six-Latn-PG +siy=siy-Arab-IR +siz=siz-Arab-EG +sja=sja-Latn-CO +sjb=sjb-Latn-ID +sjd=sjd-Cyrl-RU +sje=sje-Latn-SE +sjg=sjg-Latn-TD +sjl=sjl-Latn-IN +sjm=sjm-Latn-PH +sjp=sjp-Deva-IN +sjr=sjr-Latn-PG +sjt=sjt-Cyrl-RU +sju=sju-Latn-SE +sjw=sjw-Latn-US +sk=sk-Latn-SK +ska=ska-Latn-US +skb=skb-Thai-TH +skc=skc-Latn-PG +skd=skd-Latn-US +ske=ske-Latn-VU +skf=skf-Latn-BR +skg=skg-Latn-MG +skh=skh-Latn-ID +ski=ski-Latn-ID +skj=skj-Deva-NP +skm=skm-Latn-PG +skn=skn-Latn-PH +sko=sko-Latn-ID +skp=skp-Latn-MY +skq=skq-Latn-BF +skr=skr-Arab-PK +sks=sks-Latn-PG +skt=skt-Latn-CD +sku=sku-Latn-VU +skv=skv-Latn-ID +skw=skw-Latn-GY +skx=skx-Latn-ID +sky=sky-Latn-SB +skz=skz-Latn-ID +sl=sl-Latn-SI +slc=slc-Latn-CO +sld=sld-Latn-BF +slg=slg-Latn-ID +slh=slh-Latn-US +sli=sli-Latn-PL +slj=slj-Latn-BR +sll=sll-Latn-PG +slm=slm-Latn-PH +sln=sln-Latn-US +slp=slp-Latn-ID +slr=slr-Latn-CN +slu=slu-Latn-ID +slw=slw-Latn-PG +slx=slx-Latn-CD +sly=sly-Latn-ID +slz=slz-Latn-ID +sm=sm-Latn-WS +sma=sma-Latn-SE +smb=smb-Latn-PG +smc=smc-Latn-PG +smf=smf-Latn-PG +smg=smg-Latn-PG +smh=smh-Yiii-CN +smj=smj-Latn-SE +smk=smk-Latn-PH +sml=sml-Latn-PH +smn=smn-Latn-FI +smp=smp-Samr-IL +smq=smq-Latn-PG +smr=smr-Latn-ID +sms=sms-Latn-FI +smt=smt-Latn-IN +smu=smu-Khmr-KH +smw=smw-Latn-ID +smx=smx-Latn-CD +smy=smy-Arab-IR +smz=smz-Latn-PG +sn=sn-Latn-ZW +snc=snc-Latn-PG +sne=sne-Latn-MY +snf=snf-Latn-SN +sng=sng-Latn-CD +sni=sni-Latn-PE +snj=snj-Latn-CF +snk=snk-Latn-ML +snl=snl-Latn-PH +snm=snm-Latn-UG +snn=snn-Latn-CO +sno=sno-Latn-US +snp=snp-Latn-PG +snq=snq-Latn-GA +snr=snr-Latn-PG +sns=sns-Latn-VU +snu=snu-Latn-ID +snv=snv-Latn-MY +snw=snw-Latn-GH +snx=snx-Latn-PG +sny=sny-Latn-PG +snz=snz-Latn-PG +so=so-Latn-SO +soa=soa-Tavt-TH +sob=sob-Latn-ID +soc=soc-Latn-CD +sod=sod-Latn-CD +soe=soe-Latn-CD +sog=sog-Sogd-UZ +soi=soi-Deva-NP +sok=sok-Latn-TD +sol=sol-Latn-PG +soo=soo-Latn-CD +sop=sop-Latn-CD +soq=soq-Latn-PG +sor=sor-Latn-TD +sos=sos-Latn-BF +sou=sou-Thai-TH +sov=sov-Latn-PW +sow=sow-Latn-PG +sox=sox-Latn-CM +soy=soy-Latn-BJ +soz=soz-Latn-TZ +spb=spb-Latn-ID +spc=spc-Latn-VE +spd=spd-Latn-PG +spe=spe-Latn-PG +spg=spg-Latn-MY +spi=spi-Latn-ID +spk=spk-Latn-PG +spl=spl-Latn-PG +spm=spm-Latn-PG +spn=spn-Latn-PY +spo=spo-Latn-US +spp=spp-Latn-ML +spq=spq-Latn-PE +spr=spr-Latn-ID +sps=sps-Latn-PG +spt=spt-Tibt-IN +spv=spv-Orya-IN +sq=sq-Latn-AL +sqa=sqa-Latn-NG +sqh=sqh-Latn-NG +sqm=sqm-Latn-CF +sqo=sqo-Arab-IR +sqq=sqq-Laoo-LA +sqt=sqt-Arab-YE +squ=squ-Latn-CA +sr=sr-Cyrl-RS +sr-ME=sr-Latn-ME +sr-RO=sr-Latn-RO +sr-TR=sr-Latn-TR +sra=sra-Latn-PG +srb=srb-Sora-IN +sre=sre-Latn-ID +srf=srf-Latn-PG +srg=srg-Latn-PH +srh=srh-Arab-CN +sri=sri-Latn-CO +srk=srk-Latn-MY +srl=srl-Latn-ID +srm=srm-Latn-SR +srn=srn-Latn-SR +sro=sro-Latn-IT +srq=srq-Latn-BO +srr=srr-Latn-SN +srs=srs-Latn-CA +srt=srt-Latn-ID +sru=sru-Latn-BR +srv=srv-Latn-PH +srw=srw-Latn-ID +srx=srx-Deva-IN +sry=sry-Latn-PG +srz=srz-Arab-IR +ss=ss-Latn-ZA +ssb=ssb-Latn-PH +ssc=ssc-Latn-TZ +ssd=ssd-Latn-PG +sse=sse-Latn-PH +ssf=ssf-Latn-TW +ssg=ssg-Latn-PG +ssh=ssh-Arab-AE +ssj=ssj-Latn-PG +ssl=ssl-Latn-GH +ssm=ssm-Latn-MY +ssn=ssn-Latn-KE +sso=sso-Latn-PG +ssq=ssq-Latn-ID +sss=sss-Laoo-LA +sst=sst-Latn-PG +ssu=ssu-Latn-PG +ssv=ssv-Latn-VU +ssx=ssx-Latn-PG +ssy=ssy-Latn-ER +ssz=ssz-Latn-PG +st=st-Latn-ZA +sta=sta-Latn-ZM +stb=stb-Latn-PH +ste=ste-Latn-ID +stf=stf-Latn-PG +stg=stg-Latn-VN +sth=sth-Latn-IE +sti=sti-Latn-VN +stj=stj-Latn-BF +stk=stk-Latn-PG +stl=stl-Latn-NL +stm=stm-Latn-PG +stn=stn-Latn-SB +sto=sto-Latn-CA +stp=stp-Latn-MX +stq=stq-Latn-DE +str=str-Latn-CA +sts=sts-Arab-AF +stt=stt-Latn-VN +stv=stv-Ethi-ET +stw=stw-Latn-FM +sty=sty-Cyrl-RU +su=su-Latn-ID +sua=sua-Latn-PG +sub=sub-Latn-CD +suc=suc-Latn-PH +sue=sue-Latn-PG +sug=sug-Latn-PG +sui=sui-Latn-PG +suj=suj-Latn-TZ +suk=suk-Latn-TZ +suo=suo-Latn-PG +suq=suq-Latn-ET +sur=sur-Latn-NG +sus=sus-Latn-GN +sut=sut-Latn-NI +suv=suv-Latn-IN +suw=suw-Latn-TZ +suy=suy-Latn-BR +suz=suz-Sunu-NP +sv=sv-Latn-SE +sva=sva-Geor-GE +svb=svb-Latn-PG +svc=svc-Latn-VC +sve=sve-Latn-ID +svm=svm-Latn-IT +svs=svs-Latn-SB +sw=sw-Latn-TZ +swb=swb-Arab-YT +swf=swf-Latn-CD +swg=swg-Latn-DE +swi=swi-Hani-CN +swj=swj-Latn-GA +swk=swk-Latn-MW +swm=swm-Latn-PG +swo=swo-Latn-BR +swp=swp-Latn-PG +swq=swq-Latn-CM +swr=swr-Latn-ID +sws=sws-Latn-ID +swt=swt-Latn-ID +swu=swu-Latn-ID +swv=swv-Deva-IN +sww=sww-Latn-VU +swx=swx-Latn-BR +swy=swy-Latn-TD +sxb=sxb-Latn-KE +sxe=sxe-Latn-GA +sxn=sxn-Latn-ID +sxr=sxr-Latn-TW +sxs=sxs-Latn-NG +sxu=sxu-Runr-DE +sxw=sxw-Latn-BJ +sya=sya-Latn-ID +syb=syb-Latn-PH +syc=syc-Syrc-TR +syi=syi-Latn-GA +syk=syk-Latn-NG +syl=syl-Beng-BD +sym=sym-Latn-BF +syn=syn-Syrc-IR +syo=syo-Latn-KH +syr=syr-Syrc-IQ +sys=sys-Latn-TD +syw=syw-Deva-NP +syx=syx-Latn-GA +sza=sza-Latn-MY +szb=szb-Latn-ID +szc=szc-Latn-MY +szg=szg-Latn-CD +szl=szl-Latn-PL +szn=szn-Latn-ID +szp=szp-Latn-ID +szv=szv-Latn-CM +szw=szw-Latn-ID +szy=szy-Latn-TW +ta=ta-Taml-IN +taa=taa-Latn-US +tab=tab-Cyrl-RU +tac=tac-Latn-MX +tad=tad-Latn-ID +tae=tae-Latn-BR +taf=taf-Latn-BR +tag=tag-Latn-SD +taj=taj-Deva-NP +tak=tak-Latn-NG +tal=tal-Latn-NG +tan=tan-Latn-NG +tao=tao-Latn-TW +tap=tap-Latn-CD +taq=taq-Latn-ML +tar=tar-Latn-MX +tas=tas-Latn-VN +tau=tau-Latn-US +tav=tav-Latn-CO +taw=taw-Latn-PG +tax=tax-Latn-TD +tay=tay-Latn-TW +taz=taz-Latn-SD +tba=tba-Latn-BR +tbc=tbc-Latn-PG +tbd=tbd-Latn-PG +tbe=tbe-Latn-SB +tbf=tbf-Latn-PG +tbg=tbg-Latn-PG +tbh=tbh-Latn-AU +tbi=tbi-Latn-SD +tbj=tbj-Latn-PG +tbk=tbk-Tagb-PH +tbl=tbl-Latn-PH +tbm=tbm-Latn-CD +tbn=tbn-Latn-CO +tbo=tbo-Latn-PG +tbp=tbp-Latn-ID +tbs=tbs-Latn-PG +tbt=tbt-Latn-CD +tbu=tbu-Latn-MX +tbv=tbv-Latn-PG +tbw=tbw-Latn-PH +tbx=tbx-Latn-PG +tby=tby-Latn-ID +tbz=tbz-Latn-BJ +tca=tca-Latn-BR +tcb=tcb-Latn-US +tcc=tcc-Latn-TZ +tcd=tcd-Latn-GH +tce=tce-Latn-CA +tcf=tcf-Latn-MX +tcg=tcg-Latn-ID +tch=tch-Latn-TC +tci=tci-Latn-PG +tck=tck-Latn-GA +tcm=tcm-Latn-ID +tcn=tcn-Tibt-NP +tco=tco-Mymr-MM +tcp=tcp-Latn-MM +tcq=tcq-Latn-ID +tcs=tcs-Latn-AU +tcu=tcu-Latn-MX +tcw=tcw-Latn-MX +tcx=tcx-Taml-IN +tcy=tcy-Knda-IN +tcz=tcz-Latn-IN +tda=tda-Tfng-NE +tdb=tdb-Deva-IN +tdc=tdc-Latn-CO +tdd=tdd-Tale-CN +tde=tde-Latn-ML +tdg=tdg-Deva-NP +tdh=tdh-Deva-NP +tdi=tdi-Latn-ID +tdj=tdj-Latn-ID +tdk=tdk-Latn-NG +tdl=tdl-Latn-NG +tdm=tdm-Latn-GY +tdn=tdn-Latn-ID +tdo=tdo-Latn-NG +tdq=tdq-Latn-NG +tdr=tdr-Latn-VN +tds=tds-Latn-ID +tdt=tdt-Latn-TL +tdv=tdv-Latn-NG +tdx=tdx-Latn-MG +tdy=tdy-Latn-PH +te=te-Telu-IN +tea=tea-Latn-MY +teb=teb-Latn-EC +tec=tec-Latn-KE +ted=ted-Latn-CI +tee=tee-Latn-MX +teg=teg-Latn-GA +teh=teh-Latn-AR +tei=tei-Latn-PG +tek=tek-Latn-CD +tem=tem-Latn-SL +ten=ten-Latn-CO +teo=teo-Latn-UG +tep=tep-Latn-MX +teq=teq-Latn-SD +ter=ter-Latn-BR +tes=tes-Java-ID +tet=tet-Latn-TL +teu=teu-Latn-UG +tev=tev-Latn-ID +tew=tew-Latn-US +tex=tex-Latn-SS +tey=tey-Latn-SD +tez=tez-Latn-NE +tfi=tfi-Latn-BJ +tfn=tfn-Latn-US +tfo=tfo-Latn-ID +tfr=tfr-Latn-PA +tft=tft-Latn-ID +tg=tg-Cyrl-TJ +tg-Arab=tg-Arab-PK +tg-PK=tg-Arab-PK +tga=tga-Latn-KE +tgb=tgb-Latn-MY +tgc=tgc-Latn-PG +tgd=tgd-Latn-NG +tge=tge-Deva-NP +tgf=tgf-Tibt-BT +tgh=tgh-Latn-TT +tgi=tgi-Latn-PG +tgj=tgj-Latn-IN +tgn=tgn-Latn-PH +tgo=tgo-Latn-PG +tgp=tgp-Latn-VU +tgq=tgq-Latn-MY +tgs=tgs-Latn-VU +tgt=tgt-Latn-PH +tgu=tgu-Latn-PG +tgv=tgv-Latn-BR +tgw=tgw-Latn-CI +tgx=tgx-Latn-CA +tgy=tgy-Latn-SS +tgz=tgz-Latn-AU +th=th-Thai-TH +thd=thd-Latn-AU +the=the-Deva-NP +thf=thf-Deva-NP +thh=thh-Latn-MX +thi=thi-Tale-LA +thk=thk-Latn-KE +thl=thl-Deva-NP +thm=thm-Thai-TH +thp=thp-Latn-CA +thq=thq-Deva-NP +thr=thr-Deva-NP +ths=ths-Deva-NP +tht=tht-Latn-CA +thu=thu-Latn-SS +thv=thv-Latn-DZ +thy=thy-Latn-NG +thz=thz-Latn-NE +ti=ti-Ethi-ET +tic=tic-Latn-SD +tif=tif-Latn-PG +tig=tig-Ethi-ER +tih=tih-Latn-MY +tii=tii-Latn-CD +tij=tij-Deva-NP +tik=tik-Latn-CM +til=til-Latn-US +tim=tim-Latn-PG +tin=tin-Cyrl-RU +tio=tio-Latn-PG +tip=tip-Latn-ID +tiq=tiq-Latn-BF +tis=tis-Latn-PH +tit=tit-Latn-CO +tiu=tiu-Latn-PH +tiv=tiv-Latn-NG +tiw=tiw-Latn-AU +tix=tix-Latn-US +tiy=tiy-Latn-PH +tja=tja-Latn-LR +tjg=tjg-Latn-ID +tji=tji-Latn-CN +tjj=tjj-Latn-AU +tjl=tjl-Mymr-MM +tjn=tjn-Latn-CI +tjo=tjo-Arab-DZ +tjp=tjp-Latn-AU +tjs=tjs-Latn-CN +tju=tju-Latn-AU +tjw=tjw-Latn-AU +tk=tk-Latn-TM +tka=tka-Latn-BR +tkb=tkb-Deva-IN +tkd=tkd-Latn-TL +tke=tke-Latn-MZ +tkf=tkf-Latn-BR +tkg=tkg-Latn-MG +tkl=tkl-Latn-TK +tkp=tkp-Latn-SB +tkq=tkq-Latn-NG +tkr=tkr-Latn-AZ +tks=tks-Arab-IR +tkt=tkt-Deva-NP +tku=tku-Latn-MX +tkv=tkv-Latn-PG +tkw=tkw-Latn-SB +tkx=tkx-Latn-ID +tkz=tkz-Latn-VN +tl=tl-Latn-PH +tla=tla-Latn-MX +tlb=tlb-Latn-ID +tlc=tlc-Latn-MX +tld=tld-Latn-ID +tlf=tlf-Latn-PG +tlg=tlg-Latn-ID +tli=tli-Latn-US +tlj=tlj-Latn-UG +tlk=tlk-Latn-ID +tll=tll-Latn-CD +tlm=tlm-Latn-VU +tln=tln-Latn-ID +tlp=tlp-Latn-MX +tlq=tlq-Latn-MM +tlr=tlr-Latn-SB +tls=tls-Latn-VU +tlt=tlt-Latn-ID +tlu=tlu-Latn-ID +tlv=tlv-Latn-ID +tlx=tlx-Latn-PG +tly=tly-Latn-AZ +tma=tma-Latn-TD +tmb=tmb-Latn-VU +tmc=tmc-Latn-TD +tmd=tmd-Latn-PG +tme=tme-Latn-BR +tmf=tmf-Latn-PY +tmg=tmg-Latn-ID +tmh=tmh-Latn-NE +tmi=tmi-Latn-VU +tmj=tmj-Latn-ID +tml=tml-Latn-ID +tmm=tmm-Latn-VN +tmn=tmn-Latn-ID +tmo=tmo-Latn-MY +tmq=tmq-Latn-PG +tmr=tmr-Syrc-IL +tmt=tmt-Latn-VU +tmu=tmu-Latn-ID +tmv=tmv-Latn-CD +tmw=tmw-Latn-MY +tmy=tmy-Latn-PG +tmz=tmz-Latn-VE +tn=tn-Latn-ZA +tna=tna-Latn-BO +tnb=tnb-Latn-CO +tnc=tnc-Latn-CO +tnd=tnd-Latn-CO +tng=tng-Latn-TD +tnh=tnh-Latn-PG +tni=tni-Latn-ID +tnk=tnk-Latn-VU +tnl=tnl-Latn-VU +tnm=tnm-Latn-ID +tnn=tnn-Latn-VU +tno=tno-Latn-BO +tnp=tnp-Latn-VU +tnq=tnq-Latn-PR +tnr=tnr-Latn-SN +tns=tns-Latn-PG +tnt=tnt-Latn-ID +tnv=tnv-Cakm-BD +tnw=tnw-Latn-ID +tnx=tnx-Latn-SB +tny=tny-Latn-TZ +to=to-Latn-TO +tob=tob-Latn-AR +toc=toc-Latn-MX +tod=tod-Latn-GN +tof=tof-Latn-PG +tog=tog-Latn-MW +toh=toh-Latn-MZ +toi=toi-Latn-ZM +toj=toj-Latn-MX +tok=tok-Latn-001 +tol=tol-Latn-US +tom=tom-Latn-ID +too=too-Latn-MX +top=top-Latn-MX +toq=toq-Latn-SS +tor=tor-Latn-CD +tos=tos-Latn-MX +tou=tou-Latn-VN +tov=tov-Arab-IR +tow=tow-Latn-US +tox=tox-Latn-PW +toy=toy-Latn-ID +toz=toz-Latn-CM +tpa=tpa-Latn-PG +tpc=tpc-Latn-MX +tpe=tpe-Latn-BD +tpf=tpf-Latn-ID +tpg=tpg-Latn-ID +tpi=tpi-Latn-PG +tpj=tpj-Latn-PY +tpk=tpk-Latn-BR +tpl=tpl-Latn-MX +tpm=tpm-Latn-GH +tpn=tpn-Latn-BR +tpp=tpp-Latn-MX +tpr=tpr-Latn-BR +tpt=tpt-Latn-MX +tpu=tpu-Khmr-KH +tpv=tpv-Latn-MP +tpx=tpx-Latn-MX +tpy=tpy-Latn-BR +tpz=tpz-Latn-PG +tqb=tqb-Latn-BR +tql=tql-Latn-VU +tqm=tqm-Latn-PG +tqn=tqn-Latn-US +tqo=tqo-Latn-PG +tqp=tqp-Latn-PG +tqt=tqt-Latn-MX +tqu=tqu-Latn-SB +tqw=tqw-Latn-US +tr=tr-Latn-TR +tra=tra-Arab-AF +trb=trb-Latn-PG +trc=trc-Latn-MX +tre=tre-Latn-ID +trf=trf-Latn-TT +trg=trg-Hebr-IL +trh=trh-Latn-PG +tri=tri-Latn-SR +trj=trj-Latn-TD +trl=trl-Latn-GB +trm=trm-Arab-AF +trn=trn-Latn-BO +tro=tro-Latn-IN +trp=trp-Latn-IN +trq=trq-Latn-MX +trr=trr-Latn-PE +trs=trs-Latn-MX +trt=trt-Latn-ID +tru=tru-Latn-TR +trv=trv-Latn-TW +trw=trw-Arab-PK +trx=trx-Latn-MY +try=try-Latn-IN +trz=trz-Latn-BR +ts=ts-Latn-ZA +tsa=tsa-Latn-CG +tsb=tsb-Latn-ET +tsc=tsc-Latn-MZ +tsd=tsd-Grek-GR +tsg=tsg-Latn-PH +tsh=tsh-Latn-CM +tsi=tsi-Latn-CA +tsj=tsj-Tibt-BT +tsl=tsl-Latn-VN +tsp=tsp-Latn-BF +tsr=tsr-Latn-VU +tst=tst-Latn-ML +tsu=tsu-Latn-TW +tsv=tsv-Latn-GA +tsw=tsw-Latn-NG +tsx=tsx-Latn-PG +tsz=tsz-Latn-MX +tt=tt-Cyrl-RU +ttb=ttb-Latn-NG +ttc=ttc-Latn-GT +ttd=ttd-Latn-PG +tte=tte-Latn-PG +ttf=ttf-Latn-CM +tth=tth-Laoo-LA +tti=tti-Latn-ID +ttj=ttj-Latn-UG +ttk=ttk-Latn-CO +ttl=ttl-Latn-ZM +ttm=ttm-Latn-CA +ttn=ttn-Latn-ID +tto=tto-Laoo-LA +ttp=ttp-Latn-ID +ttr=ttr-Latn-NG +tts=tts-Thai-TH +ttt=ttt-Latn-AZ +ttu=ttu-Latn-PG +ttv=ttv-Latn-PG +ttw=ttw-Latn-MY +tty=tty-Latn-ID +ttz=ttz-Deva-NP +tua=tua-Latn-PG +tub=tub-Latn-US +tuc=tuc-Latn-PG +tud=tud-Latn-BR +tue=tue-Latn-CO +tuf=tuf-Latn-CO +tug=tug-Latn-TD +tuh=tuh-Latn-PG +tui=tui-Latn-CM +tuj=tuj-Latn-ID +tul=tul-Latn-NG +tum=tum-Latn-MW +tun=tun-Latn-US +tuo=tuo-Latn-BR +tuq=tuq-Latn-TD +tus=tus-Latn-CA +tuu=tuu-Latn-US +tuv=tuv-Latn-KE +tux=tux-Latn-BR +tuy=tuy-Latn-KE +tuz=tuz-Latn-BF +tva=tva-Latn-SB +tvd=tvd-Latn-NG +tve=tve-Latn-ID +tvi=tvi-Latn-NG +tvk=tvk-Latn-VU +tvl=tvl-Latn-TV +tvm=tvm-Latn-ID +tvn=tvn-Mymr-MM +tvo=tvo-Latn-ID +tvs=tvs-Latn-KE +tvt=tvt-Latn-IN +tvu=tvu-Latn-CM +tvw=tvw-Latn-ID +tvx=tvx-Latn-TW +twa=twa-Latn-US +twb=twb-Latn-PH +twd=twd-Latn-NL +twe=twe-Latn-ID +twf=twf-Latn-US +twg=twg-Latn-ID +twh=twh-Latn-VN +twl=twl-Latn-MZ +twm=twm-Deva-IN +twn=twn-Latn-CM +two=two-Latn-BW +twp=twp-Latn-PG +twq=twq-Latn-NE +twr=twr-Latn-MX +twt=twt-Latn-BR +twu=twu-Latn-ID +tww=tww-Latn-PG +twx=twx-Latn-MZ +twy=twy-Latn-ID +txa=txa-Latn-MY +txe=txe-Latn-ID +txg=txg-Tang-CN +txi=txi-Latn-BR +txj=txj-Latn-NG +txm=txm-Latn-ID +txn=txn-Latn-ID +txo=txo-Toto-IN +txq=txq-Latn-ID +txs=txs-Latn-ID +txt=txt-Latn-ID +txu=txu-Latn-BR +txx=txx-Latn-MY +txy=txy-Latn-MG +ty=ty-Latn-PF +tya=tya-Latn-PG +tye=tye-Latn-NG +tyh=tyh-Latn-VN +tyi=tyi-Latn-CG +tyj=tyj-Latn-VN +tyl=tyl-Latn-VN +tyn=tyn-Latn-ID +typ=typ-Latn-AU +tyr=tyr-Tavt-VN +tys=tys-Latn-VN +tyt=tyt-Latn-VN +tyu=tyu-Latn-BW +tyv=tyv-Cyrl-RU +tyx=tyx-Latn-CG +tyy=tyy-Latn-NG +tyz=tyz-Latn-VN +tzh=tzh-Latn-MX +tzj=tzj-Latn-GT +tzl=tzl-Latn-001 +tzm=tzm-Latn-MA +tzn=tzn-Latn-ID +tzo=tzo-Latn-MX +tzx=tzx-Latn-PG +uam=uam-Latn-BR +uar=uar-Latn-PG +uba=uba-Latn-NG +ubi=ubi-Latn-TD +ubl=ubl-Latn-PH +ubr=ubr-Latn-PG +ubu=ubu-Latn-PG +uby=uby-Latn-TR +uda=uda-Latn-NG +ude=ude-Cyrl-RU +udg=udg-Mlym-IN +udi=udi-Cyrl-RU +udj=udj-Latn-ID +udl=udl-Latn-CM +udm=udm-Cyrl-RU +udu=udu-Latn-SD +ues=ues-Latn-ID +ufi=ufi-Latn-PG +ug=ug-Arab-CN +ug-Cyrl=ug-Cyrl-KZ +ug-KZ=ug-Cyrl-KZ +ug-MN=ug-Cyrl-MN +uga=uga-Ugar-SY +ugb=ugb-Latn-AU +uge=uge-Latn-SB +ugh=ugh-Cyrl-RU +ugo=ugo-Thai-TH +uha=uha-Latn-NG +uhn=uhn-Latn-ID +uis=uis-Latn-PG +uiv=uiv-Latn-CM +uji=uji-Latn-NG +uk=uk-Cyrl-UA +uka=uka-Latn-ID +ukg=ukg-Latn-PG +ukh=ukh-Latn-CF +uki=uki-Orya-IN +ukk=ukk-Latn-MM +ukp=ukp-Latn-NG +ukq=ukq-Latn-NG +uku=uku-Latn-NG +ukv=ukv-Latn-SS +ukw=ukw-Latn-NG +uky=uky-Latn-AU +ula=ula-Latn-NG +ulb=ulb-Latn-NG +ulc=ulc-Cyrl-RU +ule=ule-Latn-AR +ulf=ulf-Latn-ID +uli=uli-Latn-FM +ulk=ulk-Latn-AU +ulm=ulm-Latn-ID +uln=uln-Latn-PG +ulu=ulu-Latn-ID +ulw=ulw-Latn-NI +uly=uly-Latn-NG +uma=uma-Latn-US +umb=umb-Latn-AO +umd=umd-Latn-AU +umg=umg-Latn-AU +umi=umi-Latn-MY +umm=umm-Latn-NG +umn=umn-Latn-MM +umo=umo-Latn-BR +ump=ump-Latn-AU +umr=umr-Latn-AU +ums=ums-Latn-ID +una=una-Latn-PG +und=en-Latn-US +und-419=es-Latn-419 +und-AD=ca-Latn-AD +und-AE=ar-Arab-AE +und-AF=fa-Arab-AF +und-AL=sq-Latn-AL +und-AM=hy-Armn-AM +und-AO=pt-Latn-AO +und-AR=es-Latn-AR +und-AS=sm-Latn-AS +und-AT=de-Latn-AT +und-AW=nl-Latn-AW +und-AX=sv-Latn-AX +und-AZ=az-Latn-AZ +und-Adlm=ff-Adlm-GN +und-Aghb=xag-Aghb-AZ +und-Ahom=aho-Ahom-IN +und-Arab=ar-Arab-EG +und-Arab-AF=fa-Arab-AF +und-Arab-AZ=az-Arab-AZ +und-Arab-BN=ms-Arab-BN +und-Arab-CC=ms-Arab-CC +und-Arab-CN=ug-Arab-CN +und-Arab-GB=ur-Arab-GB +und-Arab-ID=ms-Arab-ID +und-Arab-IN=ur-Arab-IN +und-Arab-IR=fa-Arab-IR +und-Arab-KH=cja-Arab-KH +und-Arab-MM=rhg-Arab-MM +und-Arab-MN=kk-Arab-MN +und-Arab-MU=ur-Arab-MU +und-Arab-NG=ha-Arab-NG +und-Arab-PK=ur-Arab-PK +und-Arab-TH=mfa-Arab-TH +und-Arab-TJ=fa-Arab-TJ +und-Arab-TR=apc-Arab-TR +und-Arab-YT=swb-Arab-YT +und-Armi=arc-Armi-IR +und-Armn=hy-Armn-AM +und-Avst=ae-Avst-IR +und-BA=bs-Latn-BA +und-BD=bn-Beng-BD +und-BE=nl-Latn-BE +und-BF=fr-Latn-BF +und-BG=bg-Cyrl-BG +und-BH=ar-Arab-BH +und-BI=rn-Latn-BI +und-BJ=fr-Latn-BJ +und-BL=fr-Latn-BL +und-BN=ms-Latn-BN +und-BO=es-Latn-BO +und-BQ=pap-Latn-BQ +und-BR=pt-Latn-BR +und-BT=dz-Tibt-BT +und-BV=no-Latn-BV +und-BY=be-Cyrl-BY +und-Bali=ban-Bali-ID +und-Bamu=bax-Bamu-CM +und-Bass=bsq-Bass-LR +und-Batk=bbc-Batk-ID +und-Beng=bn-Beng-BD +und-Bhks=sa-Bhks-IN +und-Bopo=zh-Bopo-TW +und-Brah=pka-Brah-IN +und-Brai=fr-Brai-FR +und-Bugi=bug-Bugi-ID +und-Buhd=bku-Buhd-PH +und-CC=ms-Arab-CC +und-CD=fr-Latn-CD +und-CF=sg-Latn-CF +und-CG=fr-Latn-CG +und-CH=de-Latn-CH +und-CI=fr-Latn-CI +und-CL=es-Latn-CL +und-CM=fr-Latn-CM +und-CN=zh-Hans-CN +und-CO=es-Latn-CO +und-CR=es-Latn-CR +und-CU=es-Latn-CU +und-CV=pt-Latn-CV +und-CW=pap-Latn-CW +und-CY=el-Grek-CY +und-CZ=cs-Latn-CZ +und-Cakm=ccp-Cakm-BD +und-Cans=iu-Cans-CA +und-Cari=xcr-Cari-TR +und-Cham=cjm-Cham-VN +und-Cher=chr-Cher-US +und-Chrs=xco-Chrs-UZ +und-Copt=cop-Copt-EG +und-Cpmn=und-Cpmn-CY +und-Cprt=ecy-Cprt-CY +und-Cyrl=ru-Cyrl-RU +und-Cyrl-AF=kaa-Cyrl-AF +und-Cyrl-AL=mk-Cyrl-AL +und-Cyrl-AZ=az-Cyrl-AZ +und-Cyrl-BA=sr-Cyrl-BA +und-Cyrl-BG=bg-Cyrl-BG +und-Cyrl-BY=be-Cyrl-BY +und-Cyrl-GE=ab-Cyrl-GE +und-Cyrl-GR=mk-Cyrl-GR +und-Cyrl-IR=kaa-Cyrl-IR +und-Cyrl-KG=ky-Cyrl-KG +und-Cyrl-MD=uk-Cyrl-MD +und-Cyrl-ME=sr-Cyrl-ME +und-Cyrl-MK=mk-Cyrl-MK +und-Cyrl-MN=mn-Cyrl-MN +und-Cyrl-RO=bg-Cyrl-RO +und-Cyrl-RS=sr-Cyrl-RS +und-Cyrl-SK=uk-Cyrl-SK +und-Cyrl-TJ=tg-Cyrl-TJ +und-Cyrl-TR=kbd-Cyrl-TR +und-Cyrl-UA=uk-Cyrl-UA +und-Cyrl-UZ=uz-Cyrl-UZ +und-Cyrl-XK=sr-Cyrl-XK +und-DE=de-Latn-DE +und-DJ=fr-Latn-DJ +und-DK=da-Latn-DK +und-DO=es-Latn-DO +und-DZ=ar-Arab-DZ +und-Deva=hi-Deva-IN +und-Deva-BT=ne-Deva-BT +und-Deva-FJ=hif-Deva-FJ +und-Deva-MU=bho-Deva-MU +und-Deva-NP=ne-Deva-NP +und-Deva-PK=btv-Deva-PK +und-Diak=dv-Diak-MV +und-Dogr=doi-Dogr-IN +und-Dupl=fr-Dupl-FR +und-EA=es-Latn-EA +und-EC=es-Latn-EC +und-EE=et-Latn-EE +und-EG=ar-Arab-EG +und-EH=ar-Arab-EH +und-ER=ti-Ethi-ER +und-ES=es-Latn-ES +und-ET=am-Ethi-ET +und-Egyp=egy-Egyp-EG +und-Elba=sq-Elba-AL +und-Elym=arc-Elym-IR +und-Ethi=am-Ethi-ET +und-Ethi-ER=ti-Ethi-ER +und-FI=fi-Latn-FI +und-FO=fo-Latn-FO +und-FR=fr-Latn-FR +und-GA=fr-Latn-GA +und-GE=ka-Geor-GE +und-GF=fr-Latn-GF +und-GH=ak-Latn-GH +und-GL=kl-Latn-GL +und-GN=fr-Latn-GN +und-GP=fr-Latn-GP +und-GQ=es-Latn-GQ +und-GR=el-Grek-GR +und-GT=es-Latn-GT +und-GW=pt-Latn-GW +und-Gara=wo-Gara-SN +und-Geor=ka-Geor-GE +und-Glag=cu-Glag-BG +und-Gong=wsg-Gong-IN +und-Gonm=esg-Gonm-IN +und-Goth=got-Goth-UA +und-Gran=sa-Gran-IN +und-Grek=el-Grek-GR +und-Grek-TR=bgx-Grek-TR +und-Gujr=gu-Gujr-IN +und-Gukh=gvr-Gukh-NP +und-Guru=pa-Guru-IN +und-HK=zh-Hant-HK +und-HN=es-Latn-HN +und-HR=hr-Latn-HR +und-HT=ht-Latn-HT +und-HU=hu-Latn-HU +und-Hanb=zh-Hanb-TW +und-Hang=ko-Hang-KR +und-Hani=zh-Hani-CN +und-Hano=hnn-Hano-PH +und-Hans=zh-Hans-CN +und-Hant=zh-Hant-TW +und-Hant-CA=yue-Hant-CA +und-Hant-CN=yue-Hant-CN +und-Hatr=arc-Hatr-IQ +und-Hebr=he-Hebr-IL +und-Hebr-SE=yi-Hebr-SE +und-Hebr-UA=yi-Hebr-UA +und-Hebr-US=yi-Hebr-US +und-Hira=ja-Hira-JP +und-Hluw=hlu-Hluw-TR +und-Hmng=hnj-Hmng-LA +und-Hmnp=hnj-Hmnp-US +und-Hung=hu-Hung-HU +und-IC=es-Latn-IC +und-ID=id-Latn-ID +und-IL=he-Hebr-IL +und-IN=hi-Deva-IN +und-IQ=ar-Arab-IQ +und-IR=fa-Arab-IR +und-IS=is-Latn-IS +und-IT=it-Latn-IT +und-Ital=ett-Ital-IT +und-JO=ar-Arab-JO +und-JP=ja-Jpan-JP +und-Jamo=ko-Jamo-KR +und-Java=jv-Java-ID +und-Jpan=ja-Jpan-JP +und-KE=sw-Latn-KE +und-KG=ky-Cyrl-KG +und-KH=km-Khmr-KH +und-KM=ar-Arab-KM +und-KP=ko-Kore-KP +und-KR=ko-Kore-KR +und-KW=ar-Arab-KW +und-KZ=ru-Cyrl-KZ +und-Kali=eky-Kali-MM +und-Kana=ja-Kana-JP +und-Kawi=kaw-Kawi-ID +und-Khar=pra-Khar-PK +und-Khmr=km-Khmr-KH +und-Khoj=sd-Khoj-IN +und-Kits=zkt-Kits-CN +und-Knda=kn-Knda-IN +und-Kore=ko-Kore-KR +und-Krai=bap-Krai-IN +und-Kthi=bho-Kthi-IN +und-LA=lo-Laoo-LA +und-LB=ar-Arab-LB +und-LI=de-Latn-LI +und-LK=si-Sinh-LK +und-LS=st-Latn-LS +und-LT=lt-Latn-LT +und-LU=fr-Latn-LU +und-LV=lv-Latn-LV +und-LY=ar-Arab-LY +und-Lana=nod-Lana-TH +und-Laoo=lo-Laoo-LA +und-Latn-AE=en-Latn-AE +und-Latn-AF=tk-Latn-AF +und-Latn-AM=ku-Latn-AM +und-Latn-BD=en-Latn-BD +und-Latn-BG=en-Latn-BG +und-Latn-BT=en-Latn-BT +und-Latn-CC=en-Latn-CC +und-Latn-CN=za-Latn-CN +und-Latn-CY=tr-Latn-CY +und-Latn-DZ=fr-Latn-DZ +und-Latn-EG=en-Latn-EG +und-Latn-ER=en-Latn-ER +und-Latn-ET=en-Latn-ET +und-Latn-GE=ku-Latn-GE +und-Latn-GR=en-Latn-GR +und-Latn-HK=en-Latn-HK +und-Latn-IL=en-Latn-IL +und-Latn-IN=en-Latn-IN +und-Latn-IQ=en-Latn-IQ +und-Latn-IR=tk-Latn-IR +und-Latn-JO=en-Latn-JO +und-Latn-KM=fr-Latn-KM +und-Latn-KZ=en-Latn-KZ +und-Latn-LB=en-Latn-LB +und-Latn-LK=en-Latn-LK +und-Latn-MA=fr-Latn-MA +und-Latn-MK=sq-Latn-MK +und-Latn-MM=kac-Latn-MM +und-Latn-MO=en-Latn-MO +und-Latn-MR=fr-Latn-MR +und-Latn-MV=en-Latn-MV +und-Latn-NP=en-Latn-NP +und-Latn-PK=en-Latn-PK +und-Latn-RU=krl-Latn-RU +und-Latn-SD=en-Latn-SD +und-Latn-SS=en-Latn-SS +und-Latn-SY=ku-Latn-SY +und-Latn-TD=fr-Latn-TD +und-Latn-TH=en-Latn-TH +und-Latn-TN=fr-Latn-TN +und-Latn-TW=trv-Latn-TW +und-Latn-UA=pl-Latn-UA +und-Latn-YE=en-Latn-YE +und-Lepc=lep-Lepc-IN +und-Limb=lif-Limb-IN +und-Lina=lab-Lina-GR +und-Linb=gmy-Linb-GR +und-Lisu=lis-Lisu-CN +und-Lyci=xlc-Lyci-TR +und-Lydi=xld-Lydi-TR +und-MA=ar-Arab-MA +und-MC=fr-Latn-MC +und-MD=ro-Latn-MD +und-ME=sr-Latn-ME +und-MF=fr-Latn-MF +und-MG=mg-Latn-MG +und-MK=mk-Cyrl-MK +und-ML=bm-Latn-ML +und-MM=my-Mymr-MM +und-MN=mn-Cyrl-MN +und-MO=zh-Hant-MO +und-MQ=fr-Latn-MQ +und-MR=ar-Arab-MR +und-MT=mt-Latn-MT +und-MU=fr-Latn-MU +und-MV=dv-Thaa-MV +und-MX=es-Latn-MX +und-MY=ms-Latn-MY +und-MZ=pt-Latn-MZ +und-Mahj=hi-Mahj-IN +und-Maka=mak-Maka-ID +und-Mand=myz-Mand-IR +und-Mani=xmn-Mani-CN +und-Marc=bo-Marc-CN +und-Medf=dmf-Medf-NG +und-Mend=men-Mend-SL +und-Merc=xmr-Merc-SD +und-Mero=xmr-Mero-SD +und-Mlym=ml-Mlym-IN +und-Modi=mr-Modi-IN +und-Mong=mn-Mong-CN +und-Mroo=mro-Mroo-BD +und-Mtei=mni-Mtei-IN +und-Mult=skr-Mult-PK +und-Mymr=my-Mymr-MM +und-Mymr-IN=kht-Mymr-IN +und-Mymr-TH=mnw-Mymr-TH +und-NA=af-Latn-NA +und-NC=fr-Latn-NC +und-NE=ha-Latn-NE +und-NI=es-Latn-NI +und-NL=nl-Latn-NL +und-NO=nb-Latn-NO +und-NP=ne-Deva-NP +und-Nagm=unr-Nagm-IN +und-Nand=sa-Nand-IN +und-Narb=xna-Narb-SA +und-Nbat=arc-Nbat-JO +und-Newa=new-Newa-NP +und-Nkoo=man-Nkoo-GN +und-Nkoo-ML=bm-Nkoo-ML +und-Nshu=zhx-Nshu-CN +und-OM=ar-Arab-OM +und-Ogam=sga-Ogam-IE +und-Olck=sat-Olck-IN +und-Onao=unr-Onao-IN +und-Orkh=otk-Orkh-MN +und-Orya=or-Orya-IN +und-Osge=osa-Osge-US +und-Osma=so-Osma-SO +und-Ougr=oui-Ougr-CN +und-PA=es-Latn-PA +und-PE=es-Latn-PE +und-PF=fr-Latn-PF +und-PG=tpi-Latn-PG +und-PH=fil-Latn-PH +und-PK=ur-Arab-PK +und-PL=pl-Latn-PL +und-PM=fr-Latn-PM +und-PR=es-Latn-PR +und-PS=ar-Arab-PS +und-PT=pt-Latn-PT +und-PW=pau-Latn-PW +und-PY=gn-Latn-PY +und-Palm=arc-Palm-SY +und-Pauc=ctd-Pauc-MM +und-Perm=kv-Perm-RU +und-Phag=lzh-Phag-CN +und-Phli=pal-Phli-IR +und-Phlp=pal-Phlp-CN +und-Phnx=phn-Phnx-LB +und-Plrd=hmd-Plrd-CN +und-Prti=xpr-Prti-IR +und-QA=ar-Arab-QA +und-RE=fr-Latn-RE +und-RO=ro-Latn-RO +und-RS=sr-Cyrl-RS +und-RU=ru-Cyrl-RU +und-RW=rw-Latn-RW +und-Rjng=rej-Rjng-ID +und-Rohg=rhg-Rohg-MM +und-Runr=non-Runr-SE +und-SA=ar-Arab-SA +und-SC=fr-Latn-SC +und-SD=ar-Arab-SD +und-SE=sv-Latn-SE +und-SI=sl-Latn-SI +und-SJ=nb-Latn-SJ +und-SK=sk-Latn-SK +und-SM=it-Latn-SM +und-SN=wo-Latn-SN +und-SO=so-Latn-SO +und-SR=nl-Latn-SR +und-SS=ar-Arab-SS +und-ST=pt-Latn-ST +und-SV=es-Latn-SV +und-SY=ar-Arab-SY +und-Samr=smp-Samr-IL +und-Sarb=xsa-Sarb-YE +und-Saur=saz-Saur-IN +und-Sgnw=ase-Sgnw-US +und-Shaw=en-Shaw-GB +und-Shrd=sa-Shrd-IN +und-Sidd=sa-Sidd-IN +und-Sind=sd-Sind-IN +und-Sinh=si-Sinh-LK +und-Sogd=sog-Sogd-UZ +und-Sogo=sog-Sogo-UZ +und-Sora=srb-Sora-IN +und-Soyo=cmg-Soyo-MN +und-Sund=su-Sund-ID +und-Sunu=suz-Sunu-NP +und-Sylo=syl-Sylo-BD +und-Syrc=syr-Syrc-IQ +und-TD=ar-Arab-TD +und-TF=fr-Latn-TF +und-TG=fr-Latn-TG +und-TH=th-Thai-TH +und-TJ=tg-Cyrl-TJ +und-TK=tkl-Latn-TK +und-TL=pt-Latn-TL +und-TM=tk-Latn-TM +und-TN=ar-Arab-TN +und-TO=to-Latn-TO +und-TR=tr-Latn-TR +und-TV=tvl-Latn-TV +und-TW=zh-Hant-TW +und-TZ=sw-Latn-TZ +und-Tagb=tbw-Tagb-PH +und-Takr=doi-Takr-IN +und-Tale=tdd-Tale-CN +und-Talu=khb-Talu-CN +und-Taml=ta-Taml-IN +und-Tang=txg-Tang-CN +und-Tavt=blt-Tavt-VN +und-Telu=te-Telu-IN +und-Tfng=zgh-Tfng-MA +und-Tglg=fil-Tglg-PH +und-Thaa=dv-Thaa-MV +und-Thai=th-Thai-TH +und-Thai-CN=lcp-Thai-CN +und-Thai-KH=kdt-Thai-KH +und-Thai-LA=kdt-Thai-LA +und-Tibt=bo-Tibt-CN +und-Tibt-BT=dz-Tibt-BT +und-Tirh=mai-Tirh-IN +und-Tnsa=nst-Tnsa-IN +und-Todr=sq-Todr-AL +und-Toto=txo-Toto-IN +und-Tutg=sa-Tutg-IN +und-UA=uk-Cyrl-UA +und-UG=sw-Latn-UG +und-UY=es-Latn-UY +und-UZ=uz-Latn-UZ +und-Ugar=uga-Ugar-SY +und-VA=it-Latn-VA +und-VE=es-Latn-VE +und-VN=vi-Latn-VN +und-VU=bi-Latn-VU +und-Vaii=vai-Vaii-LR +und-Vith=sq-Vith-AL +und-WF=fr-Latn-WF +und-WS=sm-Latn-WS +und-Wara=hoc-Wara-IN +und-Wcho=nnp-Wcho-IN +und-XK=sq-Latn-XK +und-Xpeo=peo-Xpeo-IR +und-Xsux=akk-Xsux-IQ +und-YE=ar-Arab-YE +und-YT=fr-Latn-YT +und-Yezi=ku-Yezi-GE +und-Yiii=ii-Yiii-CN +und-ZW=sn-Latn-ZW +und-Zanb=cmg-Zanb-MN +une=une-Latn-NG +ung=ung-Latn-AU +uni=uni-Latn-PG +unk=unk-Latn-BR +unm=unm-Latn-US +unn=unn-Latn-AU +unr=unr-Beng-IN +unr-Deva=unr-Deva-NP +unr-NP=unr-Deva-NP +unu=unu-Latn-PG +unx=unx-Beng-IN +unz=unz-Latn-ID +uon=uon-Latn-TW +upi=upi-Latn-PG +upv=upv-Latn-VU +ur=ur-Arab-PK +ura=ura-Latn-PE +urb=urb-Latn-BR +urc=urc-Latn-AU +ure=ure-Latn-BO +urf=urf-Latn-AU +urg=urg-Latn-PG +urh=urh-Latn-NG +uri=uri-Latn-PG +urk=urk-Thai-TH +urm=urm-Latn-PG +urn=urn-Latn-ID +uro=uro-Latn-PG +urp=urp-Latn-BR +urr=urr-Latn-VU +urt=urt-Latn-PG +uru=uru-Latn-BR +urv=urv-Latn-PG +urw=urw-Latn-PG +urx=urx-Latn-PG +ury=ury-Latn-ID +urz=urz-Latn-BR +usa=usa-Latn-PG +ush=ush-Arab-PK +usi=usi-Latn-BD +usk=usk-Latn-CM +usp=usp-Latn-GT +uss=uss-Latn-NG +usu=usu-Latn-PG +uta=uta-Latn-NG +ute=ute-Latn-US +uth=uth-Latn-NG +utp=utp-Latn-SB +utr=utr-Latn-NG +utu=utu-Latn-PG +uum=uum-Grek-GE +uur=uur-Latn-VU +uve=uve-Latn-NC +uvh=uvh-Latn-PG +uvl=uvl-Latn-PG +uwa=uwa-Latn-AU +uya=uya-Latn-NG +uz=uz-Latn-UZ +uz-AF=uz-Arab-AF +uz-Arab=uz-Arab-AF +uz-CN=uz-Cyrl-CN +uzs=uzs-Arab-AF +vaa=vaa-Taml-IN +vae=vae-Latn-CF +vaf=vaf-Arab-IR +vag=vag-Latn-GH +vah=vah-Deva-IN +vai=vai-Vaii-LR +vaj=vaj-Latn-NA +val=val-Latn-PG +vam=vam-Latn-PG +van=van-Latn-PG +vao=vao-Latn-VU +vap=vap-Latn-IN +var=var-Latn-MX +vas=vas-Deva-IN +vau=vau-Latn-CD +vav=vav-Deva-IN +vay=vay-Deva-NP +vbb=vbb-Latn-ID +vbk=vbk-Latn-PH +ve=ve-Latn-ZA +vec=vec-Latn-IT +vem=vem-Latn-NG +veo=veo-Latn-US +vep=vep-Latn-RU +ver=ver-Latn-NG +vgr=vgr-Arab-PK +vi=vi-Latn-VN +vic=vic-Latn-SX +vid=vid-Latn-TZ +vif=vif-Latn-CG +vig=vig-Latn-BF +vil=vil-Latn-AR +vin=vin-Latn-TZ +vit=vit-Latn-NG +viv=viv-Latn-PG +vjk=vjk-Deva-IN +vka=vka-Latn-AU +vkj=vkj-Latn-TD +vkk=vkk-Latn-ID +vkl=vkl-Latn-ID +vkm=vkm-Latn-BR +vkn=vkn-Latn-NG +vko=vko-Latn-ID +vkp=vkp-Latn-IN +vkt=vkt-Latn-ID +vku=vku-Latn-AU +vkz=vkz-Latn-NG +vlp=vlp-Latn-VU +vls=vls-Latn-BE +vma=vma-Latn-AU +vmb=vmb-Latn-AU +vmc=vmc-Latn-MX +vmd=vmd-Knda-IN +vme=vme-Latn-ID +vmf=vmf-Latn-DE +vmg=vmg-Latn-PG +vmh=vmh-Arab-IR +vmi=vmi-Latn-AU +vmj=vmj-Latn-MX +vmk=vmk-Latn-MZ +vml=vml-Latn-AU +vmm=vmm-Latn-MX +vmp=vmp-Latn-MX +vmq=vmq-Latn-MX +vmr=vmr-Latn-MZ +vms=vms-Latn-ID +vmu=vmu-Latn-AU +vmw=vmw-Latn-MZ +vmx=vmx-Latn-MX +vmy=vmy-Latn-MX +vmz=vmz-Latn-MX +vnk=vnk-Latn-SB +vnm=vnm-Latn-VU +vnp=vnp-Latn-VU +vo=vo-Latn-001 +vor=vor-Latn-NG +vot=vot-Latn-RU +vra=vra-Latn-VU +vro=vro-Latn-EE +vrs=vrs-Latn-SB +vrt=vrt-Latn-VU +vto=vto-Latn-ID +vum=vum-Latn-GA +vun=vun-Latn-TZ +vut=vut-Latn-CM +vwa=vwa-Latn-CN +wa=wa-Latn-BE +waa=waa-Latn-US +wab=wab-Latn-PG +wac=wac-Latn-US +wad=wad-Latn-ID +wae=wae-Latn-CH +waf=waf-Latn-BR +wag=wag-Latn-PG +wah=wah-Latn-ID +wai=wai-Latn-ID +waj=waj-Latn-PG +wal=wal-Ethi-ET +wam=wam-Latn-US +wan=wan-Latn-CI +wap=wap-Latn-GY +waq=waq-Latn-AU +war=war-Latn-PH +was=was-Latn-US +wat=wat-Latn-PG +wau=wau-Latn-BR +wav=wav-Latn-NG +waw=waw-Latn-BR +wax=wax-Latn-PG +way=way-Latn-SR +waz=waz-Latn-PG +wba=wba-Latn-VE +wbb=wbb-Latn-ID +wbe=wbe-Latn-ID +wbf=wbf-Latn-BF +wbh=wbh-Latn-TZ +wbi=wbi-Latn-TZ +wbj=wbj-Latn-TZ +wbk=wbk-Arab-AF +wbl=wbl-Latn-PK +wbm=wbm-Latn-CN +wbp=wbp-Latn-AU +wbq=wbq-Telu-IN +wbr=wbr-Deva-IN +wbt=wbt-Latn-AU +wbv=wbv-Latn-AU +wbw=wbw-Latn-ID +wca=wca-Latn-BR +wci=wci-Latn-TG +wdd=wdd-Latn-GA +wdg=wdg-Latn-PG +wdj=wdj-Latn-AU +wdk=wdk-Latn-AU +wdt=wdt-Latn-CA +wdu=wdu-Latn-AU +wdy=wdy-Latn-AU +wec=wec-Latn-CI +wed=wed-Latn-PG +weg=weg-Latn-AU +weh=weh-Latn-CM +wei=wei-Latn-PG +wem=wem-Latn-BJ +weo=weo-Latn-ID +wep=wep-Latn-DE +wer=wer-Latn-PG +wes=wes-Latn-CM +wet=wet-Latn-ID +weu=weu-Latn-MM +wew=wew-Latn-ID +wfg=wfg-Latn-ID +wga=wga-Latn-AU +wgb=wgb-Latn-PG +wgg=wgg-Latn-AU +wgi=wgi-Latn-PG +wgo=wgo-Latn-ID +wgu=wgu-Latn-AU +wgy=wgy-Latn-AU +wha=wha-Latn-ID +whg=whg-Latn-PG +whk=whk-Latn-ID +whu=whu-Latn-ID +wib=wib-Latn-BF +wic=wic-Latn-US +wie=wie-Latn-AU +wif=wif-Latn-AU +wig=wig-Latn-AU +wih=wih-Latn-AU +wii=wii-Latn-PG +wij=wij-Latn-AU +wik=wik-Latn-AU +wil=wil-Latn-AU +wim=wim-Latn-AU +win=win-Latn-US +wir=wir-Latn-BR +wiu=wiu-Latn-PG +wiv=wiv-Latn-PG +wiy=wiy-Latn-US +wja=wja-Latn-NG +wji=wji-Latn-NG +wka=wka-Latn-TZ +wkd=wkd-Latn-ID +wkr=wkr-Latn-AU +wkw=wkw-Latn-AU +wky=wky-Latn-AU +wla=wla-Latn-PG +wle=wle-Ethi-ET +wlg=wlg-Latn-AU +wlh=wlh-Latn-TL +wli=wli-Latn-ID +wlm=wlm-Latn-GB +wlo=wlo-Arab-ID +wlr=wlr-Latn-VU +wls=wls-Latn-WF +wlu=wlu-Latn-AU +wlv=wlv-Latn-AR +wlw=wlw-Latn-ID +wlx=wlx-Latn-GH +wma=wma-Latn-NG +wmb=wmb-Latn-AU +wmc=wmc-Latn-PG +wmd=wmd-Latn-BR +wme=wme-Deva-NP +wmh=wmh-Latn-TL +wmi=wmi-Latn-AU +wmm=wmm-Latn-ID +wmn=wmn-Latn-NC +wmo=wmo-Latn-PG +wms=wms-Latn-ID +wmt=wmt-Latn-AU +wmw=wmw-Latn-MZ +wmx=wmx-Latn-PG +wnb=wnb-Latn-PG +wnc=wnc-Latn-PG +wnd=wnd-Latn-AU +wne=wne-Arab-PK +wng=wng-Latn-ID +wni=wni-Arab-KM +wnk=wnk-Latn-ID +wnm=wnm-Latn-AU +wnn=wnn-Latn-AU +wno=wno-Latn-ID +wnp=wnp-Latn-PG +wnu=wnu-Latn-PG +wnw=wnw-Latn-US +wny=wny-Latn-AU +wo=wo-Latn-SN +woa=woa-Latn-AU +wob=wob-Latn-CI +woc=woc-Latn-PG +wod=wod-Latn-ID +woe=woe-Latn-FM +wof=wof-Latn-GM +wog=wog-Latn-PG +woi=woi-Latn-ID +wok=wok-Latn-CM +wom=wom-Latn-NG +won=won-Latn-CD +woo=woo-Latn-ID +wor=wor-Latn-ID +wos=wos-Latn-PG +wow=wow-Latn-ID +wpc=wpc-Latn-VE +wrb=wrb-Latn-AU +wrg=wrg-Latn-AU +wrh=wrh-Latn-AU +wri=wri-Latn-AU +wrk=wrk-Latn-AU +wrl=wrl-Latn-AU +wrm=wrm-Latn-AU +wro=wro-Latn-AU +wrp=wrp-Latn-ID +wrr=wrr-Latn-AU +wrs=wrs-Latn-PG +wru=wru-Latn-ID +wrv=wrv-Latn-PG +wrw=wrw-Latn-AU +wrx=wrx-Latn-ID +wrz=wrz-Latn-AU +wsa=wsa-Latn-ID +wsg=wsg-Gong-IN +wsi=wsi-Latn-VU +wsk=wsk-Latn-PG +wsr=wsr-Latn-PG +wss=wss-Latn-GH +wsu=wsu-Latn-BR +wsv=wsv-Arab-AF +wtb=wtb-Latn-TZ +wtf=wtf-Latn-PG +wth=wth-Latn-AU +wti=wti-Latn-ET +wtk=wtk-Latn-PG +wtm=wtm-Deva-IN +wtw=wtw-Latn-ID +wua=wua-Latn-AU +wub=wub-Latn-AU +wud=wud-Latn-TG +wul=wul-Latn-ID +wum=wum-Latn-GA +wun=wun-Latn-TZ +wur=wur-Latn-AU +wut=wut-Latn-PG +wuu=wuu-Hans-CN +wuv=wuv-Latn-PG +wux=wux-Latn-AU +wuy=wuy-Latn-ID +wwa=wwa-Latn-BJ +wwb=wwb-Latn-AU +wwo=wwo-Latn-VU +wwr=wwr-Latn-AU +www=www-Latn-CM +wxw=wxw-Latn-AU +wyb=wyb-Latn-AU +wyi=wyi-Latn-AU +wym=wym-Latn-PL +wyn=wyn-Latn-US +wyr=wyr-Latn-BR +wyy=wyy-Latn-FJ +xaa=xaa-Latn-ES +xab=xab-Latn-NG +xag=xag-Aghb-AZ +xai=xai-Latn-BR +xaj=xaj-Latn-BR +xak=xak-Latn-VE +xal=xal-Cyrl-RU +xam=xam-Latn-ZA +xan=xan-Ethi-ET +xao=xao-Latn-VN +xar=xar-Latn-PG +xas=xas-Cyrl-RU +xat=xat-Latn-BR +xau=xau-Latn-ID +xav=xav-Latn-BR +xaw=xaw-Latn-US +xay=xay-Latn-ID +xbb=xbb-Latn-AU +xbd=xbd-Latn-AU +xbe=xbe-Latn-AU +xbg=xbg-Latn-AU +xbi=xbi-Latn-PG +xbj=xbj-Latn-AU +xbm=xbm-Latn-FR +xbn=xbn-Latn-MY +xbp=xbp-Latn-AU +xbr=xbr-Latn-ID +xbw=xbw-Latn-BR +xby=xby-Latn-AU +xch=xch-Latn-US +xco=xco-Chrs-UZ +xcr=xcr-Cari-TR +xda=xda-Latn-AU +xdk=xdk-Latn-AU +xdo=xdo-Latn-AO +xdq=xdq-Cyrl-RU +xdy=xdy-Latn-ID +xed=xed-Latn-CM +xeg=xeg-Latn-ZA +xem=xem-Latn-ID +xer=xer-Latn-BR +xes=xes-Latn-PG +xet=xet-Latn-BR +xeu=xeu-Latn-PG +xgb=xgb-Latn-CI +xgd=xgd-Latn-AU +xgg=xgg-Latn-AU +xgi=xgi-Latn-AU +xgm=xgm-Latn-AU +xgu=xgu-Latn-AU +xgw=xgw-Latn-AU +xh=xh-Latn-ZA +xhe=xhe-Arab-PK +xhm=xhm-Khmr-KH +xhv=xhv-Latn-VN +xii=xii-Latn-ZA +xin=xin-Latn-GT +xir=xir-Latn-BR +xis=xis-Orya-IN +xiy=xiy-Latn-BR +xjb=xjb-Latn-AU +xjt=xjt-Latn-AU +xka=xka-Arab-PK +xkb=xkb-Latn-BJ +xkc=xkc-Arab-IR +xkd=xkd-Latn-ID +xke=xke-Latn-ID +xkf=xkf-Tibt-BT +xkg=xkg-Latn-ML +xkj=xkj-Arab-IR +xkl=xkl-Latn-ID +xkn=xkn-Latn-ID +xkp=xkp-Arab-IR +xkq=xkq-Latn-ID +xkr=xkr-Latn-BR +xks=xks-Latn-ID +xkt=xkt-Latn-GH +xku=xku-Latn-CG +xkv=xkv-Latn-BW +xkw=xkw-Latn-ID +xkx=xkx-Latn-PG +xky=xky-Latn-MY +xkz=xkz-Latn-BT +xla=xla-Latn-PG +xlc=xlc-Lyci-TR +xld=xld-Lydi-TR +xly=xly-Elym-IR +xma=xma-Latn-SO +xmb=xmb-Latn-CM +xmc=xmc-Latn-MZ +xmd=xmd-Latn-CM +xmf=xmf-Geor-GE +xmg=xmg-Latn-CM +xmh=xmh-Latn-AU +xmj=xmj-Latn-CM +xmm=xmm-Latn-ID +xmn=xmn-Mani-CN +xmo=xmo-Latn-BR +xmp=xmp-Latn-AU +xmq=xmq-Latn-AU +xmr=xmr-Merc-SD +xmt=xmt-Latn-ID +xmu=xmu-Latn-AU +xmv=xmv-Latn-MG +xmw=xmw-Latn-MG +xmx=xmx-Latn-ID +xmy=xmy-Latn-AU +xmz=xmz-Latn-ID +xna=xna-Narb-SA +xnb=xnb-Latn-TW +xni=xni-Latn-AU +xnj=xnj-Latn-TZ +xnk=xnk-Latn-AU +xnm=xnm-Latn-AU +xnn=xnn-Latn-PH +xnq=xnq-Latn-MZ +xnr=xnr-Deva-IN +xnt=xnt-Latn-US +xnu=xnu-Latn-AU +xny=xny-Latn-AU +xnz=xnz-Latn-EG +xoc=xoc-Latn-NG +xod=xod-Latn-ID +xog=xog-Latn-UG +xoi=xoi-Latn-PG +xok=xok-Latn-BR +xom=xom-Latn-SD +xon=xon-Latn-GH +xoo=xoo-Latn-BR +xop=xop-Latn-PG +xor=xor-Latn-BR +xow=xow-Latn-PG +xpa=xpa-Latn-AU +xpb=xpb-Latn-AU +xpd=xpd-Latn-AU +xpf=xpf-Latn-AU +xpg=xpg-Grek-TR +xph=xph-Latn-AU +xpi=xpi-Ogam-GB +xpj=xpj-Latn-AU +xpk=xpk-Latn-BR +xpl=xpl-Latn-AU +xpm=xpm-Cyrl-RU +xpn=xpn-Latn-BR +xpo=xpo-Latn-MX +xpq=xpq-Latn-US +xpr=xpr-Prti-IR +xpt=xpt-Latn-AU +xpv=xpv-Latn-AU +xpw=xpw-Latn-AU +xpx=xpx-Latn-AU +xpz=xpz-Latn-AU +xra=xra-Latn-BR +xrb=xrb-Latn-BF +xrd=xrd-Latn-AU +xre=xre-Latn-BR +xrg=xrg-Latn-AU +xri=xri-Latn-BR +xrm=xrm-Cyrl-RU +xrn=xrn-Cyrl-RU +xrr=xrr-Latn-IT +xru=xru-Latn-AU +xrw=xrw-Latn-PG +xsa=xsa-Sarb-YE +xsb=xsb-Latn-PH +xse=xse-Latn-ID +xsh=xsh-Latn-NG +xsi=xsi-Latn-PG +xsm=xsm-Latn-GH +xsn=xsn-Latn-NG +xsp=xsp-Latn-PG +xsq=xsq-Latn-MZ +xsr=xsr-Deva-NP +xsu=xsu-Latn-VE +xsy=xsy-Latn-TW +xta=xta-Latn-MX +xtb=xtb-Latn-MX +xtc=xtc-Latn-SD +xtd=xtd-Latn-MX +xte=xte-Latn-ID +xth=xth-Latn-AU +xti=xti-Latn-MX +xtj=xtj-Latn-MX +xtl=xtl-Latn-MX +xtm=xtm-Latn-MX +xtn=xtn-Latn-MX +xtp=xtp-Latn-MX +xtq=xtq-Brah-IR +xts=xts-Latn-MX +xtt=xtt-Latn-MX +xtu=xtu-Latn-MX +xtv=xtv-Latn-AU +xtw=xtw-Latn-BR +xty=xty-Latn-MX +xub=xub-Taml-IN +xud=xud-Latn-AU +xuj=xuj-Taml-IN +xul=xul-Latn-AU +xum=xum-Latn-IT +xun=xun-Latn-AU +xuo=xuo-Latn-TD +xut=xut-Latn-AU +xuu=xuu-Latn-NA +xve=xve-Ital-IT +xvi=xvi-Arab-AF +xvn=xvn-Latn-ES +xvo=xvo-Latn-IT +xvs=xvs-Latn-IT +xwa=xwa-Latn-BR +xwd=xwd-Latn-AU +xwe=xwe-Latn-BJ +xwj=xwj-Latn-AU +xwk=xwk-Latn-AU +xwl=xwl-Latn-BJ +xwo=xwo-Cyrl-RU +xwr=xwr-Latn-ID +xwt=xwt-Latn-AU +xww=xww-Latn-AU +xxb=xxb-Latn-GH +xxk=xxk-Latn-ID +xxm=xxm-Latn-AU +xxr=xxr-Latn-BR +xxt=xxt-Latn-ID +xya=xya-Latn-AU +xyb=xyb-Latn-AU +xyj=xyj-Latn-AU +xyk=xyk-Latn-AU +xyl=xyl-Latn-BR +xyt=xyt-Latn-AU +xyy=xyy-Latn-AU +xzh=xzh-Marc-CN +xzp=xzp-Latn-MX +yaa=yaa-Latn-PE +yab=yab-Latn-BR +yac=yac-Latn-ID +yad=yad-Latn-PE +yae=yae-Latn-VE +yaf=yaf-Latn-CD +yag=yag-Latn-CL +yah=yah-Latn-TJ +yai=yai-Cyrl-TJ +yaj=yaj-Latn-CF +yak=yak-Latn-US +yal=yal-Latn-GN +yam=yam-Latn-CM +yan=yan-Latn-NI +yao=yao-Latn-MZ +yap=yap-Latn-FM +yaq=yaq-Latn-MX +yar=yar-Latn-VE +yas=yas-Latn-CM +yat=yat-Latn-CM +yau=yau-Latn-VE +yav=yav-Latn-CM +yaw=yaw-Latn-BR +yax=yax-Latn-AO +yay=yay-Latn-NG +yaz=yaz-Latn-NG +yba=yba-Latn-NG +ybb=ybb-Latn-CM +ybe=ybe-Latn-CN +ybh=ybh-Deva-NP +ybi=ybi-Deva-NP +ybj=ybj-Latn-NG +ybl=ybl-Latn-NG +ybm=ybm-Latn-PG +ybn=ybn-Latn-BR +ybo=ybo-Latn-PG +ybx=ybx-Latn-PG +yby=yby-Latn-PG +ycl=ycl-Latn-CN +ycn=ycn-Latn-CO +ycr=ycr-Latn-TW +yda=yda-Latn-AU +yde=yde-Latn-PG +ydg=ydg-Arab-PK +ydk=ydk-Latn-PG +yea=yea-Mlym-IN +yec=yec-Latn-DE +yee=yee-Latn-PG +yei=yei-Latn-CM +yej=yej-Grek-GR +yel=yel-Latn-CD +yer=yer-Latn-NG +yes=yes-Latn-NG +yet=yet-Latn-ID +yeu=yeu-Telu-IN +yev=yev-Latn-PG +yey=yey-Latn-BW +yga=yga-Latn-AU +ygi=ygi-Latn-AU +ygl=ygl-Latn-PG +ygm=ygm-Latn-PG +ygp=ygp-Plrd-CN +ygr=ygr-Latn-PG +ygu=ygu-Latn-AU +ygw=ygw-Latn-PG +yhd=yhd-Hebr-IL +yi=yi-Hebr-UA +yia=yia-Latn-AU +yig=yig-Yiii-CN +yih=yih-Hebr-DE +yii=yii-Latn-AU +yij=yij-Latn-AU +yil=yil-Latn-AU +yim=yim-Latn-IN +yir=yir-Latn-ID +yis=yis-Latn-PG +yiv=yiv-Yiii-CN +yka=yka-Latn-PH +ykg=ykg-Cyrl-RU +ykh=ykh-Cyrl-MN +yki=yki-Latn-ID +ykk=ykk-Latn-PG +ykm=ykm-Latn-PG +yko=yko-Latn-CM +ykr=ykr-Latn-PG +yky=yky-Latn-CF +yla=yla-Latn-PG +ylb=ylb-Latn-PG +yle=yle-Latn-PG +ylg=ylg-Latn-PG +yli=yli-Latn-ID +yll=yll-Latn-PG +ylr=ylr-Latn-AU +ylu=ylu-Latn-PG +yly=yly-Latn-NC +ymb=ymb-Latn-PG +yme=yme-Latn-PE +ymg=ymg-Latn-CD +ymk=ymk-Latn-MZ +yml=yml-Latn-PG +ymm=ymm-Latn-SO +ymn=ymn-Latn-ID +ymo=ymo-Latn-PG +ymp=ymp-Latn-PG +yna=yna-Plrd-CN +ynd=ynd-Latn-AU +yng=yng-Latn-CD +ynk=ynk-Cyrl-RU +ynl=ynl-Latn-PG +ynq=ynq-Latn-NG +yns=yns-Latn-CD +ynu=ynu-Latn-CO +yo=yo-Latn-NG +yob=yob-Latn-PG +yog=yog-Latn-PH +yoi=yoi-Jpan-JP +yok=yok-Latn-US +yol=yol-Latn-IE +yom=yom-Latn-CD +yon=yon-Latn-PG +yot=yot-Latn-NG +yoy=yoy-Thai-TH +yra=yra-Latn-PG +yrb=yrb-Latn-PG +yre=yre-Latn-CI +yrk=yrk-Cyrl-RU +yrl=yrl-Latn-BR +yrm=yrm-Latn-AU +yro=yro-Latn-BR +yrs=yrs-Latn-ID +yrw=yrw-Latn-PG +yry=yry-Latn-AU +ysd=ysd-Yiii-CN +ysn=ysn-Yiii-CN +ysp=ysp-Yiii-CN +ysr=ysr-Cyrl-RU +yss=yss-Latn-PG +ysy=ysy-Plrd-CN +ytw=ytw-Latn-PG +yty=yty-Latn-AU +yua=yua-Latn-MX +yub=yub-Latn-AU +yuc=yuc-Latn-US +yud=yud-Hebr-IL +yue=yue-Hant-HK +yue-CN=yue-Hans-CN +yue-Hans=yue-Hans-CN +yuf=yuf-Latn-US +yug=yug-Cyrl-RU +yui=yui-Latn-CO +yuj=yuj-Latn-PG +yul=yul-Latn-CF +yum=yum-Latn-US +yun=yun-Latn-NG +yup=yup-Latn-CO +yuq=yuq-Latn-BO +yur=yur-Latn-US +yut=yut-Latn-PG +yuw=yuw-Latn-PG +yux=yux-Cyrl-RU +yuz=yuz-Latn-BO +yva=yva-Latn-ID +yvt=yvt-Latn-VE +ywa=ywa-Latn-PG +ywg=ywg-Latn-AU +ywn=ywn-Latn-BR +ywq=ywq-Plrd-CN +ywr=ywr-Latn-AU +ywu=ywu-Plrd-CN +yww=yww-Latn-AU +yxa=yxa-Latn-AU +yxg=yxg-Latn-AU +yxl=yxl-Latn-AU +yxm=yxm-Latn-AU +yxu=yxu-Latn-AU +yxy=yxy-Latn-AU +yyr=yyr-Latn-AU +yyu=yyu-Latn-PG +za=za-Latn-CN +zaa=zaa-Latn-MX +zab=zab-Latn-MX +zac=zac-Latn-MX +zad=zad-Latn-MX +zae=zae-Latn-MX +zaf=zaf-Latn-MX +zag=zag-Latn-SD +zah=zah-Latn-NG +zaj=zaj-Latn-TZ +zak=zak-Latn-TZ +zam=zam-Latn-MX +zao=zao-Latn-MX +zap=zap-Latn-MX +zaq=zaq-Latn-MX +zar=zar-Latn-MX +zas=zas-Latn-MX +zat=zat-Latn-MX +zau=zau-Tibt-IN +zav=zav-Latn-MX +zaw=zaw-Latn-MX +zax=zax-Latn-MX +zay=zay-Latn-ET +zaz=zaz-Latn-NG +zba=zba-Arab-001 +zbc=zbc-Latn-MY +zbe=zbe-Latn-MY +zbt=zbt-Latn-ID +zbu=zbu-Latn-NG +zbw=zbw-Latn-MY +zca=zca-Latn-MX +zch=zch-Hani-CN +zdj=zdj-Arab-KM +zea=zea-Latn-NL +zeg=zeg-Latn-PG +zeh=zeh-Hani-CN +zem=zem-Latn-NG +zen=zen-Tfng-MR +zga=zga-Latn-TZ +zgb=zgb-Hani-CN +zgh=zgh-Tfng-MA +zgm=zgm-Hani-CN +zgn=zgn-Hani-CN +zgr=zgr-Latn-PG +zh=zh-Hans-CN +zh-AU=zh-Hant-AU +zh-BN=zh-Hant-BN +zh-Bopo=zh-Bopo-TW +zh-GB=zh-Hant-GB +zh-GF=zh-Hant-GF +zh-HK=zh-Hant-HK +zh-Hanb=zh-Hanb-TW +zh-Hant=zh-Hant-TW +zh-ID=zh-Hant-ID +zh-MO=zh-Hant-MO +zh-PA=zh-Hant-PA +zh-PF=zh-Hant-PF +zh-PH=zh-Hant-PH +zh-SR=zh-Hant-SR +zh-TH=zh-Hant-TH +zh-TW=zh-Hant-TW +zh-US=zh-Hant-US +zh-VN=zh-Hant-VN +zhd=zhd-Hani-CN +zhi=zhi-Latn-NG +zhn=zhn-Latn-CN +zhw=zhw-Latn-CM +zhx=zhx-Nshu-CN +zia=zia-Latn-PG +zik=zik-Latn-PG +zil=zil-Latn-GN +zim=zim-Latn-TD +zin=zin-Latn-TZ +ziw=ziw-Latn-TZ +ziz=ziz-Latn-NG +zka=zka-Latn-ID +zkd=zkd-Latn-MM +zko=zko-Cyrl-RU +zkp=zkp-Latn-BR +zkt=zkt-Kits-CN +zku=zku-Latn-AU +zkz=zkz-Cyrl-RU +zla=zla-Latn-CD +zlj=zlj-Hani-CN +zlm=zlm-Latn-MY +zln=zln-Hani-CN +zlq=zlq-Hani-CN +zlu=zlu-Latn-NG +zma=zma-Latn-AU +zmb=zmb-Latn-CD +zmc=zmc-Latn-AU +zmd=zmd-Latn-AU +zme=zme-Latn-AU +zmf=zmf-Latn-CD +zmg=zmg-Latn-AU +zmh=zmh-Latn-PG +zmi=zmi-Latn-MY +zmj=zmj-Latn-AU +zmk=zmk-Latn-AU +zml=zml-Latn-AU +zmm=zmm-Latn-AU +zmn=zmn-Latn-GA +zmo=zmo-Latn-SD +zmp=zmp-Latn-CD +zmq=zmq-Latn-CD +zmr=zmr-Latn-AU +zms=zms-Latn-CD +zmt=zmt-Latn-AU +zmu=zmu-Latn-AU +zmv=zmv-Latn-AU +zmw=zmw-Latn-CD +zmx=zmx-Latn-CG +zmy=zmy-Latn-AU +zmz=zmz-Latn-CD +zna=zna-Latn-TD +zne=zne-Latn-CD +zng=zng-Latn-VN +znk=znk-Latn-AU +zns=zns-Latn-NG +zoc=zoc-Latn-MX +zoh=zoh-Latn-MX +zom=zom-Latn-IN +zoo=zoo-Latn-MX +zoq=zoq-Latn-MX +zor=zor-Latn-MX +zos=zos-Latn-MX +zpa=zpa-Latn-MX +zpb=zpb-Latn-MX +zpc=zpc-Latn-MX +zpd=zpd-Latn-MX +zpe=zpe-Latn-MX +zpf=zpf-Latn-MX +zpg=zpg-Latn-MX +zph=zph-Latn-MX +zpi=zpi-Latn-MX +zpj=zpj-Latn-MX +zpk=zpk-Latn-MX +zpl=zpl-Latn-MX +zpm=zpm-Latn-MX +zpn=zpn-Latn-MX +zpo=zpo-Latn-MX +zpp=zpp-Latn-MX +zpq=zpq-Latn-MX +zpr=zpr-Latn-MX +zps=zps-Latn-MX +zpt=zpt-Latn-MX +zpu=zpu-Latn-MX +zpv=zpv-Latn-MX +zpw=zpw-Latn-MX +zpx=zpx-Latn-MX +zpy=zpy-Latn-MX +zpz=zpz-Latn-MX +zqe=zqe-Hani-CN +zrg=zrg-Orya-IN +zrn=zrn-Latn-TD +zro=zro-Latn-EC +zrp=zrp-Hebr-FR +zrs=zrs-Latn-ID +zsa=zsa-Latn-PG +zsr=zsr-Latn-MX +zsu=zsu-Latn-PG +zte=zte-Latn-MX +ztg=ztg-Latn-MX +ztl=ztl-Latn-MX +ztm=ztm-Latn-MX +ztn=ztn-Latn-MX +ztp=ztp-Latn-MX +ztq=ztq-Latn-MX +zts=zts-Latn-MX +ztt=ztt-Latn-MX +ztu=ztu-Latn-MX +ztx=ztx-Latn-MX +zty=zty-Latn-MX +zu=zu-Latn-ZA +zuh=zuh-Latn-PG +zum=zum-Arab-OM +zun=zun-Latn-US +zuy=zuy-Latn-CM +zwa=zwa-Ethi-ET +zyg=zyg-Hani-CN +zyj=zyj-Latn-CN +zyn=zyn-Hani-CN +zyp=zyp-Latn-MM +zza=zza-Latn-TR +zzj=zzj-Hani-CN diff --git a/Jint/Native/Intl/Data/LikelySubtagsData.cs b/Jint/Native/Intl/Data/LikelySubtagsData.cs new file mode 100644 index 0000000000..65369a68c9 --- /dev/null +++ b/Jint/Native/Intl/Data/LikelySubtagsData.cs @@ -0,0 +1,50 @@ +using System.IO; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides access to CLDR likely subtags data for locale maximize/minimize operations. +/// Data is lazy-loaded from embedded text resource (key=value format). +/// +internal static class LikelySubtagsData +{ + private static Dictionary? _likelySubtags; + + private static Dictionary LikelySubtags => _likelySubtags ??= Load(); + + public static bool TryResolve(string key, out string value) + { + return LikelySubtags.TryGetValue(key, out value!); + } + + private static Dictionary Load() + { + var assembly = typeof(LikelySubtagsData).Assembly; + const string resourceName = "Jint.Native.Intl.Data.LikelySubtags.txt"; + using var stream = assembly.GetManifestResourceStream(resourceName) + ?? throw new InvalidOperationException( + "Could not load embedded Intl likely-subtags data."); + + using var reader = new StreamReader(stream); + var data = new Dictionary(8000, StringComparer.Ordinal); + + string? line; + while ((line = reader.ReadLine()) != null) + { + if (line.Length == 0) + { + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex > 0) + { + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + data[key] = value; + } + } + + return data; + } +} diff --git a/Jint/Native/Intl/Data/ListPatternsData.cs b/Jint/Native/Intl/Data/ListPatternsData.cs new file mode 100644 index 0000000000..a4c98c39b0 --- /dev/null +++ b/Jint/Native/Intl/Data/ListPatternsData.cs @@ -0,0 +1,190 @@ +using System.Reflection; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR list formatting patterns for locale-aware list formatting. +/// Data is loaded from embedded ListPatternsData.txt resource. +/// +internal static class ListPatternsData +{ + private static readonly object _lock = new(); + private static Dictionary>? _patterns; + private static volatile bool _loaded; + + /// + /// Gets list patterns for a locale. + /// Returns patterns grouped by type_style (e.g., "conjunction_long", "unit_narrow"). + /// Falls back to English if locale not found. + /// + public static Dictionary? GetPatternsForLocale(string locale) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(locale)) + { + // Get language code from locale (e.g., "es" from "es-ES") + var language = GetLanguageCode(locale); + + // Try to find patterns for this language + if (_patterns!.TryGetValue(language, out var data)) + { + return data; + } + } + + // Fall back to English if not found and not already English + if (!IsEnglish(locale)) + { + if (_patterns!.TryGetValue("en", out var enData)) + { + return enData; + } + } + + return null; + } + + private static string GetLanguageCode(string locale) + { + if (string.IsNullOrEmpty(locale)) + { + return "en"; + } + + // Extract language code (e.g., "es" from "es-ES") + var dashIndex = locale.IndexOf('-'); + return dashIndex > 0 ? locale.Substring(0, dashIndex) : locale; + } + + private static bool IsEnglish(string? locale) + { + if (string.IsNullOrEmpty(locale)) + { + return false; + } + + return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase); + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _patterns = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(ListPatternsData).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.ListPatternsData.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentLocale = null; + Dictionary? currentPatterns = null; + + // Temporary storage for building ListPatterns objects + var tempPatterns = new Dictionary>(StringComparer.Ordinal); + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + // Save previous locale data + if (currentLocale != null && tempPatterns.Count > 0) + { + currentPatterns = BuildListPatternsFromTemp(tempPatterns); + _patterns[currentLocale] = currentPatterns; + tempPatterns.Clear(); + } + + currentLocale = line.Substring(1, line.Length - 2); + continue; + } + + if (currentLocale == null) + { + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + // Parse key: type_style_position (e.g., "conjunction_long_end") + // Store in temp dictionary for later assembly + var parts = key.Split('_'); + if (parts.Length >= 3) + { + var type = parts[0]; // conjunction, disjunction, unit + var style = parts[1]; // long, short, narrow + var position = parts[2]; // start, middle, end, two + + var typeStyleKey = type + "_" + style; + if (!tempPatterns.TryGetValue(typeStyleKey, out var positionPatterns)) + { + positionPatterns = new Dictionary(StringComparer.Ordinal); + tempPatterns[typeStyleKey] = positionPatterns; + } + + positionPatterns[position] = value; + } + } + + // Save last locale data + if (currentLocale != null && tempPatterns.Count > 0) + { + currentPatterns = BuildListPatternsFromTemp(tempPatterns); + _patterns[currentLocale] = currentPatterns; + } + + _loaded = true; + } + } + + private static Dictionary BuildListPatternsFromTemp(Dictionary> tempPatterns) + { + var result = new Dictionary(StringComparer.Ordinal); + + foreach (var kvp in tempPatterns) + { + var typeStyleKey = kvp.Key; + var positionPatterns = kvp.Value; + + // Build ListPatterns object + var listPatterns = new ListPatterns + { + Start = positionPatterns.TryGetValue("start", out var start) ? start : "{0}, {1}", + Middle = positionPatterns.TryGetValue("middle", out var middle) ? middle : "{0}, {1}", + End = positionPatterns.TryGetValue("end", out var end) ? end : "{0}, {1}", + Two = positionPatterns.TryGetValue("two", out var two) ? two : "{0}, {1}" + }; + + result[typeStyleKey] = listPatterns; + } + + return result; + } +} diff --git a/Jint/Native/Intl/Data/ListPatternsData.txt b/Jint/Native/Intl/Data/ListPatternsData.txt new file mode 100644 index 0000000000..b9845fd560 --- /dev/null +++ b/Jint/Native/Intl/Data/ListPatternsData.txt @@ -0,0 +1,151 @@ +[en] +conjunction_long_start={0}, {1} +conjunction_long_middle={0}, {1} +conjunction_long_end={0}, and {1} +conjunction_long_two={0} and {1} +conjunction_short_start={0}, {1} +conjunction_short_middle={0}, {1} +conjunction_short_end={0}, & {1} +conjunction_short_two={0} & {1} +conjunction_narrow_start={0}, {1} +conjunction_narrow_middle={0}, {1} +conjunction_narrow_end={0}, {1} +conjunction_narrow_two={0}, {1} +disjunction_long_start={0}, {1} +disjunction_long_middle={0}, {1} +disjunction_long_end={0}, or {1} +disjunction_long_two={0} or {1} +disjunction_short_start={0}, {1} +disjunction_short_middle={0}, {1} +disjunction_short_end={0}, or {1} +disjunction_short_two={0} or {1} +disjunction_narrow_start={0}, {1} +disjunction_narrow_middle={0}, {1} +disjunction_narrow_end={0}, or {1} +disjunction_narrow_two={0} or {1} +unit_long_start={0}, {1} +unit_long_middle={0}, {1} +unit_long_end={0}, {1} +unit_long_two={0}, {1} +unit_short_start={0}, {1} +unit_short_middle={0}, {1} +unit_short_end={0}, {1} +unit_short_two={0}, {1} +unit_narrow_start={0} {1} +unit_narrow_middle={0} {1} +unit_narrow_end={0} {1} +unit_narrow_two={0} {1} + +[es] +conjunction_long_start={0}, {1} +conjunction_long_middle={0}, {1} +conjunction_long_end={0} y {1} +conjunction_long_two={0} y {1} +conjunction_short_start={0}, {1} +conjunction_short_middle={0}, {1} +conjunction_short_end={0} y {1} +conjunction_short_two={0} y {1} +conjunction_narrow_start={0}, {1} +conjunction_narrow_middle={0}, {1} +conjunction_narrow_end={0} y {1} +conjunction_narrow_two={0} y {1} +disjunction_long_start={0}, {1} +disjunction_long_middle={0}, {1} +disjunction_long_end={0} o {1} +disjunction_long_two={0} o {1} +disjunction_short_start={0}, {1} +disjunction_short_middle={0}, {1} +disjunction_short_end={0} o {1} +disjunction_short_two={0} o {1} +disjunction_narrow_start={0}, {1} +disjunction_narrow_middle={0}, {1} +disjunction_narrow_end={0} o {1} +disjunction_narrow_two={0} o {1} +unit_long_start={0}, {1} +unit_long_middle={0}, {1} +unit_long_end={0} y {1} +unit_long_two={0} y {1} +unit_short_start={0}, {1} +unit_short_middle={0}, {1} +unit_short_end={0}, {1} +unit_short_two={0} y {1} +unit_narrow_start={0} {1} +unit_narrow_middle={0} {1} +unit_narrow_end={0} {1} +unit_narrow_two={0} {1} + +[de] +conjunction_long_start={0}, {1} +conjunction_long_middle={0}, {1} +conjunction_long_end={0} und {1} +conjunction_long_two={0} und {1} +conjunction_short_start={0}, {1} +conjunction_short_middle={0}, {1} +conjunction_short_end={0}, {1} +conjunction_short_two={0}, {1} +conjunction_narrow_start={0}, {1} +conjunction_narrow_middle={0}, {1} +conjunction_narrow_end={0}, {1} +conjunction_narrow_two={0}, {1} +disjunction_long_start={0}, {1} +disjunction_long_middle={0}, {1} +disjunction_long_end={0} oder {1} +disjunction_long_two={0} oder {1} +disjunction_short_start={0}, {1} +disjunction_short_middle={0}, {1} +disjunction_short_end={0} od. {1} +disjunction_short_two={0} od. {1} +disjunction_narrow_start={0}, {1} +disjunction_narrow_middle={0}, {1} +disjunction_narrow_end={0} od. {1} +disjunction_narrow_two={0} od. {1} +unit_long_start={0}, {1} +unit_long_middle={0}, {1} +unit_long_end={0}, {1} +unit_long_two={0}, {1} +unit_short_start={0}, {1} +unit_short_middle={0}, {1} +unit_short_end={0}, {1} +unit_short_two={0}, {1} +unit_narrow_start={0} {1} +unit_narrow_middle={0} {1} +unit_narrow_end={0} {1} +unit_narrow_two={0} {1} + +[pl] +conjunction_long_start={0}, {1} +conjunction_long_middle={0}, {1} +conjunction_long_end={0} i {1} +conjunction_long_two={0} i {1} +conjunction_short_start={0}, {1} +conjunction_short_middle={0}, {1} +conjunction_short_end={0} i {1} +conjunction_short_two={0} i {1} +conjunction_narrow_start={0}, {1} +conjunction_narrow_middle={0}, {1} +conjunction_narrow_end={0} i {1} +conjunction_narrow_two={0} i {1} +disjunction_long_start={0}, {1} +disjunction_long_middle={0}, {1} +disjunction_long_end={0} lub {1} +disjunction_long_two={0} lub {1} +disjunction_short_start={0}, {1} +disjunction_short_middle={0}, {1} +disjunction_short_end={0} lub {1} +disjunction_short_two={0} lub {1} +disjunction_narrow_start={0}, {1} +disjunction_narrow_middle={0}, {1} +disjunction_narrow_end={0} lub {1} +disjunction_narrow_two={0} lub {1} +unit_long_start={0}, {1} +unit_long_middle={0}, {1} +unit_long_end={0}, {1} +unit_long_two={0}, {1} +unit_short_start={0}, {1} +unit_short_middle={0}, {1} +unit_short_end={0}, {1} +unit_short_two={0}, {1} +unit_narrow_start={0} {1} +unit_narrow_middle={0} {1} +unit_narrow_end={0} {1} +unit_narrow_two={0} {1} diff --git a/Jint/Native/Intl/Data/LocaleData.cs b/Jint/Native/Intl/Data/LocaleData.cs new file mode 100644 index 0000000000..283ada7e0e --- /dev/null +++ b/Jint/Native/Intl/Data/LocaleData.cs @@ -0,0 +1,296 @@ +using System.Reflection; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR locale data for canonicalization. +/// Data is loaded from embedded LocaleData.txt resource. +/// +internal static class LocaleData +{ + private static readonly object _lock = new object(); + private static Dictionary? _tagMappings; + private static Dictionary? _languageMappings; + private static Dictionary? _complexLanguageMappings; + private static Dictionary? _regionMappings; + private static Dictionary? _variantMappings; + private static Dictionary? _languageVariantMappings; + private static Dictionary? _scriptRegionMappings; + private static Dictionary>? _unicodeMappings; + private static volatile bool _loaded; + + /// + /// Grandfathered tag mappings (e.g., "art-lojban" → "jbo"). + /// + public static Dictionary TagMappings + { + get + { + EnsureLoaded(); + return _tagMappings!; + } + } + + /// + /// Simple language code mappings (e.g., "cmn" → "zh", "iw" → "he"). + /// + public static Dictionary LanguageMappings + { + get + { + EnsureLoaded(); + return _languageMappings!; + } + } + + /// + /// Complex language mappings that may include script/region. + /// + public static Dictionary ComplexLanguageMappings + { + get + { + EnsureLoaded(); + return _complexLanguageMappings!; + } + } + + /// + /// Region code mappings (e.g., "DD" → "DE", numeric to alpha). + /// + public static Dictionary RegionMappings + { + get + { + EnsureLoaded(); + return _regionMappings!; + } + } + + /// + /// Variant subtag mappings. + /// + public static Dictionary VariantMappings + { + get + { + EnsureLoaded(); + return _variantMappings!; + } + } + + /// + /// Language + variant mappings for grandfathered variants. + /// Key format: "language+variant" (e.g., "art+lojban"), Value: new language (e.g., "jbo"). + /// + public static Dictionary LanguageVariantMappings + { + get + { + EnsureLoaded(); + return _languageVariantMappings!; + } + } + + /// + /// Script + region mappings for deprecated regions (like SU). + /// Key format: "Script+Region" (e.g., "Armn+SU"), Value: new region (e.g., "AM"). + /// + public static Dictionary ScriptRegionMappings + { + get + { + EnsureLoaded(); + return _scriptRegionMappings!; + } + } + + /// + /// Unicode extension value mappings, keyed by extension key (e.g., "ca", "tz"). + /// + public static Dictionary> UnicodeMappings + { + get + { + EnsureLoaded(); + return _unicodeMappings!; + } + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _tagMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _languageMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _complexLanguageMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _regionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _variantMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _languageVariantMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _scriptRegionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + _unicodeMappings = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(LocaleData).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.LocaleData.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentSection = null; + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + currentSection = line.Substring(1, line.Length - 2); + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + switch (currentSection) + { + case "TAG_MAPPINGS": + _tagMappings[key] = value; + break; + + case "LANGUAGE_MAPPINGS": + _languageMappings[key] = value; + break; + + case "COMPLEX_LANGUAGE_MAPPINGS": + ParseComplexLanguageMapping(key, value); + break; + + case "REGION_MAPPINGS": + _regionMappings[key] = value; + break; + + case "VARIANT_MAPPINGS": + ParseVariantMapping(key, value); + break; + + case "LANGUAGE_VARIANT_MAPPINGS": + _languageVariantMappings![key] = value; + break; + + case "SCRIPT_REGION_MAPPINGS": + _scriptRegionMappings![key] = value; + break; + + case "UNICODE_MAPPINGS": + ParseUnicodeMapping(key, value); + break; + } + } + + _loaded = true; + } + } + + private static void ParseComplexLanguageMapping(string key, string value) + { + // Format: language,script:Latn,region:ME + var parts = value.Split(','); + string? script = null; + string? region = null; + + for (var i = 1; i < parts.Length; i++) + { + var part = parts[i]; + if (part.StartsWith("script:", StringComparison.Ordinal)) + { + script = part.Substring(7); + } + else if (part.StartsWith("region:", StringComparison.Ordinal)) + { + region = part.Substring(7); + } + } + + _complexLanguageMappings![key] = new ComplexLanguageMapping(parts[0], script, region); + } + + private static void ParseVariantMapping(string key, string value) + { + // Format: type,replacement + var commaIndex = value.IndexOf(','); + if (commaIndex > 0) + { + _variantMappings![key] = new VariantMapping( + value.Substring(0, commaIndex), + value.Substring(commaIndex + 1) + ); + } + } + + private static void ParseUnicodeMapping(string key, string value) + { + // Format key: keyType:oldValue (e.g., "ca:islamicc") + var colonIndex = key.IndexOf(':'); + if (colonIndex > 0) + { + var keyType = key.Substring(0, colonIndex); + var oldValue = key.Substring(colonIndex + 1); + + if (!_unicodeMappings!.TryGetValue(keyType, out var typeDict)) + { + typeDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + _unicodeMappings[keyType] = typeDict; + } + + typeDict[oldValue] = value; + } + } + + internal readonly struct ComplexLanguageMapping + { + public ComplexLanguageMapping(string language, string? script, string? region) + { + Language = language; + Script = script; + Region = region; + } + + public string Language { get; } + public string? Script { get; } + public string? Region { get; } + } + + internal readonly struct VariantMapping + { + public VariantMapping(string type, string replacement) + { + Type = type; + Replacement = replacement; + } + + public string Type { get; } + public string Replacement { get; } + } +} diff --git a/Jint/Native/Intl/Data/LocaleData.txt b/Jint/Native/Intl/Data/LocaleData.txt new file mode 100644 index 0000000000..d560939efd --- /dev/null +++ b/Jint/Native/Intl/Data/LocaleData.txt @@ -0,0 +1,991 @@ +[TAG_MAPPINGS] +art-lojban=jbo +cel-gaulish=xtg +zh-guoyu=zh +zh-hakka=hak +zh-xiang=hsn + +[LANGUAGE_MAPPINGS] +aam=aas +aar=aa +abk=ab +adp=dz +afr=af +aju=jrb +aka=ak +alb=sq +als=sq +amh=am +ara=ar +arb=ar +arg=an +arm=hy +asd=snz +asm=as +aue=ktz +ava=av +ave=ae +aym=ay +ayr=ay +ayx=nun +aze=az +azj=az +bak=ba +bam=bm +baq=eu +bcc=bal +bcl=bik +bel=be +ben=bn +bgm=bcg +bh=bho +bih=bho +bis=bi +bjd=drl +bod=bo +bos=bs +bre=br +bul=bg +bur=my +bxk=luy +bxr=bua +cat=ca +ccq=rki +ces=cs +cha=ch +che=ce +chi=zh +chu=cu +chv=cv +cjr=mom +cka=cmr +cld=syr +cmk=xch +cmn=zh +cor=kw +cos=co +coy=pij +cqu=quh +cre=cr +cwd=cr +cym=cy +cze=cs +dan=da +deu=de +dgo=doi +dhd=mwr +dik=din +diq=zza +dit=dif +div=dv +drh=mn +dut=nl +dzo=dz +ekk=et +ell=el +emk=man +eng=en +epo=eo +esk=ik +est=et +eus=eu +ewe=ee +fao=fo +fas=fa +fat=ak +fij=fj +fin=fi +fra=fr +fre=fr +fry=fy +fuc=ff +ful=ff +gav=dev +gaz=om +gbo=grb +geo=ka +ger=de +gfx=vaj +ggn=gvr +gla=gd +gle=ga +glg=gl +glv=gv +gno=gon +gre=el +grn=gn +gti=nyc +gug=gn +guj=gu +guv=duz +gya=gba +hat=ht +hau=ha +hdn=hai +hea=hmn +heb=he +her=hz +him=srx +hin=hi +hmo=ho +hrr=jal +hrv=hr +hun=hu +hye=hy +ibi=opa +ibo=ig +ice=is +ido=io +iii=ii +ike=iu +iku=iu +ile=ie +ilw=gal +in=id +ina=ia +ind=id +ipk=ik +isl=is +ita=it +iw=he +jav=jv +jeg=oyb +ji=yi +jpn=ja +jw=jv +kal=kl +kan=kn +kas=ks +kat=ka +kau=kr +kaz=kk +kgc=tdf +kgh=kml +khk=mn +khm=km +kik=ki +kin=rw +kir=ky +kmr=ku +knc=kr +kng=kg +knn=kok +koj=kwv +kom=kv +kon=kg +kor=ko +kpv=kv +krm=bmf +ktr=dtp +kua=kj +kur=ku +kvs=gdj +kwq=yam +kxe=tvd +kzj=dtp +kzt=dtp +lao=lo +lat=la +lav=lv +lbk=bnc +lii=raq +lim=li +lin=ln +lit=lt +llo=ngt +lmm=rmx +ltz=lb +lub=lu +lug=lg +lvs=lv +mac=mk +mah=mh +mal=ml +mao=mi +mar=mr +may=ms +meg=cir +mhr=chm +mkd=mk +mlg=mg +mlt=mt +mnk=man +mo=ro +mol=ro +mon=mn +mri=mi +msa=ms +mst=mry +mup=raj +mwj=vaj +mya=my +myd=aog +myt=mry +nad=xny +nau=na +nav=nv +nbl=nr +ncp=kdz +nde=nd +ndo=ng +nep=ne +nld=nl +nno=nn +nns=nbr +nnx=ngv +no=nb +nob=nb +nor=nb +npi=ne +nts=pij +nya=ny +oci=oc +ojg=oj +oji=oj +ori=or +orm=om +ory=or +oss=os +oun=vaj +pan=pa +pbu=ps +pcr=adx +per=fa +pes=fa +pli=pi +plt=mg +pmc=huw +pmu=phr +pnb=lah +pol=pl +por=pt +ppa=bfy +ppr=lcq +pry=prt +pus=ps +puz=pub +que=qu +quz=qu +rmy=rom +roh=rm +ron=ro +rum=ro +run=rn +rus=ru +sag=sg +san=sa +sca=hle +scc=sr +scr=hr +sin=si +skk=oyb +slk=sk +slo=sk +slv=sl +sme=se +smo=sm +sna=sn +snd=sd +som=so +sot=st +spa=es +spy=kln +sqi=sq +src=sc +srd=sc +srp=sr +ssw=ss +sun=su +swa=sw +swe=sv +swh=sw +tah=ty +tam=ta +tat=tt +tdu=dtp +tel=te +tgk=tg +tgl=fil +tha=th +thc=tpo +thx=oyb +tib=bo +tie=ras +tir=ti +tkk=twm +tl=fil +tlw=weo +tmp=tyj +tne=kak +ton=to +tsf=taj +tsn=tn +tso=ts +ttq=tmh +tuk=tk +tur=tr +tw=ak +twi=ak +uig=ug +ukr=uk +umu=del +uok=ema +urd=ur +uzb=uz +uzn=uz +ven=ve +vie=vi +vol=vo +wel=cy +wln=wa +wol=wo +xba=cax +xho=xh +xia=acn +xkh=waw +xpe=kpe +xsj=suj +xsl=den +ybd=rki +ydd=yi +yid=yi +yma=lrr +ymt=mtm +yor=yo +yos=zom +yuu=yug +zai=zap +zha=za +zho=zh +zsm=ms +zul=zu +zyb=za + +[COMPLEX_LANGUAGE_MAPPINGS] +cnr=sr,region:ME +drw=fa,region:AF +hbs=sr,script:Latn +prs=fa,region:AF +sh=sr,script:Latn +swc=sw,region:CD +tnf=fa,region:AF + +[REGION_MAPPINGS] +100=BG +104=MM +108=BI +112=BY +116=KH +120=CM +124=CA +132=CV +136=KY +140=CF +144=LK +148=TD +152=CL +156=CN +158=TW +162=CX +166=CC +170=CO +174=KM +175=YT +178=CG +180=CD +184=CK +188=CR +191=HR +192=CU +196=CY +203=CZ +204=BJ +208=DK +212=DM +214=DO +218=EC +222=SV +226=GQ +230=ET +231=ET +232=ER +233=EE +234=FO +238=FK +239=GS +242=FJ +246=FI +248=AX +249=FR +250=FR +254=GF +258=PF +260=TF +262=DJ +266=GA +268=GE +270=GM +275=PS +276=DE +278=DE +280=DE +288=GH +292=GI +296=KI +300=GR +304=GL +308=GD +312=GP +316=GU +320=GT +324=GN +328=GY +332=HT +334=HM +336=VA +340=HN +344=HK +348=HU +352=IS +356=IN +360=ID +364=IR +368=IQ +372=IE +376=IL +380=IT +384=CI +388=JM +392=JP +398=KZ +400=JO +404=KE +408=KP +410=KR +414=KW +417=KG +418=LA +422=LB +426=LS +428=LV +430=LR +434=LY +438=LI +440=LT +442=LU +446=MO +450=MG +454=MW +458=MY +462=MV +466=ML +470=MT +474=MQ +478=MR +480=MU +484=MX +492=MC +496=MN +498=MD +499=ME +500=MS +504=MA +508=MZ +512=OM +516=NA +520=NR +524=NP +528=NL +531=CW +533=AW +534=SX +535=BQ +540=NC +548=VU +554=NZ +558=NI +562=NE +566=NG +570=NU +574=NF +578=NO +580=MP +581=UM +583=FM +584=MH +585=PW +586=PK +591=PA +598=PG +600=PY +604=PE +608=PH +612=PN +616=PL +620=PT +624=GW +626=TL +630=PR +634=QA +638=RE +642=RO +643=RU +646=RW +652=BL +654=SH +659=KN +660=AI +662=LC +663=MF +666=PM +670=VC +674=SM +678=ST +682=SA +686=SN +688=RS +690=SC +694=SL +702=SG +703=SK +704=VN +705=SI +706=SO +710=ZA +716=ZW +720=YE +724=ES +728=SS +729=SD +732=EH +736=SD +740=SR +744=SJ +748=SZ +752=SE +756=CH +760=SY +762=TJ +764=TH +768=TG +772=TK +776=TO +780=TT +784=AE +788=TN +792=TR +795=TM +796=TC +798=TV +800=UG +804=UA +807=MK +818=EG +826=GB +830=JE +831=GG +832=JE +833=IM +834=TZ +840=US +850=VI +854=BF +858=UY +860=UZ +862=VE +876=WF +882=WS +886=YE +887=YE +891=RS +894=ZM +958=AA +959=QM +960=QN +962=QP +963=QQ +964=QR +965=QS +966=QT +967=EU +968=QV +969=QW +970=QX +971=QY +972=QZ +973=XA +974=XB +975=XC +976=XD +977=XE +978=XF +979=XG +980=XH +981=XI +982=XJ +983=XK +984=XL +985=XM +986=XN +987=XO +988=XP +989=XQ +990=XR +991=XS +992=XT +993=XU +994=XV +995=XW +996=XX +997=XY +998=XZ +999=ZZ +004=AF +008=AL +010=AQ +012=DZ +016=AS +020=AD +024=AO +028=AG +031=AZ +032=AR +036=AU +040=AT +044=BS +048=BH +050=BD +051=AM +052=BB +056=BE +060=BM +062=034 +064=BT +068=BO +070=BA +072=BW +074=BV +076=BR +084=BZ +086=IO +090=SB +092=VG +096=BN +BU=MM +CS=RS +CT=KI +DD=DE +DY=BJ +FQ=AQ +FX=FR +HV=BF +JT=UM +MI=UM +NH=VU +NQ=AQ +PU=UM +PZ=PA +QU=EU +RH=ZW +TP=TL +UK=GB +VD=VN +WK=UM +YD=YE +YU=RS +ZR=CD + +[VARIANT_MAPPINGS] +aaland=region,AX +arevela=language,hy +arevmda=language,hyw +heploc=variant,alalc97 +polytoni=variant,polyton + +[LANGUAGE_VARIANT_MAPPINGS] +art+lojban=jbo +cel+gaulish=xtg +zh+guoyu=zh +zh+hakka=hak +zh+xiang=hsn + +[SCRIPT_REGION_MAPPINGS] +Armn+SU=AM +Cyrl+SU=RU +Latn+SU=RU +Geor+SU=GE +Arab+SU=UZ + +[UNICODE_MAPPINGS] +ca:ethiopic-amete-alem=ethioaa +ca:islamicc=islamic-civil +kb:yes=true +kc:yes=true +kh:yes=true +kk:yes=true +kn:yes=true +ks:primary=level1 +ks:tertiary=level3 +ms:imperial=uksystem +rg:cn11=cnbj +rg:cn12=cntj +rg:cn13=cnhe +rg:cn14=cnsx +rg:cn15=cnmn +rg:cn21=cnln +rg:cn22=cnjl +rg:cn23=cnhl +rg:cn31=cnsh +rg:cn32=cnjs +rg:cn33=cnzj +rg:cn34=cnah +rg:cn35=cnfj +rg:cn36=cnjx +rg:cn37=cnsd +rg:cn41=cnha +rg:cn42=cnhb +rg:cn43=cnhn +rg:cn44=cngd +rg:cn45=cngx +rg:cn46=cnhi +rg:cn50=cncq +rg:cn51=cnsc +rg:cn52=cngz +rg:cn53=cnyn +rg:cn54=cnxz +rg:cn61=cnsn +rg:cn62=cngs +rg:cn63=cnqh +rg:cn64=cnnx +rg:cn65=cnxj +rg:cz10a=cz110 +rg:cz10b=cz111 +rg:cz10c=cz112 +rg:cz10d=cz113 +rg:cz10e=cz114 +rg:cz10f=cz115 +rg:cz611=cz663 +rg:cz612=cz632 +rg:cz613=cz633 +rg:cz614=cz634 +rg:cz615=cz635 +rg:cz621=cz641 +rg:cz622=cz642 +rg:cz623=cz643 +rg:cz624=cz644 +rg:cz626=cz646 +rg:cz627=cz647 +rg:czjc=cz31 +rg:czjm=cz64 +rg:czka=cz41 +rg:czkr=cz52 +rg:czli=cz51 +rg:czmo=cz80 +rg:czol=cz71 +rg:czpa=cz53 +rg:czpl=cz32 +rg:czpr=cz10 +rg:czst=cz20 +rg:czus=cz42 +rg:czvy=cz63 +rg:czzl=cz72 +rg:fra=frges +rg:frb=frnaq +rg:frc=frara +rg:frd=frbfc +rg:fre=frbre +rg:frf=frcvl +rg:frg=frges +rg:frh=frcor +rg:fri=frbfc +rg:frj=fridf +rg:frk=frocc +rg:frl=frnaq +rg:frm=frges +rg:frn=frocc +rg:fro=frhdf +rg:frp=frnor +rg:frq=frnor +rg:frr=frpdl +rg:frs=frhdf +rg:frt=frnaq +rg:fru=frpac +rg:frv=frara +rg:laxn=laxs +rg:lud=lucl +rg:lug=luec +rg:lul=luca +rg:mrnkc=mr13 +rg:no23=no50 +rg:nzn=nzauk +rg:nzs=nzcan +rg:omba=ombj +rg:omsh=omsj +rg:plds=pl02 +rg:plkp=pl04 +rg:pllb=pl08 +rg:plld=pl10 +rg:pllu=pl06 +rg:plma=pl12 +rg:plmz=pl14 +rg:plop=pl16 +rg:plpd=pl20 +rg:plpk=pl18 +rg:plpm=pl22 +rg:plsk=pl26 +rg:plsl=pl24 +rg:plwn=pl28 +rg:plwp=pl30 +rg:plzp=pl32 +rg:tteto=tttob +rg:ttrcm=ttmrc +rg:ttwto=tttob +rg:twkhq=twkhh +rg:twtnq=twtnn +rg:twtpq=twnwt +rg:twtxq=twtxg +sd:cn11=cnbj +sd:cn12=cntj +sd:cn13=cnhe +sd:cn14=cnsx +sd:cn15=cnmn +sd:cn21=cnln +sd:cn22=cnjl +sd:cn23=cnhl +sd:cn31=cnsh +sd:cn32=cnjs +sd:cn33=cnzj +sd:cn34=cnah +sd:cn35=cnfj +sd:cn36=cnjx +sd:cn37=cnsd +sd:cn41=cnha +sd:cn42=cnhb +sd:cn43=cnhn +sd:cn44=cngd +sd:cn45=cngx +sd:cn46=cnhi +sd:cn50=cncq +sd:cn51=cnsc +sd:cn52=cngz +sd:cn53=cnyn +sd:cn54=cnxz +sd:cn61=cnsn +sd:cn62=cngs +sd:cn63=cnqh +sd:cn64=cnnx +sd:cn65=cnxj +sd:cz10a=cz110 +sd:cz10b=cz111 +sd:cz10c=cz112 +sd:cz10d=cz113 +sd:cz10e=cz114 +sd:cz10f=cz115 +sd:cz611=cz663 +sd:cz612=cz632 +sd:cz613=cz633 +sd:cz614=cz634 +sd:cz615=cz635 +sd:cz621=cz641 +sd:cz622=cz642 +sd:cz623=cz643 +sd:cz624=cz644 +sd:cz626=cz646 +sd:cz627=cz647 +sd:czjc=cz31 +sd:czjm=cz64 +sd:czka=cz41 +sd:czkr=cz52 +sd:czli=cz51 +sd:czmo=cz80 +sd:czol=cz71 +sd:czpa=cz53 +sd:czpl=cz32 +sd:czpr=cz10 +sd:czst=cz20 +sd:czus=cz42 +sd:czvy=cz63 +sd:czzl=cz72 +sd:fra=frges +sd:frb=frnaq +sd:frc=frara +sd:frd=frbfc +sd:fre=frbre +sd:frf=frcvl +sd:frg=frges +sd:frh=frcor +sd:fri=frbfc +sd:frj=fridf +sd:frk=frocc +sd:frl=frnaq +sd:frm=frges +sd:frn=frocc +sd:fro=frhdf +sd:frp=frnor +sd:frq=frnor +sd:frr=frpdl +sd:frs=frhdf +sd:frt=frnaq +sd:fru=frpac +sd:frv=frara +sd:laxn=laxs +sd:lud=lucl +sd:lug=luec +sd:lul=luca +sd:mrnkc=mr13 +sd:no23=no50 +sd:nzn=nzauk +sd:nzs=nzcan +sd:omba=ombj +sd:omsh=omsj +sd:plds=pl02 +sd:plkp=pl04 +sd:pllb=pl08 +sd:plld=pl10 +sd:pllu=pl06 +sd:plma=pl12 +sd:plmz=pl14 +sd:plop=pl16 +sd:plpd=pl20 +sd:plpk=pl18 +sd:plpm=pl22 +sd:plsk=pl26 +sd:plsl=pl24 +sd:plwn=pl28 +sd:plwp=pl30 +sd:plzp=pl32 +sd:tteto=tttob +sd:ttrcm=ttmrc +sd:ttwto=tttob +sd:twkhq=twkhh +sd:twtnq=twtnn +sd:twtpq=twnwt +sd:twtxq=twtxg +tz:aqams=nzakl +tz:cnckg=cnsha +tz:cnhrb=cnsha +tz:cnkhg=cnurc +tz:cuba=cuhav +tz:egypt=egcai +tz:eire=iedub +tz:est=papty +tz:gmt0=gmt +tz:hongkong=hkhkg +tz:hst=utcw10 +tz:iceland=isrey +tz:iran=irthr +tz:israel=jeruslm +tz:jamaica=jmkin +tz:japan=jptyo +tz:libya=lytip +tz:mst=utcw07 +tz:navajo=usden +tz:poland=plwaw +tz:portugal=ptlis +tz:prc=cnsha +tz:roc=twtpe +tz:rok=krsel +tz:turkey=trist +tz:uct=utc +tz:usnavajo=usden +tz:zulu=utc \ No newline at end of file diff --git a/Jint/Native/Intl/Data/NumberingSystemData.cs b/Jint/Native/Intl/Data/NumberingSystemData.cs new file mode 100644 index 0000000000..961fe16579 --- /dev/null +++ b/Jint/Native/Intl/Data/NumberingSystemData.cs @@ -0,0 +1,187 @@ +namespace Jint.Native.Intl.Data; + +/// +/// Provides digit mappings for numbering systems. +/// Based on https://tc39.es/ecma402/#table-numbering-system-digits +/// +internal static class NumberingSystemData +{ + /// + /// Maps numbering system names to their 10-digit strings (0-9). + /// + public static readonly Dictionary Digits = new(StringComparer.OrdinalIgnoreCase) + { + ["adlm"] = "\U0001E950\U0001E951\U0001E952\U0001E953\U0001E954\U0001E955\U0001E956\U0001E957\U0001E958\U0001E959", + ["ahom"] = "\U00011730\U00011731\U00011732\U00011733\U00011734\U00011735\U00011736\U00011737\U00011738\U00011739", + ["arab"] = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669", + ["arabext"] = "\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9", + ["bali"] = "\u1B50\u1B51\u1B52\u1B53\u1B54\u1B55\u1B56\u1B57\u1B58\u1B59", + ["beng"] = "\u09E6\u09E7\u09E8\u09E9\u09EA\u09EB\u09EC\u09ED\u09EE\u09EF", + ["bhks"] = "\U00011C50\U00011C51\U00011C52\U00011C53\U00011C54\U00011C55\U00011C56\U00011C57\U00011C58\U00011C59", + ["brah"] = "\U00011066\U00011067\U00011068\U00011069\U0001106A\U0001106B\U0001106C\U0001106D\U0001106E\U0001106F", + ["cakm"] = "\U00011136\U00011137\U00011138\U00011139\U0001113A\U0001113B\U0001113C\U0001113D\U0001113E\U0001113F", + ["cham"] = "\uAA50\uAA51\uAA52\uAA53\uAA54\uAA55\uAA56\uAA57\uAA58\uAA59", + ["deva"] = "\u0966\u0967\u0968\u0969\u096A\u096B\u096C\u096D\u096E\u096F", + ["diak"] = "\U00011950\U00011951\U00011952\U00011953\U00011954\U00011955\U00011956\U00011957\U00011958\U00011959", + ["fullwide"] = "\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19", + ["gong"] = "\U00011DA0\U00011DA1\U00011DA2\U00011DA3\U00011DA4\U00011DA5\U00011DA6\U00011DA7\U00011DA8\U00011DA9", + ["gonm"] = "\U00011D50\U00011D51\U00011D52\U00011D53\U00011D54\U00011D55\U00011D56\U00011D57\U00011D58\U00011D59", + ["gujr"] = "\u0AE6\u0AE7\u0AE8\u0AE9\u0AEA\u0AEB\u0AEC\u0AED\u0AEE\u0AEF", + ["guru"] = "\u0A66\u0A67\u0A68\u0A69\u0A6A\u0A6B\u0A6C\u0A6D\u0A6E\u0A6F", + ["hanidec"] = "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D", + ["hmng"] = "\U00016B50\U00016B51\U00016B52\U00016B53\U00016B54\U00016B55\U00016B56\U00016B57\U00016B58\U00016B59", + ["hmnp"] = "\U0001E140\U0001E141\U0001E142\U0001E143\U0001E144\U0001E145\U0001E146\U0001E147\U0001E148\U0001E149", + ["java"] = "\uA9D0\uA9D1\uA9D2\uA9D3\uA9D4\uA9D5\uA9D6\uA9D7\uA9D8\uA9D9", + ["kali"] = "\uA900\uA901\uA902\uA903\uA904\uA905\uA906\uA907\uA908\uA909", + ["kawi"] = "\U00011F50\U00011F51\U00011F52\U00011F53\U00011F54\U00011F55\U00011F56\U00011F57\U00011F58\U00011F59", + ["khmr"] = "\u17E0\u17E1\u17E2\u17E3\u17E4\u17E5\u17E6\u17E7\u17E8\u17E9", + ["knda"] = "\u0CE6\u0CE7\u0CE8\u0CE9\u0CEA\u0CEB\u0CEC\u0CED\u0CEE\u0CEF", + ["lana"] = "\u1A80\u1A81\u1A82\u1A83\u1A84\u1A85\u1A86\u1A87\u1A88\u1A89", + ["lanatham"] = "\u1A90\u1A91\u1A92\u1A93\u1A94\u1A95\u1A96\u1A97\u1A98\u1A99", + ["laoo"] = "\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5\u0ED6\u0ED7\u0ED8\u0ED9", + ["latn"] = "0123456789", + ["lepc"] = "\u1C40\u1C41\u1C42\u1C43\u1C44\u1C45\u1C46\u1C47\u1C48\u1C49", + ["limb"] = "\u1946\u1947\u1948\u1949\u194A\u194B\u194C\u194D\u194E\u194F", + ["mathbold"] = "\U0001D7CE\U0001D7CF\U0001D7D0\U0001D7D1\U0001D7D2\U0001D7D3\U0001D7D4\U0001D7D5\U0001D7D6\U0001D7D7", + ["mathdbl"] = "\U0001D7D8\U0001D7D9\U0001D7DA\U0001D7DB\U0001D7DC\U0001D7DD\U0001D7DE\U0001D7DF\U0001D7E0\U0001D7E1", + ["mathmono"] = "\U0001D7F6\U0001D7F7\U0001D7F8\U0001D7F9\U0001D7FA\U0001D7FB\U0001D7FC\U0001D7FD\U0001D7FE\U0001D7FF", + ["mathsanb"] = "\U0001D7EC\U0001D7ED\U0001D7EE\U0001D7EF\U0001D7F0\U0001D7F1\U0001D7F2\U0001D7F3\U0001D7F4\U0001D7F5", + ["mathsans"] = "\U0001D7E2\U0001D7E3\U0001D7E4\U0001D7E5\U0001D7E6\U0001D7E7\U0001D7E8\U0001D7E9\U0001D7EA\U0001D7EB", + ["mlym"] = "\u0D66\u0D67\u0D68\u0D69\u0D6A\u0D6B\u0D6C\u0D6D\u0D6E\u0D6F", + ["modi"] = "\U00011650\U00011651\U00011652\U00011653\U00011654\U00011655\U00011656\U00011657\U00011658\U00011659", + ["mong"] = "\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819", + ["mroo"] = "\U00016A60\U00016A61\U00016A62\U00016A63\U00016A64\U00016A65\U00016A66\U00016A67\U00016A68\U00016A69", + ["mtei"] = "\uABF0\uABF1\uABF2\uABF3\uABF4\uABF5\uABF6\uABF7\uABF8\uABF9", + ["mymr"] = "\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049", + ["mymrshan"] = "\u1090\u1091\u1092\u1093\u1094\u1095\u1096\u1097\u1098\u1099", + ["mymrtlng"] = "\uA9F0\uA9F1\uA9F2\uA9F3\uA9F4\uA9F5\uA9F6\uA9F7\uA9F8\uA9F9", + ["nagm"] = "\U0001E4F0\U0001E4F1\U0001E4F2\U0001E4F3\U0001E4F4\U0001E4F5\U0001E4F6\U0001E4F7\U0001E4F8\U0001E4F9", + ["newa"] = "\U00011450\U00011451\U00011452\U00011453\U00011454\U00011455\U00011456\U00011457\U00011458\U00011459", + ["nkoo"] = "\u07C0\u07C1\u07C2\u07C3\u07C4\u07C5\u07C6\u07C7\u07C8\u07C9", + ["olck"] = "\u1C50\u1C51\u1C52\u1C53\u1C54\u1C55\u1C56\u1C57\u1C58\u1C59", + ["orya"] = "\u0B66\u0B67\u0B68\u0B69\u0B6A\u0B6B\u0B6C\u0B6D\u0B6E\u0B6F", + ["osma"] = "\U000104A0\U000104A1\U000104A2\U000104A3\U000104A4\U000104A5\U000104A6\U000104A7\U000104A8\U000104A9", + ["rohg"] = "\U00010D30\U00010D31\U00010D32\U00010D33\U00010D34\U00010D35\U00010D36\U00010D37\U00010D38\U00010D39", + ["saur"] = "\uA8D0\uA8D1\uA8D2\uA8D3\uA8D4\uA8D5\uA8D6\uA8D7\uA8D8\uA8D9", + ["segment"] = "\U0001FBF0\U0001FBF1\U0001FBF2\U0001FBF3\U0001FBF4\U0001FBF5\U0001FBF6\U0001FBF7\U0001FBF8\U0001FBF9", + ["shrd"] = "\U000111D0\U000111D1\U000111D2\U000111D3\U000111D4\U000111D5\U000111D6\U000111D7\U000111D8\U000111D9", + ["sind"] = "\U000112F0\U000112F1\U000112F2\U000112F3\U000112F4\U000112F5\U000112F6\U000112F7\U000112F8\U000112F9", + ["sinh"] = "\u0DE6\u0DE7\u0DE8\u0DE9\u0DEA\u0DEB\u0DEC\u0DED\u0DEE\u0DEF", + ["sora"] = "\U000110F0\U000110F1\U000110F2\U000110F3\U000110F4\U000110F5\U000110F6\U000110F7\U000110F8\U000110F9", + ["sund"] = "\u1BB0\u1BB1\u1BB2\u1BB3\u1BB4\u1BB5\u1BB6\u1BB7\u1BB8\u1BB9", + ["takr"] = "\U000116C0\U000116C1\U000116C2\U000116C3\U000116C4\U000116C5\U000116C6\U000116C7\U000116C8\U000116C9", + ["talu"] = "\u19D0\u19D1\u19D2\u19D3\u19D4\u19D5\u19D6\u19D7\u19D8\u19D9", + ["tamldec"] = "\u0BE6\u0BE7\u0BE8\u0BE9\u0BEA\u0BEB\u0BEC\u0BED\u0BEE\u0BEF", + ["telu"] = "\u0C66\u0C67\u0C68\u0C69\u0C6A\u0C6B\u0C6C\u0C6D\u0C6E\u0C6F", + ["thai"] = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59", + ["tibt"] = "\u0F20\u0F21\u0F22\u0F23\u0F24\u0F25\u0F26\u0F27\u0F28\u0F29", + ["tirh"] = "\U000114D0\U000114D1\U000114D2\U000114D3\U000114D4\U000114D5\U000114D6\U000114D7\U000114D8\U000114D9", + ["tnsa"] = "\U00016AC0\U00016AC1\U00016AC2\U00016AC3\U00016AC4\U00016AC5\U00016AC6\U00016AC7\U00016AC8\U00016AC9", + ["vaii"] = "\uA620\uA621\uA622\uA623\uA624\uA625\uA626\uA627\uA628\uA629", + ["wara"] = "\U000118E0\U000118E1\U000118E2\U000118E3\U000118E4\U000118E5\U000118E6\U000118E7\U000118E8\U000118E9", + ["wcho"] = "\U0001E2F0\U0001E2F1\U0001E2F2\U0001E2F3\U0001E2F4\U0001E2F5\U0001E2F6\U0001E2F7\U0001E2F8\U0001E2F9", + }; + + /// + /// Maps numbering systems to their decimal separators (only for those that differ from '.'). + /// Based on CLDR data. + /// + private static readonly Dictionary DecimalSeparators = new(StringComparer.OrdinalIgnoreCase) + { + ["arab"] = '\u066B', // Arabic decimal separator ٫ + ["arabext"] = '\u066B', // Arabic decimal separator ٫ + }; + + /// + /// Gets the decimal separator for a numbering system. + /// Returns '.' for most systems, or the localized separator for systems like Arabic. + /// + public static char GetDecimalSeparator(string numberingSystem) + { + return DecimalSeparators.TryGetValue(numberingSystem, out var separator) ? separator : '.'; + } + + /// + /// Transliterates Latin digits (0-9) and decimal separator in the input string to the specified numbering system. + /// + public static string TransliterateDigits(string input, string numberingSystem) + { + // "latn" is the default - no transliteration needed + if (string.Equals(numberingSystem, "latn", StringComparison.OrdinalIgnoreCase)) + { + return input; + } + + if (!Digits.TryGetValue(numberingSystem, out var targetDigits)) + { + // Unknown numbering system - return as-is + return input; + } + + // Get the decimal separator for this numbering system + var decimalSeparator = GetDecimalSeparator(numberingSystem); + + // Use a StringBuilder for efficient character replacement + var sb = new System.Text.StringBuilder(input.Length * 2); // Extra space for surrogate pairs + + foreach (var c in input) + { + if (c >= '0' && c <= '9') + { + // Replace Latin digit with target numbering system digit + var digitIndex = c - '0'; + // Get the digit at the appropriate index (handling surrogate pairs) + var digitStr = GetDigitAtIndex(targetDigits, digitIndex); + sb.Append(digitStr); + } + else if (c == '.' && decimalSeparator != '.') + { + // Replace Latin decimal separator with target numbering system's separator + sb.Append(decimalSeparator); + } + else + { + sb.Append(c); + } + } + + return sb.ToString(); + } + + /// + /// Gets the digit character(s) at the specified index in a digit string. + /// Handles surrogate pairs for characters outside the BMP. + /// + private static string GetDigitAtIndex(string digits, int index) + { + var currentIndex = 0; + var i = 0; + + while (i < digits.Length) + { + if (currentIndex == index) + { + // Check if this is a surrogate pair + if (char.IsHighSurrogate(digits[i]) && i + 1 < digits.Length && char.IsLowSurrogate(digits[i + 1])) + { + return digits.Substring(i, 2); + } + return digits[i].ToString(); + } + + // Advance past this character (handling surrogate pairs) + if (char.IsHighSurrogate(digits[i]) && i + 1 < digits.Length && char.IsLowSurrogate(digits[i + 1])) + { + i += 2; + } + else + { + i += 1; + } + currentIndex++; + } + + // Should not reach here if index is valid (0-9) + return index.ToString(System.Globalization.CultureInfo.InvariantCulture); + } +} diff --git a/Jint/Native/Intl/Data/RelativeTimePatternsData.cs b/Jint/Native/Intl/Data/RelativeTimePatternsData.cs new file mode 100644 index 0000000000..1b21789716 --- /dev/null +++ b/Jint/Native/Intl/Data/RelativeTimePatternsData.cs @@ -0,0 +1,223 @@ +using System.Reflection; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR relative time formatting patterns for locale-aware relative time formatting. +/// Data is loaded from embedded RelativeTimePatternsData.txt resource. +/// +internal static class RelativeTimePatternsData +{ + private static readonly object _lock = new(); + private static Dictionary? _data; + private static volatile bool _loaded; + + /// + /// Gets relative time data for a locale. + /// Falls back to English if locale not found. + /// + public static LocaleRelativeTimeData? GetDataForLocale(string locale) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(locale)) + { + // Get language code from locale (e.g., "es" from "es-ES") + var language = GetLanguageCode(locale); + + // Try to find data for this language + if (_data!.TryGetValue(language, out var data)) + { + return data; + } + } + + // Fall back to English if not found and not already English + if (!IsEnglish(locale)) + { + if (_data!.TryGetValue("en", out var enData)) + { + return enData; + } + } + + return null; + } + + private static string GetLanguageCode(string locale) + { + if (string.IsNullOrEmpty(locale)) + { + return "en"; + } + + // Extract language code (e.g., "es" from "es-ES") + var dashIndex = locale.IndexOf('-'); + return dashIndex > 0 ? locale.Substring(0, dashIndex) : locale; + } + + private static bool IsEnglish(string? locale) + { + if (string.IsNullOrEmpty(locale)) + { + return false; + } + + return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase); + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _data = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(RelativeTimePatternsData).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.RelativeTimePatternsData.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentLocale = null; + + // Temporary storage for building patterns + var tempPatterns = new Dictionary>(StringComparer.Ordinal); + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + // Save previous locale data + if (currentLocale != null && tempPatterns.Count > 0) + { + var localeData = BuildLocaleDataFromTemp(tempPatterns); + _data[currentLocale] = localeData; + tempPatterns.Clear(); + } + + currentLocale = line.Substring(1, line.Length - 2); + continue; + } + + if (currentLocale == null) + { + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + // Parse key: unit_style_direction_pluralForm + // Example: "second_long_future_one" or "second_long_past_other" + var parts = key.Split('_'); + if (parts.Length >= 4) + { + var unit = parts[0]; // second, minute, hour, day, week, month, quarter, year + var style = parts[1]; // long, short, narrow + var direction = parts[2]; // future, past + var pluralForm = parts[3]; // one, few, many, other + + var unitStyleKey = unit + "_" + style; + if (!tempPatterns.TryGetValue(unitStyleKey, out var directionPatterns)) + { + directionPatterns = new Dictionary(StringComparer.Ordinal); + tempPatterns[unitStyleKey] = directionPatterns; + } + + var directionPluralKey = direction + "_" + pluralForm; + directionPatterns[directionPluralKey] = value; + } + } + + // Save last locale data + if (currentLocale != null && tempPatterns.Count > 0) + { + var localeData = BuildLocaleDataFromTemp(tempPatterns); + _data[currentLocale] = localeData; + } + + _loaded = true; + } + } + + private static LocaleRelativeTimeData BuildLocaleDataFromTemp(Dictionary> tempPatterns) + { + var patterns = new Dictionary(StringComparer.Ordinal); + + foreach (var kvp in tempPatterns) + { + var unitStyleKey = kvp.Key; + var directionPatterns = kvp.Value; + + var unitStylePatterns = new UnitStylePatterns + { + Patterns = new Dictionary(directionPatterns, StringComparer.Ordinal) + }; + + patterns[unitStyleKey] = unitStylePatterns; + } + + return new LocaleRelativeTimeData + { + Patterns = patterns + }; + } +} + +/// +/// Relative time data for a specific locale. +/// +internal sealed class LocaleRelativeTimeData +{ + /// + /// Patterns organized by unit_style (e.g., "second_long", "day_short"). + /// + public required Dictionary Patterns { get; init; } +} + +/// +/// Patterns for a specific unit and style combination. +/// +internal sealed class UnitStylePatterns +{ + /// + /// Patterns organized by direction_pluralForm (e.g., "future_one", "past_other", "future_few"). + /// + public required Dictionary Patterns { get; init; } + + /// + /// Gets the pattern for a specific direction and plural form. + /// + /// True for past direction, false for future. + /// Plural form (one, few, many, other). + /// The pattern string, or null if not found. + public string? GetPattern(bool isPast, string pluralForm) + { + var key = (isPast ? "past_" : "future_") + pluralForm; + return Patterns.TryGetValue(key, out var pattern) ? pattern : null; + } +} diff --git a/Jint/Native/Intl/Data/RelativeTimePatternsData.txt b/Jint/Native/Intl/Data/RelativeTimePatternsData.txt new file mode 100644 index 0000000000..b7236f102f --- /dev/null +++ b/Jint/Native/Intl/Data/RelativeTimePatternsData.txt @@ -0,0 +1,487 @@ +[en] +second_long_future_one=in {0} second +second_long_future_other=in {0} seconds +second_long_past_one={0} second ago +second_long_past_other={0} seconds ago +second_short_future_one=in {0} sec. +second_short_future_other=in {0} sec. +second_short_past_one={0} sec. ago +second_short_past_other={0} sec. ago +second_narrow_future_one=in {0}s +second_narrow_future_other=in {0}s +second_narrow_past_one={0}s ago +second_narrow_past_other={0}s ago +minute_long_future_one=in {0} minute +minute_long_future_other=in {0} minutes +minute_long_past_one={0} minute ago +minute_long_past_other={0} minutes ago +minute_short_future_one=in {0} min. +minute_short_future_other=in {0} min. +minute_short_past_one={0} min. ago +minute_short_past_other={0} min. ago +minute_narrow_future_one=in {0}m +minute_narrow_future_other=in {0}m +minute_narrow_past_one={0}m ago +minute_narrow_past_other={0}m ago +hour_long_future_one=in {0} hour +hour_long_future_other=in {0} hours +hour_long_past_one={0} hour ago +hour_long_past_other={0} hours ago +hour_short_future_one=in {0} hr. +hour_short_future_other=in {0} hr. +hour_short_past_one={0} hr. ago +hour_short_past_other={0} hr. ago +hour_narrow_future_one=in {0}h +hour_narrow_future_other=in {0}h +hour_narrow_past_one={0}h ago +hour_narrow_past_other={0}h ago +day_long_future_one=in {0} day +day_long_future_other=in {0} days +day_long_past_one={0} day ago +day_long_past_other={0} days ago +day_short_future_one=in {0} day +day_short_future_other=in {0} days +day_short_past_one={0} day ago +day_short_past_other={0} days ago +day_narrow_future_one=in {0}d +day_narrow_future_other=in {0}d +day_narrow_past_one={0}d ago +day_narrow_past_other={0}d ago +week_long_future_one=in {0} week +week_long_future_other=in {0} weeks +week_long_past_one={0} week ago +week_long_past_other={0} weeks ago +week_short_future_one=in {0} wk. +week_short_future_other=in {0} wk. +week_short_past_one={0} wk. ago +week_short_past_other={0} wk. ago +week_narrow_future_one=in {0}w +week_narrow_future_other=in {0}w +week_narrow_past_one={0}w ago +week_narrow_past_other={0}w ago +month_long_future_one=in {0} month +month_long_future_other=in {0} months +month_long_past_one={0} month ago +month_long_past_other={0} months ago +month_short_future_one=in {0} mo. +month_short_future_other=in {0} mo. +month_short_past_one={0} mo. ago +month_short_past_other={0} mo. ago +month_narrow_future_one=in {0}mo +month_narrow_future_other=in {0}mo +month_narrow_past_one={0}mo ago +month_narrow_past_other={0}mo ago +quarter_long_future_one=in {0} quarter +quarter_long_future_other=in {0} quarters +quarter_long_past_one={0} quarter ago +quarter_long_past_other={0} quarters ago +quarter_short_future_one=in {0} qtr. +quarter_short_future_other=in {0} qtrs. +quarter_short_past_one={0} qtr. ago +quarter_short_past_other={0} qtrs. ago +quarter_narrow_future_one=in {0}q +quarter_narrow_future_other=in {0}q +quarter_narrow_past_one={0}q ago +quarter_narrow_past_other={0}q ago +year_long_future_one=in {0} year +year_long_future_other=in {0} years +year_long_past_one={0} year ago +year_long_past_other={0} years ago +year_short_future_one=in {0} yr. +year_short_future_other=in {0} yr. +year_short_past_one={0} yr. ago +year_short_past_other={0} yr. ago +year_narrow_future_one=in {0}y +year_narrow_future_other=in {0}y +year_narrow_past_one={0}y ago +year_narrow_past_other={0}y ago + +[es] +second_long_future_one=dentro de {0} segundo +second_long_future_other=dentro de {0} segundos +second_long_past_one=hace {0} segundo +second_long_past_other=hace {0} segundos +second_short_future_one=dentro de {0} s +second_short_future_other=dentro de {0} s +second_short_past_one=hace {0} s +second_short_past_other=hace {0} s +second_narrow_future_one=en {0} s +second_narrow_future_other=en {0} s +second_narrow_past_one=hace {0} s +second_narrow_past_other=hace {0} s +minute_long_future_one=dentro de {0} minuto +minute_long_future_other=dentro de {0} minutos +minute_long_past_one=hace {0} minuto +minute_long_past_other=hace {0} minutos +minute_short_future_one=dentro de {0} min +minute_short_future_other=dentro de {0} min +minute_short_past_one=hace {0} min +minute_short_past_other=hace {0} min +minute_narrow_future_one=en {0} min +minute_narrow_future_other=en {0} min +minute_narrow_past_one=hace {0} min +minute_narrow_past_other=hace {0} min +hour_long_future_one=dentro de {0} hora +hour_long_future_other=dentro de {0} horas +hour_long_past_one=hace {0} hora +hour_long_past_other=hace {0} horas +hour_short_future_one=dentro de {0} h +hour_short_future_other=dentro de {0} h +hour_short_past_one=hace {0} h +hour_short_past_other=hace {0} h +hour_narrow_future_one=en {0} h +hour_narrow_future_other=en {0} h +hour_narrow_past_one=hace {0} h +hour_narrow_past_other=hace {0} h +day_long_future_one=dentro de {0} día +day_long_future_other=dentro de {0} días +day_long_past_one=hace {0} día +day_long_past_other=hace {0} días +day_short_future_one=dentro de {0} día +day_short_future_other=dentro de {0} días +day_short_past_one=hace {0} día +day_short_past_other=hace {0} días +day_narrow_future_one=en {0} d +day_narrow_future_other=en {0} d +day_narrow_past_one=hace {0} d +day_narrow_past_other=hace {0} d +week_long_future_one=dentro de {0} semana +week_long_future_other=dentro de {0} semanas +week_long_past_one=hace {0} semana +week_long_past_other=hace {0} semanas +week_short_future_one=dentro de {0} sem. +week_short_future_other=dentro de {0} sem. +week_short_past_one=hace {0} sem. +week_short_past_other=hace {0} sem. +week_narrow_future_one=en {0} sem. +week_narrow_future_other=en {0} sem. +week_narrow_past_one=hace {0} sem. +week_narrow_past_other=hace {0} sem. +month_long_future_one=dentro de {0} mes +month_long_future_other=dentro de {0} meses +month_long_past_one=hace {0} mes +month_long_past_other=hace {0} meses +month_short_future_one=dentro de {0} m +month_short_future_other=dentro de {0} m +month_short_past_one=hace {0} m +month_short_past_other=hace {0} m +month_narrow_future_one=en {0} m +month_narrow_future_other=en {0} m +month_narrow_past_one=hace {0} m +month_narrow_past_other=hace {0} m +quarter_long_future_one=dentro de {0} trimestre +quarter_long_future_other=dentro de {0} trimestres +quarter_long_past_one=hace {0} trimestre +quarter_long_past_other=hace {0} trimestres +quarter_short_future_one=dentro de {0} trim. +quarter_short_future_other=dentro de {0} trim. +quarter_short_past_one=hace {0} trim. +quarter_short_past_other=hace {0} trim. +quarter_narrow_future_one=en {0} T +quarter_narrow_future_other=en {0} T +quarter_narrow_past_one=hace {0} T +quarter_narrow_past_other=hace {0} T +year_long_future_one=dentro de {0} año +year_long_future_other=dentro de {0} años +year_long_past_one=hace {0} año +year_long_past_other=hace {0} años +year_short_future_one=dentro de {0} a +year_short_future_other=dentro de {0} a +year_short_past_one=hace {0} a +year_short_past_other=hace {0} a +year_narrow_future_one=en {0} a +year_narrow_future_other=en {0} a +year_narrow_past_one=hace {0} a +year_narrow_past_other=hace {0} a + +[de] +second_long_future_one=in {0} Sekunde +second_long_future_other=in {0} Sekunden +second_long_past_one=vor {0} Sekunde +second_long_past_other=vor {0} Sekunden +second_short_future_one=in {0} Sek. +second_short_future_other=in {0} Sek. +second_short_past_one=vor {0} Sek. +second_short_past_other=vor {0} Sek. +second_narrow_future_one=in {0} s +second_narrow_future_other=in {0} s +second_narrow_past_one=vor {0} s +second_narrow_past_other=vor {0} s +minute_long_future_one=in {0} Minute +minute_long_future_other=in {0} Minuten +minute_long_past_one=vor {0} Minute +minute_long_past_other=vor {0} Minuten +minute_short_future_one=in {0} Min. +minute_short_future_other=in {0} Min. +minute_short_past_one=vor {0} Min. +minute_short_past_other=vor {0} Min. +minute_narrow_future_one=in {0} Min. +minute_narrow_future_other=in {0} Min. +minute_narrow_past_one=vor {0} Min. +minute_narrow_past_other=vor {0} Min. +hour_long_future_one=in {0} Stunde +hour_long_future_other=in {0} Stunden +hour_long_past_one=vor {0} Stunde +hour_long_past_other=vor {0} Stunden +hour_short_future_one=in {0} Std. +hour_short_future_other=in {0} Std. +hour_short_past_one=vor {0} Std. +hour_short_past_other=vor {0} Std. +hour_narrow_future_one=in {0} Std. +hour_narrow_future_other=in {0} Std. +hour_narrow_past_one=vor {0} Std. +hour_narrow_past_other=vor {0} Std. +day_long_future_one=in {0} Tag +day_long_future_other=in {0} Tagen +day_long_past_one=vor {0} Tag +day_long_past_other=vor {0} Tagen +day_short_future_one=in {0} Tag +day_short_future_other=in {0} Tagen +day_short_past_one=vor {0} Tag +day_short_past_other=vor {0} Tagen +day_narrow_future_one=in {0} T +day_narrow_future_other=in {0} T +day_narrow_past_one=vor {0} T +day_narrow_past_other=vor {0} T +week_long_future_one=in {0} Woche +week_long_future_other=in {0} Wochen +week_long_past_one=vor {0} Woche +week_long_past_other=vor {0} Wochen +week_short_future_one=in {0} Wo. +week_short_future_other=in {0} Wo. +week_short_past_one=vor {0} Wo. +week_short_past_other=vor {0} Wo. +week_narrow_future_one=in {0} W +week_narrow_future_other=in {0} W +week_narrow_past_one=vor {0} W +week_narrow_past_other=vor {0} W +month_long_future_one=in {0} Monat +month_long_future_other=in {0} Monaten +month_long_past_one=vor {0} Monat +month_long_past_other=vor {0} Monaten +month_short_future_one=in {0} Mon. +month_short_future_other=in {0} Mon. +month_short_past_one=vor {0} Mon. +month_short_past_other=vor {0} Mon. +month_narrow_future_one=in {0} M +month_narrow_future_other=in {0} M +month_narrow_past_one=vor {0} M +month_narrow_past_other=vor {0} M +quarter_long_future_one=in {0} Quartal +quarter_long_future_other=in {0} Quartalen +quarter_long_past_one=vor {0} Quartal +quarter_long_past_other=vor {0} Quartalen +quarter_short_future_one=in {0} Quart. +quarter_short_future_other=in {0} Quart. +quarter_short_past_one=vor {0} Quart. +quarter_short_past_other=vor {0} Quart. +quarter_narrow_future_one=in {0} Q +quarter_narrow_future_other=in {0} Q +quarter_narrow_past_one=vor {0} Q +quarter_narrow_past_other=vor {0} Q +year_long_future_one=in {0} Jahr +year_long_future_other=in {0} Jahren +year_long_past_one=vor {0} Jahr +year_long_past_other=vor {0} Jahren +year_short_future_one=in {0} J +year_short_future_other=in {0} J +year_short_past_one=vor {0} J +year_short_past_other=vor {0} J +year_narrow_future_one=in {0} J +year_narrow_future_other=in {0} J +year_narrow_past_one=vor {0} J +year_narrow_past_other=vor {0} J + +[pl] +second_long_future_one=za {0} sekundę +second_long_future_few=za {0} sekundy +second_long_future_many=za {0} sekund +second_long_future_other=za {0} sekundy +second_long_past_one={0} sekundę temu +second_long_past_few={0} sekundy temu +second_long_past_many={0} sekund temu +second_long_past_other={0} sekundy temu +second_short_future_one=za {0} sek. +second_short_future_few=za {0} sek. +second_short_future_many=za {0} sek. +second_short_future_other=za {0} sek. +second_short_past_one={0} sek. temu +second_short_past_few={0} sek. temu +second_short_past_many={0} sek. temu +second_short_past_other={0} sek. temu +second_narrow_future_one=za {0} s +second_narrow_future_few=za {0} s +second_narrow_future_many=za {0} s +second_narrow_future_other=za {0} s +second_narrow_past_one={0} s temu +second_narrow_past_few={0} s temu +second_narrow_past_many={0} s temu +second_narrow_past_other={0} s temu +minute_long_future_one=za {0} minutę +minute_long_future_few=za {0} minuty +minute_long_future_many=za {0} minut +minute_long_future_other=za {0} minuty +minute_long_past_one={0} minutę temu +minute_long_past_few={0} minuty temu +minute_long_past_many={0} minut temu +minute_long_past_other={0} minuty temu +minute_short_future_one=za {0} min +minute_short_future_few=za {0} min +minute_short_future_many=za {0} min +minute_short_future_other=za {0} min +minute_short_past_one={0} min temu +minute_short_past_few={0} min temu +minute_short_past_many={0} min temu +minute_short_past_other={0} min temu +minute_narrow_future_one=za {0} min +minute_narrow_future_few=za {0} min +minute_narrow_future_many=za {0} min +minute_narrow_future_other=za {0} min +minute_narrow_past_one={0} min temu +minute_narrow_past_few={0} min temu +minute_narrow_past_many={0} min temu +minute_narrow_past_other={0} min temu +hour_long_future_one=za {0} godzinę +hour_long_future_few=za {0} godziny +hour_long_future_many=za {0} godzin +hour_long_future_other=za {0} godziny +hour_long_past_one={0} godzinę temu +hour_long_past_few={0} godziny temu +hour_long_past_many={0} godzin temu +hour_long_past_other={0} godziny temu +hour_short_future_one=za {0} godz. +hour_short_future_few=za {0} godz. +hour_short_future_many=za {0} godz. +hour_short_future_other=za {0} godz. +hour_short_past_one={0} godz. temu +hour_short_past_few={0} godz. temu +hour_short_past_many={0} godz. temu +hour_short_past_other={0} godz. temu +hour_narrow_future_one=za {0} g. +hour_narrow_future_few=za {0} g. +hour_narrow_future_many=za {0} g. +hour_narrow_future_other=za {0} g. +hour_narrow_past_one={0} g. temu +hour_narrow_past_few={0} g. temu +hour_narrow_past_many={0} g. temu +hour_narrow_past_other={0} g. temu +day_long_future_one=za {0} dzień +day_long_future_few=za {0} dni +day_long_future_many=za {0} dni +day_long_future_other=za {0} dnia +day_long_past_one={0} dzień temu +day_long_past_few={0} dni temu +day_long_past_many={0} dni temu +day_long_past_other={0} dnia temu +day_short_future_one=za {0} dzień +day_short_future_few=za {0} dni +day_short_future_many=za {0} dni +day_short_future_other=za {0} dnia +day_short_past_one={0} dzień temu +day_short_past_few={0} dni temu +day_short_past_many={0} dni temu +day_short_past_other={0} dnia temu +day_narrow_future_one=za {0} dzień +day_narrow_future_few=za {0} dni +day_narrow_future_many=za {0} dni +day_narrow_future_other=za {0} dnia +day_narrow_past_one={0} dzień temu +day_narrow_past_few={0} dni temu +day_narrow_past_many={0} dni temu +day_narrow_past_other={0} dnia temu +week_long_future_one=za {0} tydzień +week_long_future_few=za {0} tygodnie +week_long_future_many=za {0} tygodni +week_long_future_other=za {0} tygodnia +week_long_past_one={0} tydzień temu +week_long_past_few={0} tygodnie temu +week_long_past_many={0} tygodni temu +week_long_past_other={0} tygodnia temu +week_short_future_one=za {0} tydz. +week_short_future_few=za {0} tyg. +week_short_future_many=za {0} tyg. +week_short_future_other=za {0} tyg. +week_short_past_one={0} tydz. temu +week_short_past_few={0} tyg. temu +week_short_past_many={0} tyg. temu +week_short_past_other={0} tyg. temu +week_narrow_future_one=za {0} tydz. +week_narrow_future_few=za {0} tyg. +week_narrow_future_many=za {0} tyg. +week_narrow_future_other=za {0} tyg. +week_narrow_past_one={0} tydz. temu +week_narrow_past_few={0} tyg. temu +week_narrow_past_many={0} tyg. temu +week_narrow_past_other={0} tyg. temu +month_long_future_one=za {0} miesiąc +month_long_future_few=za {0} miesiące +month_long_future_many=za {0} miesięcy +month_long_future_other=za {0} miesiąca +month_long_past_one={0} miesiąc temu +month_long_past_few={0} miesiące temu +month_long_past_many={0} miesięcy temu +month_long_past_other={0} miesiąca temu +month_short_future_one=za {0} mies. +month_short_future_few=za {0} mies. +month_short_future_many=za {0} mies. +month_short_future_other=za {0} mies. +month_short_past_one={0} mies. temu +month_short_past_few={0} mies. temu +month_short_past_many={0} mies. temu +month_short_past_other={0} mies. temu +month_narrow_future_one=za {0} mies. +month_narrow_future_few=za {0} mies. +month_narrow_future_many=za {0} mies. +month_narrow_future_other=za {0} mies. +month_narrow_past_one={0} mies. temu +month_narrow_past_few={0} mies. temu +month_narrow_past_many={0} mies. temu +month_narrow_past_other={0} mies. temu +quarter_long_future_one=za {0} kwartał +quarter_long_future_few=za {0} kwartały +quarter_long_future_many=za {0} kwartałów +quarter_long_future_other=za {0} kwartału +quarter_long_past_one={0} kwartał temu +quarter_long_past_few={0} kwartały temu +quarter_long_past_many={0} kwartałów temu +quarter_long_past_other={0} kwartału temu +quarter_short_future_one=za {0} kw. +quarter_short_future_few=za {0} kw. +quarter_short_future_many=za {0} kw. +quarter_short_future_other=za {0} kw. +quarter_short_past_one={0} kw. temu +quarter_short_past_few={0} kw. temu +quarter_short_past_many={0} kw. temu +quarter_short_past_other={0} kw. temu +quarter_narrow_future_one=za {0} kw. +quarter_narrow_future_few=za {0} kw. +quarter_narrow_future_many=za {0} kw. +quarter_narrow_future_other=za {0} kw. +quarter_narrow_past_one={0} kw. temu +quarter_narrow_past_few={0} kw. temu +quarter_narrow_past_many={0} kw. temu +quarter_narrow_past_other={0} kw. temu +year_long_future_one=za {0} rok +year_long_future_few=za {0} lata +year_long_future_many=za {0} lat +year_long_future_other=za {0} roku +year_long_past_one={0} rok temu +year_long_past_few={0} lata temu +year_long_past_many={0} lat temu +year_long_past_other={0} roku temu +year_short_future_one=za {0} rok +year_short_future_few=za {0} lata +year_short_future_many=za {0} lat +year_short_future_other=za {0} roku +year_short_past_one={0} rok temu +year_short_past_few={0} lata temu +year_short_past_many={0} lat temu +year_short_past_other={0} roku temu +year_narrow_future_one=za {0} rok +year_narrow_future_few=za {0} lata +year_narrow_future_many=za {0} lat +year_narrow_future_other=za {0} roku +year_narrow_past_one={0} rok temu +year_narrow_past_few={0} lata temu +year_narrow_past_many={0} lat temu +year_narrow_past_other={0} roku temu diff --git a/Jint/Native/Intl/Data/TimeZoneData.cs b/Jint/Native/Intl/Data/TimeZoneData.cs new file mode 100644 index 0000000000..c209ecb992 --- /dev/null +++ b/Jint/Native/Intl/Data/TimeZoneData.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Generic; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides IANA time zone data for ECMA-402 compliance. +/// Contains canonical timezone IDs and case-insensitive lookup. +/// +internal static class TimeZoneData +{ + // Lazy initialization to avoid startup cost + private static Dictionary? _caseInsensitiveLookup; + private static readonly object _lock = new(); + + /// + /// Canonical IANA timezone identifiers (Zone names only - primary identifiers). + /// These are returned by Intl.supportedValuesOf("timeZone"). + /// Does NOT include Link names or UTC aliases (Etc/GMT, Etc/UTC, GMT). + /// + private static readonly string[] CanonicalZones = + [ + // IANA TZDB Zone names (primary identifiers) + "Africa/Abidjan", "Africa/Algiers", "Africa/Bissau", "Africa/Cairo", + "Africa/Casablanca", "Africa/Ceuta", "Africa/El_Aaiun", "Africa/Johannesburg", + "Africa/Juba", "Africa/Khartoum", "Africa/Lagos", "Africa/Maputo", + "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Sao_Tome", + "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", + "America/Adak", "America/Anchorage", "America/Araguaina", + "America/Argentina/Buenos_Aires", "America/Argentina/Catamarca", + "America/Argentina/Cordoba", "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", + "America/Argentina/San_Juan", "America/Argentina/San_Luis", + "America/Argentina/Tucuman", "America/Argentina/Ushuaia", + "America/Asuncion", "America/Bahia", "America/Bahia_Banderas", + "America/Barbados", "America/Belem", "America/Belize", "America/Boa_Vista", + "America/Bogota", "America/Boise", "America/Cambridge_Bay", + "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Cayenne", + "America/Chicago", "America/Chihuahua", "America/Ciudad_Juarez", + "America/Costa_Rica", "America/Cuiaba", "America/Danmarkshavn", + "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", + "America/Edmonton", "America/Eirunepe", "America/El_Salvador", + "America/Fort_Nelson", "America/Fortaleza", "America/Glace_Bay", + "America/Goose_Bay", "America/Grand_Turk", "America/Guatemala", + "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", + "America/Hermosillo", "America/Indiana/Indianapolis", "America/Indiana/Knox", + "America/Indiana/Marengo", "America/Indiana/Petersburg", + "America/Indiana/Tell_City", "America/Indiana/Vevay", + "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Inuvik", + "America/Iqaluit", "America/Jamaica", "America/Juneau", + "America/Kentucky/Louisville", "America/Kentucky/Monticello", + "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Maceio", + "America/Managua", "America/Manaus", "America/Martinique", "America/Matamoros", + "America/Mazatlan", "America/Menominee", "America/Merida", "America/Metlakatla", + "America/Mexico_City", "America/Miquelon", "America/Moncton", + "America/Monterrey", "America/Montevideo", "America/New_York", "America/Nome", + "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", "America/Nuuk", "America/Ojinaga", + "America/Panama", "America/Paramaribo", "America/Phoenix", + "America/Port-au-Prince", "America/Porto_Velho", "America/Puerto_Rico", + "America/Punta_Arenas", "America/Rankin_Inlet", "America/Recife", + "America/Regina", "America/Resolute", "America/Rio_Branco", + "America/Santarem", "America/Santiago", "America/Santo_Domingo", + "America/Sao_Paulo", "America/Scoresbysund", "America/Sitka", + "America/St_Johns", "America/Swift_Current", "America/Tegucigalpa", + "America/Thule", "America/Tijuana", "America/Toronto", "America/Vancouver", + "America/Whitehorse", "America/Winnipeg", "America/Yakutat", + "America/Yellowknife", + "Antarctica/Casey", "Antarctica/Davis", "Antarctica/Macquarie", + "Antarctica/Mawson", "Antarctica/Palmer", "Antarctica/Rothera", + "Antarctica/Troll", + "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", + "Asia/Ashgabat", "Asia/Atyrau", "Asia/Baghdad", "Asia/Baku", "Asia/Bangkok", + "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Chita", "Asia/Choibalsan", + "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", + "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Hebron", + "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", + "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", + "Asia/Kamchatka", "Asia/Karachi", "Asia/Kathmandu", "Asia/Khandyga", + "Asia/Kolkata", "Asia/Krasnoyarsk", "Asia/Kuching", "Asia/Macau", + "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Nicosia", + "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", + "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qostanay", + "Asia/Qyzylorda", "Asia/Riyadh", "Asia/Sakhalin", "Asia/Samarkand", + "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", + "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Thimphu", + "Asia/Tokyo", "Asia/Tomsk", "Asia/Ulaanbaatar", "Asia/Urumqi", "Asia/Ust-Nera", + "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yangon", "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", + "Atlantic/Cape_Verde", "Atlantic/Faroe", "Atlantic/Madeira", + "Atlantic/South_Georgia", "Atlantic/Stanley", + "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", + "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", + "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", + "Australia/Perth", "Australia/Sydney", + "CET", "CST6CDT", "EET", "EST", "EST5EDT", + // Note: Etc/GMT and Etc/UTC are NOT canonical - they are valid identifiers + // but canonicalize to UTC for supportedValuesOf purposes + "Etc/GMT+1", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12", + "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", "Etc/GMT+5", "Etc/GMT+6", + "Etc/GMT+7", "Etc/GMT+8", "Etc/GMT+9", "Etc/GMT-1", "Etc/GMT-10", + "Etc/GMT-11", "Etc/GMT-12", "Etc/GMT-13", "Etc/GMT-14", "Etc/GMT-2", + "Etc/GMT-3", "Etc/GMT-4", "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", + "Etc/GMT-8", "Etc/GMT-9", + "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belgrade", + "Europe/Berlin", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", + "Europe/Chisinau", "Europe/Dublin", "Europe/Gibraltar", "Europe/Helsinki", + "Europe/Istanbul", "Europe/Kaliningrad", "Europe/Kirov", "Europe/Kyiv", + "Europe/Lisbon", "Europe/London", "Europe/Madrid", "Europe/Malta", + "Europe/Minsk", "Europe/Moscow", "Europe/Paris", "Europe/Prague", + "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/Saratov", + "Europe/Simferopol", "Europe/Sofia", "Europe/Tallinn", "Europe/Tirane", + "Europe/Ulyanovsk", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", + "Europe/Warsaw", "Europe/Zurich", + "HST", + "Indian/Chagos", "Indian/Maldives", "Indian/Mauritius", + "MET", "MST", "MST7MDT", + "PST8PDT", + "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", + "Pacific/Chatham", "Pacific/Easter", "Pacific/Efate", "Pacific/Fakaofo", + "Pacific/Fiji", "Pacific/Galapagos", "Pacific/Gambier", + "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Kanton", + "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", + "Pacific/Marquesas", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", + "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", + "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Tahiti", + "Pacific/Tarawa", "Pacific/Tongatapu", + "UTC", + "WET" + ]; + + /// + /// All valid IANA timezone identifiers (Zone names AND Link names). + /// This list is used for validation and case-insensitive lookup. + /// Includes Link names that are valid input but may not be returned by supportedValuesOf. + /// + private static readonly string[] AllTimeZones = + [ + // IANA TZDB Zone names (primary identifiers) + "Africa/Abidjan", "Africa/Algiers", "Africa/Bissau", "Africa/Cairo", + "Africa/Casablanca", "Africa/Ceuta", "Africa/El_Aaiun", "Africa/Johannesburg", + "Africa/Juba", "Africa/Khartoum", "Africa/Lagos", "Africa/Maputo", + "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Sao_Tome", + "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", + "America/Adak", "America/Anchorage", "America/Araguaina", + "America/Argentina/Buenos_Aires", "America/Argentina/Catamarca", + "America/Argentina/Cordoba", "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", + "America/Argentina/San_Juan", "America/Argentina/San_Luis", + "America/Argentina/Tucuman", "America/Argentina/Ushuaia", + "America/Asuncion", "America/Bahia", "America/Bahia_Banderas", + "America/Barbados", "America/Belem", "America/Belize", "America/Boa_Vista", + "America/Bogota", "America/Boise", "America/Cambridge_Bay", + "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Cayenne", + "America/Chicago", "America/Chihuahua", "America/Ciudad_Juarez", + "America/Costa_Rica", "America/Cuiaba", "America/Danmarkshavn", + "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", + "America/Edmonton", "America/Eirunepe", "America/El_Salvador", + "America/Fort_Nelson", "America/Fortaleza", "America/Glace_Bay", + "America/Goose_Bay", "America/Grand_Turk", "America/Guatemala", + "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", + "America/Hermosillo", "America/Indiana/Indianapolis", "America/Indiana/Knox", + "America/Indiana/Marengo", "America/Indiana/Petersburg", + "America/Indiana/Tell_City", "America/Indiana/Vevay", + "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Inuvik", + "America/Iqaluit", "America/Jamaica", "America/Juneau", + "America/Kentucky/Louisville", "America/Kentucky/Monticello", + "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Maceio", + "America/Managua", "America/Manaus", "America/Martinique", "America/Matamoros", + "America/Mazatlan", "America/Menominee", "America/Merida", "America/Metlakatla", + "America/Mexico_City", "America/Miquelon", "America/Moncton", + "America/Monterrey", "America/Montevideo", "America/New_York", "America/Nome", + "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", "America/Nuuk", "America/Ojinaga", + "America/Panama", "America/Paramaribo", "America/Phoenix", + "America/Port-au-Prince", "America/Porto_Velho", "America/Puerto_Rico", + "America/Punta_Arenas", "America/Rankin_Inlet", "America/Recife", + "America/Regina", "America/Resolute", "America/Rio_Branco", + "America/Santarem", "America/Santiago", "America/Santo_Domingo", + "America/Sao_Paulo", "America/Scoresbysund", "America/Sitka", + "America/St_Johns", "America/Swift_Current", "America/Tegucigalpa", + "America/Thule", "America/Tijuana", "America/Toronto", "America/Vancouver", + "America/Whitehorse", "America/Winnipeg", "America/Yakutat", + "America/Yellowknife", + "Antarctica/Casey", "Antarctica/Davis", "Antarctica/Macquarie", + "Antarctica/Mawson", "Antarctica/Palmer", "Antarctica/Rothera", + "Antarctica/Troll", + "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", + "Asia/Ashgabat", "Asia/Atyrau", "Asia/Baghdad", "Asia/Baku", "Asia/Bangkok", + "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Chita", "Asia/Choibalsan", + "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", + "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Hebron", + "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", + "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", + "Asia/Kamchatka", "Asia/Karachi", "Asia/Kathmandu", "Asia/Khandyga", + "Asia/Kolkata", "Asia/Krasnoyarsk", "Asia/Kuching", "Asia/Macau", + "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Nicosia", + "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", + "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qostanay", + "Asia/Qyzylorda", "Asia/Riyadh", "Asia/Sakhalin", "Asia/Samarkand", + "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", + "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Thimphu", + "Asia/Tokyo", "Asia/Tomsk", "Asia/Ulaanbaatar", "Asia/Urumqi", "Asia/Ust-Nera", + "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yangon", "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", + "Atlantic/Cape_Verde", "Atlantic/Faroe", "Atlantic/Madeira", + "Atlantic/South_Georgia", "Atlantic/Stanley", + "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", + "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", + "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", + "Australia/Perth", "Australia/Sydney", + "CET", "CST6CDT", "EET", "EST", "EST5EDT", + // Per ECMA-402 2024 spec, Etc/GMT and Etc/UTC should be preserved (not canonicalized to UTC) + // when returned in resolvedOptions().timeZone + "Etc/GMT", "Etc/UTC", + "Etc/GMT+1", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12", + "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", "Etc/GMT+5", "Etc/GMT+6", + "Etc/GMT+7", "Etc/GMT+8", "Etc/GMT+9", "Etc/GMT-1", "Etc/GMT-10", + "Etc/GMT-11", "Etc/GMT-12", "Etc/GMT-13", "Etc/GMT-14", "Etc/GMT-2", + "Etc/GMT-3", "Etc/GMT-4", "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", + "Etc/GMT-8", "Etc/GMT-9", + "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belgrade", + "Europe/Berlin", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", + "Europe/Chisinau", "Europe/Dublin", "Europe/Gibraltar", "Europe/Helsinki", + "Europe/Istanbul", "Europe/Kaliningrad", "Europe/Kirov", "Europe/Kyiv", + "Europe/Lisbon", "Europe/London", "Europe/Madrid", "Europe/Malta", + "Europe/Minsk", "Europe/Moscow", "Europe/Paris", "Europe/Prague", + "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/Saratov", + "Europe/Simferopol", "Europe/Sofia", "Europe/Tallinn", "Europe/Tirane", + "Europe/Ulyanovsk", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", + "Europe/Warsaw", "Europe/Zurich", + "HST", + "Indian/Chagos", "Indian/Maldives", "Indian/Mauritius", + "MET", "MST", "MST7MDT", + "PST8PDT", + "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", + "Pacific/Chatham", "Pacific/Easter", "Pacific/Efate", "Pacific/Fakaofo", + "Pacific/Fiji", "Pacific/Galapagos", "Pacific/Gambier", + "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Kanton", + "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", + "Pacific/Marquesas", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", + "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", + "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Tahiti", + "Pacific/Tarawa", "Pacific/Tongatapu", + "UTC", + "WET", + + // IANA TZDB Link names (aliases - must also be supported) + "Africa/Accra", "Africa/Addis_Ababa", "Africa/Asmara", "Africa/Asmera", + "Africa/Bamako", "Africa/Bangui", "Africa/Banjul", "Africa/Blantyre", + "Africa/Brazzaville", "Africa/Bujumbura", "Africa/Conakry", "Africa/Dakar", + "Africa/Dar_es_Salaam", "Africa/Djibouti", "Africa/Douala", "Africa/Freetown", + "Africa/Gaborone", "Africa/Harare", "Africa/Kampala", "Africa/Kigali", + "Africa/Kinshasa", "Africa/Libreville", "Africa/Lome", "Africa/Luanda", + "Africa/Lubumbashi", "Africa/Lusaka", "Africa/Malabo", "Africa/Maseru", + "Africa/Mbabane", "Africa/Mogadishu", "Africa/Niamey", "Africa/Nouakchott", + "Africa/Ouagadougou", "Africa/Porto-Novo", "Africa/Timbuktu", + "America/Anguilla", "America/Antigua", "America/Argentina/ComodRivadavia", + "America/Aruba", "America/Atikokan", "America/Atka", "America/Blanc-Sablon", + "America/Buenos_Aires", "America/Catamarca", "America/Cayman", + "America/Coral_Harbour", "America/Cordoba", "America/Creston", + "America/Curacao", "America/Dominica", "America/Ensenada", + "America/Fort_Wayne", "America/Godthab", "America/Grenada", + "America/Guadeloupe", "America/Indianapolis", "America/Jujuy", + "America/Knox_IN", "America/Kralendijk", "America/Louisville", + "America/Lower_Princes", "America/Marigot", "America/Mendoza", + "America/Montreal", "America/Montserrat", "America/Nassau", + "America/Nipigon", "America/Pangnirtung", "America/Port_of_Spain", + "America/Porto_Acre", "America/Rainy_River", "America/Rosario", + "America/Santa_Isabel", "America/Shiprock", "America/St_Barthelemy", + "America/St_Kitts", "America/St_Lucia", "America/St_Thomas", + "America/St_Vincent", "America/Thunder_Bay", "America/Tortola", + "America/Virgin", + "Antarctica/DumontDUrville", "Antarctica/McMurdo", "Antarctica/South_Pole", + "Antarctica/Syowa", "Antarctica/Vostok", + "Arctic/Longyearbyen", + "Asia/Aden", "Asia/Ashkhabad", "Asia/Bahrain", "Asia/Brunei", + "Asia/Calcutta", "Asia/Chongqing", "Asia/Chungking", "Asia/Dacca", + "Asia/Harbin", "Asia/Istanbul", "Asia/Kashgar", "Asia/Katmandu", + "Asia/Kuala_Lumpur", "Asia/Kuwait", "Asia/Macao", "Asia/Muscat", + "Asia/Phnom_Penh", "Asia/Rangoon", "Asia/Saigon", "Asia/Tel_Aviv", + "Asia/Thimbu", "Asia/Ujung_Pandang", "Asia/Ulan_Bator", "Asia/Vientiane", + "Atlantic/Faeroe", "Atlantic/Jan_Mayen", "Atlantic/Reykjavik", + "Atlantic/St_Helena", + "Australia/ACT", "Australia/Canberra", "Australia/Currie", "Australia/LHI", + "Australia/NSW", "Australia/North", "Australia/Queensland", + "Australia/South", "Australia/Tasmania", "Australia/Victoria", + "Australia/West", "Australia/Yancowinna", + "Brazil/Acre", "Brazil/DeNoronha", "Brazil/East", "Brazil/West", + "Canada/Atlantic", "Canada/Central", "Canada/Eastern", "Canada/Mountain", + "Canada/Newfoundland", "Canada/Pacific", "Canada/Saskatchewan", "Canada/Yukon", + "Chile/Continental", "Chile/EasterIsland", + "Cuba", + "Egypt", + "Eire", + // Etc/* Link names that are valid IANA identifiers + "Etc/GMT+0", "Etc/GMT-0", "Etc/GMT0", "Etc/Greenwich", "Etc/UCT", "Etc/Universal", "Etc/Zulu", + "Europe/Amsterdam", "Europe/Belfast", "Europe/Bratislava", "Europe/Busingen", + "Europe/Copenhagen", "Europe/Guernsey", "Europe/Isle_of_Man", "Europe/Jersey", + "Europe/Kiev", "Europe/Ljubljana", "Europe/Luxembourg", "Europe/Mariehamn", + "Europe/Monaco", "Europe/Nicosia", "Europe/Oslo", "Europe/Podgorica", + "Europe/San_Marino", "Europe/Sarajevo", "Europe/Skopje", "Europe/Stockholm", + "Europe/Tiraspol", "Europe/Uzhgorod", "Europe/Vaduz", "Europe/Vatican", + "Europe/Zagreb", "Europe/Zaporozhye", + "GB", "GB-Eire", + // Per ECMA-402 2024 spec, GMT should be preserved (not canonicalized to UTC) + "GMT", + // GMT aliases that resolve to UTC (but are still valid identifiers) + "GMT+0", "GMT-0", "GMT0", "Greenwich", + "Hongkong", + "Iceland", + "Indian/Antananarivo", "Indian/Christmas", "Indian/Cocos", "Indian/Comoro", + "Indian/Kerguelen", "Indian/Mahe", "Indian/Mayotte", "Indian/Reunion", + "Iran", "Israel", + "Jamaica", "Japan", + "Kwajalein", + "Libya", + "Mexico/BajaNorte", "Mexico/BajaSur", "Mexico/General", + "NZ", "NZ-CHAT", "Navajo", + "PRC", + "Pacific/Chuuk", "Pacific/Enderbury", "Pacific/Funafuti", "Pacific/Johnston", + "Pacific/Majuro", "Pacific/Midway", "Pacific/Pohnpei", "Pacific/Ponape", + "Pacific/Saipan", "Pacific/Samoa", "Pacific/Truk", "Pacific/Wake", + "Pacific/Wallis", "Pacific/Yap", + "Poland", "Portugal", + "ROC", "ROK", + "Singapore", + "Turkey", + // UCT is a valid IANA Link name + "UCT", + "US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", + "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", + "US/Pacific", "US/Samoa", + // Universal and Zulu are valid IANA Link names + "Universal", + "W-SU", + "Zulu" + ]; + + /// + /// Gets all supported IANA timezone identifiers (Zone names and Link names). + /// Used for validation and case-insensitive lookup. + /// + public static IReadOnlyList GetAllTimeZones() => AllTimeZones; + + /// + /// Gets only canonical (primary) timezone identifiers. + /// Used by Intl.supportedValuesOf("timeZone"). + /// Does not include Link names or UTC aliases (Etc/GMT, Etc/UTC, GMT). + /// + public static IReadOnlyList GetCanonicalTimeZones() => CanonicalZones; + + /// + /// Performs a case-insensitive lookup of a timezone identifier. + /// Returns the canonical (properly-cased) form if found, null otherwise. + /// + public static string? FindCanonical(string timeZone) + { + EnsureLookupInitialized(); + return _caseInsensitiveLookup!.TryGetValue(timeZone.ToLowerInvariant(), out var canonical) + ? canonical + : null; + } + + /// + /// Checks if a timezone identifier is supported (case-insensitive). + /// + public static bool IsSupported(string timeZone) + { + EnsureLookupInitialized(); + return _caseInsensitiveLookup!.ContainsKey(timeZone.ToLowerInvariant()); + } + + private static void EnsureLookupInitialized() + { + if (_caseInsensitiveLookup != null) return; + + lock (_lock) + { + if (_caseInsensitiveLookup != null) return; + + var lookup = new Dictionary(AllTimeZones.Length, StringComparer.Ordinal); + foreach (var tz in AllTimeZones) + { + lookup[tz.ToLowerInvariant()] = tz; + } + _caseInsensitiveLookup = lookup; + } + } +} diff --git a/Jint/Native/Intl/Data/UnitPatternsData.cs b/Jint/Native/Intl/Data/UnitPatternsData.cs new file mode 100644 index 0000000000..077d1fd6c7 --- /dev/null +++ b/Jint/Native/Intl/Data/UnitPatternsData.cs @@ -0,0 +1,142 @@ +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR unit formatting patterns for locale-aware unit formatting. +/// Data is loaded from embedded UnitPatternsData.txt resource. +/// +internal static class UnitPatternsData +{ + private static readonly object _lock = new(); + private static Dictionary>? _patterns; + private static volatile bool _loaded; + + /// + /// Gets unit patterns for a locale. + /// Returns patterns grouped by unit_displayStyle (e.g., "kilometer-per-hour_short"). + /// Falls back to English if locale not found. + /// + public static Dictionary? GetPatternsForLocale(string locale) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(locale)) + { + // Get language code from locale (e.g., "zh" from "zh-TW") + var language = GetLanguageCode(locale); + + // Try to find patterns for this language + if (_patterns!.TryGetValue(language, out var data)) + { + return data; + } + } + + // Fall back to English if not found and not already English + if (!IsEnglish(locale)) + { + if (_patterns!.TryGetValue("en", out var enData)) + { + return enData; + } + } + + return null; + } + + private static string GetLanguageCode(string locale) + { + if (string.IsNullOrEmpty(locale)) + { + return "en"; + } + + // Extract language code (e.g., "zh" from "zh-TW") + var dashIndex = locale.IndexOf('-'); + return dashIndex > 0 ? locale.Substring(0, dashIndex) : locale; + } + + private static bool IsEnglish(string? locale) + { + if (string.IsNullOrEmpty(locale)) + { + return false; + } + + return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase); + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _patterns = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(UnitPatternsData).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.UnitPatternsData.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentLocale = null; + Dictionary? currentPatterns = null; + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + // Save previous locale data + if (currentLocale != null && currentPatterns != null) + { + _patterns[currentLocale] = currentPatterns; + } + + currentLocale = line.Substring(1, line.Length - 2); + currentPatterns = new Dictionary(StringComparer.Ordinal); + continue; + } + + if (currentLocale == null || currentPatterns == null) + { + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + currentPatterns[key] = value; + } + + // Save last locale data + if (currentLocale != null && currentPatterns != null) + { + _patterns[currentLocale] = currentPatterns; + } + + _loaded = true; + } + } +} diff --git a/Jint/Native/Intl/Data/UnitPatternsData.txt b/Jint/Native/Intl/Data/UnitPatternsData.txt new file mode 100644 index 0000000000..97ecd8a826 --- /dev/null +++ b/Jint/Native/Intl/Data/UnitPatternsData.txt @@ -0,0 +1,24 @@ +[en] +kilometer-per-hour_short={0} km/h +kilometer-per-hour_narrow={0}km/h +kilometer-per-hour_long={0} kilometers per hour + +[de] +kilometer-per-hour_short={0} km/h +kilometer-per-hour_narrow={0} km/h +kilometer-per-hour_long={0} Kilometer pro Stunde + +[ja] +kilometer-per-hour_short={0} km/h +kilometer-per-hour_narrow={0}km/h +kilometer-per-hour_long=時速 {0} キロメートル + +[ko] +kilometer-per-hour_short={0}km/h +kilometer-per-hour_narrow={0}km/h +kilometer-per-hour_long=시속 {0}킬로미터 + +[zh] +kilometer-per-hour_short={0} 公里/小時 +kilometer-per-hour_narrow={0}公里/小時 +kilometer-per-hour_long=每小時 {0} 公里 diff --git a/Jint/Native/Intl/Data/WeekData.cs b/Jint/Native/Intl/Data/WeekData.cs new file mode 100644 index 0000000000..9baf332ace --- /dev/null +++ b/Jint/Native/Intl/Data/WeekData.cs @@ -0,0 +1,254 @@ +using System.Reflection; + +namespace Jint.Native.Intl.Data; + +/// +/// Provides CLDR week data for locale-aware week information. +/// Data is loaded from embedded WeekData.txt resource. +/// +internal static class WeekData +{ + private static readonly object _lock = new object(); + private static Dictionary? _firstDay; + private static Dictionary? _minDays; + private static Dictionary? _weekendStart; + private static Dictionary? _weekendEnd; + private static volatile bool _loaded; + + /// + /// First day of week per region (mon, tue, wed, thu, fri, sat, sun). + /// Key "001" is the default/world value. + /// + public static Dictionary FirstDay + { + get + { + EnsureLoaded(); + return _firstDay!; + } + } + + /// + /// Minimum days in first week per region (typically 1 or 4). + /// Key "001" is the default/world value. + /// + public static Dictionary MinDays + { + get + { + EnsureLoaded(); + return _minDays!; + } + } + + /// + /// Weekend start day per region. + /// Key "001" is the default/world value (typically "sat"). + /// + public static Dictionary WeekendStart + { + get + { + EnsureLoaded(); + return _weekendStart!; + } + } + + /// + /// Weekend end day per region. + /// Key "001" is the default/world value (typically "sun"). + /// + public static Dictionary WeekendEnd + { + get + { + EnsureLoaded(); + return _weekendEnd!; + } + } + + /// + /// Gets the first day of week for a region (1=Monday, 7=Sunday). + /// + public static int GetFirstDayOfWeek(string? region) + { + var dayName = GetFirstDayName(region); + return DayNameToNumber(dayName); + } + + /// + /// Gets the first day of week name for a region. + /// + public static string GetFirstDayName(string? region) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(region) && _firstDay!.TryGetValue(region!, out var day)) + { + return day; + } + + // Default to world value + return _firstDay!.TryGetValue("001", out var defaultDay) ? defaultDay : "mon"; + } + + /// + /// Gets the minimum days in first week for a region. + /// + public static int GetMinDays(string? region) + { + EnsureLoaded(); + + if (!string.IsNullOrEmpty(region) && _minDays!.TryGetValue(region!, out var days)) + { + return days; + } + + // Default to world value + return _minDays!.TryGetValue("001", out var defaultDays) ? defaultDays : 1; + } + + /// + /// Gets the weekend days for a region as an array of day numbers (1=Monday, 7=Sunday). + /// + public static int[] GetWeekend(string? region) + { + EnsureLoaded(); + + string startDay, endDay; + + if (!string.IsNullOrEmpty(region) && _weekendStart!.TryGetValue(region!, out var start)) + { + startDay = start; + } + else + { + startDay = _weekendStart!.TryGetValue("001", out var defaultStart) ? defaultStart : "sat"; + } + + if (!string.IsNullOrEmpty(region) && _weekendEnd!.TryGetValue(region!, out var end)) + { + endDay = end; + } + else + { + endDay = _weekendEnd!.TryGetValue("001", out var defaultEnd) ? defaultEnd : "sun"; + } + + var startNum = DayNameToNumber(startDay); + var endNum = DayNameToNumber(endDay); + + // Build weekend array + var weekend = new List(); + var current = startNum; + while (true) + { + weekend.Add(current); + if (current == endNum) + { + break; + } + current = current == 7 ? 1 : current + 1; + if (weekend.Count > 7) // Safety check + { + break; + } + } + + return weekend.ToArray(); + } + + private static int DayNameToNumber(string dayName) + { + return dayName.ToLowerInvariant() switch + { + "mon" => 1, + "tue" => 2, + "wed" => 3, + "thu" => 4, + "fri" => 5, + "sat" => 6, + "sun" => 7, + _ => 1 // Default to Monday + }; + } + + private static void EnsureLoaded() + { + if (_loaded) + { + return; + } + + lock (_lock) + { + if (_loaded) + { + return; + } + + _firstDay = new Dictionary(StringComparer.OrdinalIgnoreCase); + _minDays = new Dictionary(StringComparer.OrdinalIgnoreCase); + _weekendStart = new Dictionary(StringComparer.OrdinalIgnoreCase); + _weekendEnd = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var assembly = typeof(WeekData).Assembly; + using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.WeekData.txt"); + if (stream is null) + { + _loaded = true; + return; + } + + using var reader = new StreamReader(stream); + string? currentSection = null; + + while (reader.ReadLine() is { } line) + { + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']') + { + currentSection = line.Substring(1, line.Length - 2); + continue; + } + + var eqIndex = line.IndexOf('='); + if (eqIndex < 0) + { + continue; + } + + var key = line.Substring(0, eqIndex); + var value = line.Substring(eqIndex + 1); + + switch (currentSection) + { + case "FIRST_DAY": + _firstDay[key] = value; + break; + + case "MIN_DAYS": + if (int.TryParse(value, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out var minDays)) + { + _minDays[key] = minDays; + } + break; + + case "WEEKEND_START": + _weekendStart[key] = value; + break; + + case "WEEKEND_END": + _weekendEnd[key] = value; + break; + } + } + + _loaded = true; + } + } +} diff --git a/Jint/Native/Intl/Data/WeekData.txt b/Jint/Native/Intl/Data/WeekData.txt new file mode 100644 index 0000000000..55bfff3dc7 --- /dev/null +++ b/Jint/Native/Intl/Data/WeekData.txt @@ -0,0 +1,243 @@ +[FIRST_DAY] +001=mon +AD=mon +AE=mon +AF=sat +AG=sun +AI=mon +AL=mon +AM=mon +AN=mon +AR=mon +AS=sun +AT=mon +AU=mon +AX=mon +AZ=mon +BA=mon +BD=sun +BE=mon +BG=mon +BH=sat +BM=mon +BN=mon +BR=sun +BS=sun +BT=sun +BW=sun +BY=mon +BZ=sun +CA=sun +CH=mon +CL=mon +CM=mon +CN=mon +CO=sun +CR=mon +CY=mon +CZ=mon +DE=mon +DJ=sat +DK=mon +DM=sun +DO=sun +DZ=sat +EC=mon +EE=mon +EG=sat +ES=mon +ET=sun +FI=mon +FJ=mon +FO=mon +FR=mon +GB=mon +GB-alt-variant=sun +GE=mon +GF=mon +GP=mon +GR=mon +GT=sun +GU=sun +HK=sun +HN=sun +HR=mon +HU=mon +ID=sun +IE=mon +IL=sun +IN=sun +IQ=sat +IR=sat +IS=mon +IT=mon +JM=sun +JO=sat +JP=sun +KE=sun +KG=mon +KH=sun +KR=sun +KW=sat +KZ=mon +LA=sun +LB=mon +LI=mon +LK=mon +LT=mon +LU=mon +LV=mon +LY=sat +MC=mon +MD=mon +ME=mon +MH=sun +MK=mon +MM=sun +MN=mon +MO=sun +MQ=mon +MT=sun +MV=fri +MX=sun +MY=mon +MZ=sun +NI=sun +NL=mon +NO=mon +NP=sun +NZ=mon +OM=sat +PA=sun +PE=sun +PH=sun +PK=sun +PL=mon +PR=sun +PT=sun +PY=sun +QA=sat +RE=mon +RO=mon +RS=mon +RU=mon +SA=sun +SD=sat +SE=mon +SG=sun +SI=mon +SK=mon +SM=mon +SV=sun +SY=sat +TH=sun +TJ=mon +TM=mon +TR=mon +TT=sun +TW=sun +UA=mon +UM=sun +US=sun +UY=mon +UZ=mon +VA=mon +VE=sun +VI=sun +VN=mon +WS=sun +XK=mon +YE=sun +ZA=sun +ZW=sun + +[MIN_DAYS] +001=1 +AD=4 +AN=4 +AT=4 +AX=4 +BE=4 +BG=4 +CH=4 +CZ=4 +DE=4 +DK=4 +EE=4 +ES=4 +FI=4 +FJ=4 +FO=4 +FR=4 +GB=4 +GF=4 +GG=4 +GI=4 +GP=4 +GR=4 +GU=1 +HU=4 +IE=4 +IM=4 +IS=4 +IT=4 +JE=4 +LI=4 +LT=4 +LU=4 +MC=4 +MQ=4 +NL=4 +NO=4 +PL=4 +PT=4 +RE=4 +RU=4 +SE=4 +SJ=4 +SK=4 +SM=4 +UM=1 +US=1 +VA=4 +VI=1 + +[WEEKEND_START] +001=sat +AF=thu +BH=fri +DZ=fri +EG=fri +IL=fri +IN=sun +IQ=fri +IR=fri +JO=fri +KW=fri +LY=fri +OM=fri +QA=fri +SA=fri +SD=fri +SY=fri +UG=sun +YE=fri + +[WEEKEND_END] +001=sun +AF=fri +BH=sat +DZ=sat +EG=sat +IL=sat +IQ=sat +IR=fri +JO=sat +KW=sat +LY=sat +OM=sat +QA=sat +SA=sat +SD=sat +SY=sat +YE=sat \ No newline at end of file diff --git a/Jint/Native/Intl/DefaultCldrProvider.cs b/Jint/Native/Intl/DefaultCldrProvider.cs new file mode 100644 index 0000000000..fd135ced8e --- /dev/null +++ b/Jint/Native/Intl/DefaultCldrProvider.cs @@ -0,0 +1,838 @@ +using System.Globalization; +using System.Linq; +using Jint.Native.Intl.Data; + +namespace Jint.Native.Intl; + +/// +/// Default CLDR provider that uses embedded data files and hardcoded patterns. +/// Supports basic en-US/en-GB with English fallback for other locales. +/// +public sealed class DefaultCldrProvider : ICldrProvider +{ + /// + /// Singleton instance of the default provider. + /// + public static readonly DefaultCldrProvider Instance = new(); + + private DefaultCldrProvider() + { + } + + // === List Patterns === + + public ListPatterns? GetListPatterns(string locale, string type, string style) + { + // Try embedded CLDR data first + var localePatterns = ListPatternsData.GetPatternsForLocale(locale); + if (localePatterns != null) + { + var key = $"{type}_{style}"; + if (localePatterns.TryGetValue(key, out var patterns)) + { + return patterns; + } + } + + // Fallback to English if not already English + if (!IsEnglish(locale)) + { + var enPatterns = ListPatternsData.GetPatternsForLocale("en"); + if (enPatterns != null) + { + var key = $"{type}_{style}"; + if (enPatterns.TryGetValue(key, out var patterns)) + { + return patterns; + } + } + } + + return null; + } + + // === Relative Time Patterns === + + public RelativeTimePatterns? GetRelativeTimePatterns(string locale, string unit, string style) + { + // Try embedded CLDR data first + var localeData = RelativeTimePatternsData.GetDataForLocale(locale); + + // Fallback to English if not found + if (localeData == null && !IsEnglish(locale)) + { + localeData = RelativeTimePatternsData.GetDataForLocale("en"); + } + + if (localeData == null) + { + return null; + } + + var key = $"{unit}_{style}"; + if (!localeData.Patterns.TryGetValue(key, out var unitPatterns)) + { + return null; + } + + // Build RelativeTimePatterns with plural form support + var futurePatterns = new Dictionary(StringComparer.Ordinal); + var pastPatterns = new Dictionary(StringComparer.Ordinal); + + foreach (var kvp in unitPatterns.Patterns) + { + var patternKey = kvp.Key; + var pattern = kvp.Value; + + if (patternKey.StartsWith("future_", StringComparison.Ordinal)) + { + futurePatterns[patternKey.Substring(7)] = pattern; // "future_one" → "one" + } + else if (patternKey.StartsWith("past_", StringComparison.Ordinal)) + { + pastPatterns[patternKey.Substring(5)] = pattern; // "past_one" → "one" + } + } + + // Legacy properties for backwards compatibility + var futureOne = futurePatterns.TryGetValue("one", out var f1) ? f1 : ""; + var futureOther = futurePatterns.TryGetValue("other", out var f2) ? f2 : ""; + var pastOne = pastPatterns.TryGetValue("one", out var p1) ? p1 : ""; + var pastOther = pastPatterns.TryGetValue("other", out var p2) ? p2 : ""; + + return new RelativeTimePatterns + { + Future = futureOne, + FuturePlural = futureOther, + Past = pastOne, + PastPlural = pastOther, + FuturePatterns = futurePatterns.Count > 0 ? futurePatterns : null, + PastPatterns = pastPatterns.Count > 0 ? pastPatterns : null + }; + } + + public string? GetRelativeTimeSpecialPhrase(string locale, string unit, int value, bool past, string style) + { + // Only provide English phrases + if (!IsEnglish(locale)) + { + return null; + } + + if (value == 0) + { + return unit switch + { + "second" => "now", + "minute" => "this minute", + "hour" => "this hour", + "day" => "today", + "week" => "this week", + "month" => "this month", + "quarter" => "this quarter", + "year" => "this year", + _ => null + }; + } + + if (value == 1) + { + if (past) + { + return unit switch + { + "day" => "yesterday", + "week" => "last week", + "month" => "last month", + "quarter" => "last quarter", + "year" => "last year", + _ => null + }; + } + return unit switch + { + "day" => "tomorrow", + "week" => "next week", + "month" => "next month", + "quarter" => "next quarter", + "year" => "next year", + _ => null + }; + } + + return null; + } + + // === Number Formatting === + + public string? GetNumberingSystemDigits(string numberingSystem) + { + return NumberingSystemData.Digits.TryGetValue(numberingSystem, out var digits) ? digits : null; + } + + public CompactPatterns? GetCompactPatterns(string locale, string style) + { + // Use existing CompactPatterns data + // The default provider returns English patterns only + if (!IsEnglish(locale)) + { + return null; + } + + if (string.Equals(style, "short", StringComparison.Ordinal)) + { + return new CompactPatterns + { + Patterns = new Dictionary + { + [3] = "{0}K", + [6] = "{0}M", + [9] = "{0}B", + [12] = "{0}T" + } + }; + } + + if (string.Equals(style, "long", StringComparison.Ordinal)) + { + return new CompactPatterns + { + Patterns = new Dictionary + { + [3] = "{0} thousand", + [6] = "{0} million", + [9] = "{0} billion", + [12] = "{0} trillion" + } + }; + } + + return null; + } + + public CurrencyData? GetCurrencyData(string locale, string currencyCode) + { + // Default provider returns basic currency data from .NET + try + { + var culture = new CultureInfo(RemoveExtensions(locale)); + var region = new RegionInfo(culture.Name); + + // Common currency symbols + var symbol = currencyCode switch + { + "USD" => "$", + "EUR" => "\u20AC", + "GBP" => "\u00A3", + "JPY" => "\u00A5", + "CNY" => "\u00A5", + _ => currencyCode + }; + + return new CurrencyData + { + Symbol = symbol, + NarrowSymbol = symbol, + DisplayName = currencyCode + }; + } + catch + { + return null; + } + } + + public UnitPatterns? GetUnitPatterns(string locale, string unit, string style) + { + // Try embedded CLDR data first + var localePatterns = UnitPatternsData.GetPatternsForLocale(locale); + if (localePatterns != null) + { + var key = $"{unit}_{style}"; + if (localePatterns.TryGetValue(key, out var pattern)) + { + // For now, use the same pattern for both singular and plural + // (CLDR unit patterns like "km/h" don't change based on plurality) + return new UnitPatterns + { + DisplayName = unit, + One = pattern, + Other = pattern + }; + } + } + + // Fallback to English if not already English + if (!IsEnglish(locale)) + { + var enPatterns = UnitPatternsData.GetPatternsForLocale("en"); + if (enPatterns != null) + { + var key = $"{unit}_{style}"; + if (enPatterns.TryGetValue(key, out var pattern)) + { + return new UnitPatterns + { + DisplayName = unit, + One = pattern, + Other = pattern + }; + } + } + } + + // Legacy fallback for units not in embedded data (English only) + if (!IsEnglish(locale)) + { + return null; + } + + var displayName = GetUnitDisplayName(unit, style); + var unitSingular = GetUnitSingular(unit, style); + var unitPlural = GetUnitPlural(unit, style); + + // Special units like percent, celsius, fahrenheit don't have space before unit + // Narrow style also doesn't have space between number and unit + var needsSpace = !string.Equals(style, "narrow", StringComparison.Ordinal) && + !string.Equals(unit, "percent", StringComparison.Ordinal) && + !string.Equals(unit, "celsius", StringComparison.Ordinal) && + !string.Equals(unit, "fahrenheit", StringComparison.Ordinal); + + var one = needsSpace ? $"{{0}} {unitSingular}" : $"{{0}}{unitSingular}"; + var other = needsSpace ? $"{{0}} {unitPlural}" : $"{{0}}{unitPlural}"; + + return new UnitPatterns + { + DisplayName = displayName, + One = one, + Other = other + }; + } + + // === Date/Time Formatting === + + public DateTimePatterns? GetDateTimePatterns(string locale, string? dateStyle, string? timeStyle) + { + // Default provider delegates to .NET's DateTimeFormatInfo + return null; + } + + public string[]? GetMonthNames(string locale, string style) + { + try + { + var culture = new CultureInfo(RemoveExtensions(locale)); + return style switch + { + "long" => culture.DateTimeFormat.MonthNames.Take(12).ToArray(), + "short" => culture.DateTimeFormat.AbbreviatedMonthNames.Take(12).ToArray(), + "narrow" => culture.DateTimeFormat.AbbreviatedMonthNames.Take(12).Select(m => m.Length > 0 ? m[0].ToString() : m).ToArray(), + _ => null + }; + } + catch + { + return null; + } + } + + public string[]? GetWeekdayNames(string locale, string style) + { + try + { + var culture = new CultureInfo(RemoveExtensions(locale)); + return style switch + { + "long" => culture.DateTimeFormat.DayNames, + "short" => culture.DateTimeFormat.AbbreviatedDayNames, + "narrow" => culture.DateTimeFormat.ShortestDayNames, + _ => null + }; + } + catch + { + return null; + } + } + + public string[]? GetDayPeriods(string locale, string style) + { + try + { + var culture = new CultureInfo(RemoveExtensions(locale)); + return [culture.DateTimeFormat.AMDesignator, culture.DateTimeFormat.PMDesignator]; + } + catch + { + return null; + } + } + + public string[]? GetEraNames(string locale, string style) + { + if (!IsEnglish(locale)) + { + return null; + } + + return style switch + { + "long" => ["Before Christ", "Anno Domini"], + "short" => ["BC", "AD"], + "narrow" => ["B", "A"], + _ => null + }; + } + + // === Display Names === + + public string? GetLanguageDisplayName(string locale, string code) + { + if (!IsEnglish(locale)) + { + return null; + } + + try + { + var culture = new CultureInfo(code); + return culture.EnglishName; + } + catch + { + return null; + } + } + + public string? GetRegionDisplayName(string locale, string code) + { + if (!IsEnglish(locale)) + { + return null; + } + + try + { + var region = new RegionInfo(code); + return region.EnglishName; + } + catch + { + return null; + } + } + + public string? GetScriptDisplayName(string locale, string code) + { + if (!IsEnglish(locale)) + { + return null; + } + + // Common script names + return code.ToUpperInvariant() switch + { + "LATN" => "Latin", + "CYRL" => "Cyrillic", + "ARAB" => "Arabic", + "HANS" => "Simplified Chinese", + "HANT" => "Traditional Chinese", + "DEVA" => "Devanagari", + "GREK" => "Greek", + "HEBR" => "Hebrew", + "JPAN" => "Japanese", + "KORE" => "Korean", + "THAI" => "Thai", + _ => null + }; + } + + public string? GetCurrencyDisplayName(string locale, string code) + { + if (!IsEnglish(locale)) + { + return null; + } + + // Look up currency name from .NET culture data by finding a culture that uses this currency + var upperCode = code.ToUpperInvariant(); + foreach (var culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) + { + try + { + var region = new RegionInfo(culture.Name); + if (string.Equals(region.ISOCurrencySymbol, upperCode, StringComparison.OrdinalIgnoreCase)) + { + return region.CurrencyEnglishName; + } + } + catch + { + // Skip cultures without region info + } + } + + // Don't provide fallback - only return names for currencies we actually know about + return null; + } + + // === Locale Data === + + public string? GetLikelySubtags(string locale) + { + return LikelySubtagsData.TryResolve(locale, out var result) ? result : null; + } + + public WeekInfo? GetWeekInfo(string locale) + { + // Extract region from locale for week data lookup + var region = ExtractRegion(locale); + + var firstDayNum = WeekData.GetFirstDayOfWeek(region); + var minDays = WeekData.GetMinDays(region); + + // Convert CLDR day number (1=Monday, 7=Sunday) to DayOfWeek + var firstDay = firstDayNum switch + { + 1 => DayOfWeek.Monday, + 2 => DayOfWeek.Tuesday, + 3 => DayOfWeek.Wednesday, + 4 => DayOfWeek.Thursday, + 5 => DayOfWeek.Friday, + 6 => DayOfWeek.Saturday, + 7 => DayOfWeek.Sunday, + _ => DayOfWeek.Monday + }; + + return new WeekInfo + { + FirstDay = firstDay, + MinimalDays = minDays, + Weekend = new[] { DayOfWeek.Saturday, DayOfWeek.Sunday } + }; + } + + // === Plural Rules === + + public string SelectPluralCategory(string locale, double value, string type) + { + // Basic English plural rules for cardinal numbers + // English only has "one" and "other" categories + // For ordinal: "one" (1st, 21st), "two" (2nd, 22nd), "few" (3rd, 23rd), "other" (4th, 11th, etc.) + + var absValue = System.Math.Abs(value); + + if (string.Equals(type, "ordinal", StringComparison.Ordinal)) + { + // English ordinal rules + var intValue = (int) absValue; + var mod10 = intValue % 10; + var mod100 = intValue % 100; + + if (mod10 == 1 && mod100 != 11) + { + return "one"; // 1st, 21st, 31st, ... + } + if (mod10 == 2 && mod100 != 12) + { + return "two"; // 2nd, 22nd, 32nd, ... + } + if (mod10 == 3 && mod100 != 13) + { + return "few"; // 3rd, 23rd, 33rd, ... + } + return "other"; // 4th, 5th, 11th, 12th, 13th, ... + } + + // English cardinal rules: "one" for 1, "other" for everything else + // Note: Many languages have more complex rules (zero, two, few, many) + return absValue == 1 ? "one" : "other"; + } + + private static string? ExtractRegion(string locale) + { + // Locale format: language-Script-REGION-... + var parts = locale.Split('-'); + foreach (var part in parts) + { + // Region is typically 2 uppercase letters or 3 digits + if (part.Length == 2 && char.IsUpper(part[0]) && char.IsUpper(part[1])) + { + return part; + } + if (part.Length == 3 && char.IsDigit(part[0]) && char.IsDigit(part[1]) && char.IsDigit(part[2])) + { + return part; + } + } + return null; + } + + // === Supported Values === + + public IReadOnlyCollection GetSupportedCalendars() + { + // Only return calendars that are fully supported per ECMA-402 and Intl.Era-monthcode spec + // Note: "islamic" and "islamic-rgsa" are excluded because they require specific + // DateTimeFormat support that maps them back correctly (not aliased to islamic-civil) + return new[] + { + "buddhist", "chinese", "coptic", "dangi", "ethioaa", "ethiopic", + "gregory", "hebrew", "indian", "islamic-civil", + "islamic-tbla", "islamic-umalqura", "iso8601", + "japanese", "persian", "roc" + }; + } + + public IReadOnlyCollection GetSupportedCollations() + { + return new[] + { + "big5han", "compat", "dict", "direct", "ducet", "emoji", "eor", + "gb2312", "phonebk", "phonetic", "pinyin", "reformed", "searchjl", + "stroke", "trad", "unihan", "zhuyin" + }; + } + + public IReadOnlyCollection GetSupportedCurrencies() + { + var currencies = new HashSet(StringComparer.Ordinal); + foreach (var culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) + { + try + { + var region = new RegionInfo(culture.Name); + var currencyCode = region.ISOCurrencySymbol; + + // Filter out invalid currency codes (must be 3 uppercase ASCII letters) + // Some cultures have placeholder codes like "¤¤" or "XXX" + if (currencyCode.Length == 3 && + IsUpperAsciiLetter(currencyCode[0]) && + IsUpperAsciiLetter(currencyCode[1]) && + IsUpperAsciiLetter(currencyCode[2]) && + !string.Equals(currencyCode, "XXX", StringComparison.Ordinal)) // XXX is "no currency" + { + currencies.Add(currencyCode); + } + } + catch + { + // Skip cultures without region info + } + } + return currencies.ToArray(); + } + + public IReadOnlyCollection GetSupportedNumberingSystems() + { + return NumberingSystemData.Digits.Keys.ToArray(); + } + + public IReadOnlyCollection GetSupportedTimeZones() + { + // Return only canonical (primary) timezone identifiers for supportedValuesOf + return TimeZoneData.GetCanonicalTimeZones(); + } + + public IReadOnlyCollection GetSupportedUnits() + { + return new[] + { + "acre", "bit", "byte", "celsius", "centimeter", "day", "degree", + "fahrenheit", "fluid-ounce", "foot", "gallon", "gigabit", "gigabyte", + "gram", "hectare", "hour", "inch", "kilobit", "kilobyte", "kilogram", + "kilometer", "liter", "megabit", "megabyte", "meter", "microsecond", + "mile", "mile-scandinavian", "milliliter", "millimeter", "millisecond", + "minute", "month", "nanosecond", "ounce", "percent", "petabyte", + "pound", "second", "stone", "terabit", "terabyte", "week", "yard", "year" + }; + } + + // === Helper Methods === + + private static bool IsEnglish(string locale) + { + return locale.StartsWith("en", StringComparison.OrdinalIgnoreCase); + } + + private static bool IsUpperAsciiLetter(char c) + { + return c >= 'A' && c <= 'Z'; + } + + private static string RemoveExtensions(string locale) + { + var uIndex = locale.IndexOf("-u-", StringComparison.OrdinalIgnoreCase); + return uIndex >= 0 ? locale.Substring(0, uIndex) : locale; + } + + private static string GetUnitName(string unit, string style, bool plural) + { + if (string.Equals(style, "narrow", StringComparison.Ordinal)) + { + return unit switch + { + "second" or "seconds" => "s", + "minute" or "minutes" => "m", + "hour" or "hours" => "h", + "day" or "days" => "d", + "week" or "weeks" => "w", + "month" or "months" => "mo", + "quarter" or "quarters" => "q", + "year" or "years" => "y", + "millisecond" or "milliseconds" => "ms", + "microsecond" or "microseconds" => "μs", + "nanosecond" or "nanoseconds" => "ns", + "meter" or "meters" => "m", + "kilometer" or "kilometers" => "km", + "centimeter" or "centimeters" => "cm", + "millimeter" or "millimeters" => "mm", + "mile" or "miles" => "mi", + "foot" or "feet" => "ft", + "inch" or "inches" => "in", + "yard" or "yards" => "yd", + "gram" or "grams" => "g", + "kilogram" or "kilograms" => "kg", + "pound" or "pounds" => "lb", + "ounce" or "ounces" => "oz", + "liter" or "liters" => "l", + "milliliter" or "milliliters" => "mL", + "gallon" or "gallons" => "gal", + "byte" or "bytes" => "B", + "kilobyte" or "kilobytes" => "kB", + "megabyte" or "megabytes" => "MB", + "gigabyte" or "gigabytes" => "GB", + "percent" => "%", + "celsius" => "°C", + "fahrenheit" => "°F", + _ => unit + }; + } + + if (string.Equals(style, "short", StringComparison.Ordinal)) + { + return unit switch + { + "second" or "seconds" => "sec", + "minute" or "minutes" => "min", + "hour" or "hours" => "hr", + // "day" is special in English - short form has pluralization (day/days) + "day" or "days" => plural ? "days" : "day", + "week" or "weeks" => "wk", + "month" or "months" => "mo", + "quarter" or "quarters" => "qtr", + "year" or "years" => "yr", + "millisecond" or "milliseconds" => "ms", + "microsecond" or "microseconds" => "μs", + "nanosecond" or "nanoseconds" => "ns", + "meter" or "meters" => "m", + "kilometer" or "kilometers" => "km", + "centimeter" or "centimeters" => "cm", + "millimeter" or "millimeters" => "mm", + "mile" or "miles" => "mi", + "foot" or "feet" => "ft", + "inch" or "inches" => "in", + "yard" or "yards" => "yd", + "gram" or "grams" => "g", + "kilogram" or "kilograms" => "kg", + "pound" or "pounds" => "lb", + "ounce" or "ounces" => "oz", + "liter" or "liters" => "L", + "milliliter" or "milliliters" => "mL", + "gallon" or "gallons" => "gal", + "byte" or "bytes" => "B", + "kilobyte" or "kilobytes" => "kB", + "megabyte" or "megabytes" => "MB", + "gigabyte" or "gigabytes" => "GB", + "percent" => "%", + "celsius" => "°C", + "fahrenheit" => "°F", + _ => unit + }; + } + + // Long style + return unit switch + { + "second" => plural ? "seconds" : "second", + "seconds" => "seconds", + "minute" => plural ? "minutes" : "minute", + "minutes" => "minutes", + "hour" => plural ? "hours" : "hour", + "hours" => "hours", + "day" => plural ? "days" : "day", + "days" => "days", + "week" => plural ? "weeks" : "week", + "weeks" => "weeks", + "month" => plural ? "months" : "month", + "months" => "months", + "quarter" => plural ? "quarters" : "quarter", + "quarters" => "quarters", + "year" => plural ? "years" : "year", + "years" => "years", + "millisecond" => plural ? "milliseconds" : "millisecond", + "milliseconds" => "milliseconds", + "microsecond" => plural ? "microseconds" : "microsecond", + "microseconds" => "microseconds", + "nanosecond" => plural ? "nanoseconds" : "nanosecond", + "nanoseconds" => "nanoseconds", + "meter" => plural ? "meters" : "meter", + "meters" => "meters", + "kilometer" => plural ? "kilometers" : "kilometer", + "kilometers" => "kilometers", + "centimeter" => plural ? "centimeters" : "centimeter", + "centimeters" => "centimeters", + "millimeter" => plural ? "millimeters" : "millimeter", + "millimeters" => "millimeters", + "mile" => plural ? "miles" : "mile", + "miles" => "miles", + "foot" => plural ? "feet" : "foot", + "feet" => "feet", + "inch" => plural ? "inches" : "inch", + "inches" => "inches", + "yard" => plural ? "yards" : "yard", + "yards" => "yards", + "gram" => plural ? "grams" : "gram", + "grams" => "grams", + "kilogram" => plural ? "kilograms" : "kilogram", + "kilograms" => "kilograms", + "pound" => plural ? "pounds" : "pound", + "pounds" => "pounds", + "ounce" => plural ? "ounces" : "ounce", + "ounces" => "ounces", + "liter" => plural ? "liters" : "liter", + "liters" => "liters", + "milliliter" => plural ? "milliliters" : "milliliter", + "milliliters" => "milliliters", + "gallon" => plural ? "gallons" : "gallon", + "gallons" => "gallons", + "byte" => plural ? "bytes" : "byte", + "bytes" => "bytes", + "kilobyte" => plural ? "kilobytes" : "kilobyte", + "kilobytes" => "kilobytes", + "megabyte" => plural ? "megabytes" : "megabyte", + "megabytes" => "megabytes", + "gigabyte" => plural ? "gigabytes" : "gigabyte", + "gigabytes" => "gigabytes", + "percent" => "percent", + "celsius" => "degrees Celsius", + "fahrenheit" => "degrees Fahrenheit", + _ => unit + }; + } + + private static string GetUnitDisplayName(string unit, string style) + { + return GetUnitName(unit, style, plural: true); + } + + private static string GetUnitSingular(string unit, string style) + { + return GetUnitName(unit, style, plural: false); + } + + private static string GetUnitPlural(string unit, string style) + { + return GetUnitName(unit, style, plural: true); + } +} diff --git a/Jint/Options.cs b/Jint/Options.cs index 623f98be96..5b93ad45dc 100644 --- a/Jint/Options.cs +++ b/Jint/Options.cs @@ -511,14 +511,14 @@ public class JsonOptions public class IntlOptions { /// - /// CLDR provider for locale data. Set this to enable full locale support for the Intl API. - /// Defaults to null. Will be set to DefaultCldrProvider in a future PR. + /// CLDR provider for locale data. Defaults to DefaultCldrProvider + /// which provides basic English (en-US, en-GB) support. /// /// /// Set this to a custom ICldrProvider implementation (e.g., ICU-based provider) /// to enable full locale support for the Intl API. /// - public ICldrProvider? CldrProvider { get; set; } + public ICldrProvider CldrProvider { get; set; } = DefaultCldrProvider.Instance; } }