diff --git a/SabreTools.RedumpLib.Test/RedumpInfo/ExtensionsTests.cs b/SabreTools.RedumpLib.Test/RedumpInfo/ExtensionsTests.cs index 2562974..fbc9509 100644 --- a/SabreTools.RedumpLib.Test/RedumpInfo/ExtensionsTests.cs +++ b/SabreTools.RedumpLib.Test/RedumpInfo/ExtensionsTests.cs @@ -425,6 +425,175 @@ namespace SabreTools.RedumpLib.Test.RedumpInfo #endregion + #region Language + + /// + /// Check that every Language has a long name provided + /// + /// Language value to check + /// True to expect a null value, false otherwise + [Theory] + [MemberData(nameof(GenerateLanguageTestData))] + public void Language_LongName(Language? language, bool expectNull) + { + var actual = language.LongName(); + + if (expectNull) + Assert.Null(actual); + else + Assert.NotNull(actual); + } + + /// + /// Check that every Language has a short name provided + /// + /// Language value to check + /// True to expect a null value, false otherwise + [Theory] + [MemberData(nameof(GenerateLanguageTestData))] + public void Language_ShortName(Language? language, bool expectNull) + { + var actual = language.ShortName(); + + if (expectNull) + Assert.Null(actual); + else + Assert.NotNull(actual); + } + + /// + /// Check that every Language can be mapped from a string + /// + /// Language value to check + /// True to expect a null value, false otherwise + [Theory] + [MemberData(nameof(GenerateLanguageTestData))] + public void Language_ToLanguage(Language? lang, bool expectNull) + { + string? twoLetterCode = lang.TwoLetterCode(); + string? threeLetterCode = lang.ThreeLetterCode(); + string? threeLetterCodeAlt = lang.ThreeLetterCodeAlt(); + + var actualTwoLetterCode = twoLetterCode.ToLanguage(); + var actualThreeLetterCode = threeLetterCode.ToLanguage(); + var actualThreeLetterCodeAlt = threeLetterCodeAlt.ToLanguage(); + + if (expectNull) + { + Assert.Null(actualTwoLetterCode); + Assert.Null(actualThreeLetterCode); + Assert.Null(actualThreeLetterCodeAlt); + } + else + { + Assert.Equal(lang, actualThreeLetterCode); + + // Not guaranteed to exist + if (twoLetterCode is not null) + Assert.Equal(lang, actualTwoLetterCode); + if (threeLetterCodeAlt is not null) + Assert.Equal(lang, actualThreeLetterCodeAlt); + } + } + + /// + /// Ensure that every Language that has a standard/bibliographic ISO 639-2 code is unique + /// + [Fact] + public void Language_ThreeLetterCode_NoDuplicates() + { + var fullLanguages = Enum.GetValues().Cast().ToList(); + var filteredLanguages = new Dictionary(); + + int totalCount = 0; + foreach (Language? language in fullLanguages) + { + var code = language.ThreeLetterCode(); + if (string.IsNullOrEmpty(code)) + continue; + + // Throw if the code already exists + if (filteredLanguages.ContainsKey(code)) + throw new DuplicateNameException($"Code {code} already in dictionary"); + + filteredLanguages[code] = language; + totalCount++; + } + + Assert.Equal(totalCount, filteredLanguages.Count); + } + + /// + /// Ensure that every Language that has a terminology ISO 639-2 code is unique + /// + [Fact] + public void Language_ThreeLetterCodeAlt_NoDuplicates() + { + var fullLanguages = Enum.GetValues().Cast().ToList(); + var filteredLanguages = new Dictionary(); + + int totalCount = 0; + foreach (Language? language in fullLanguages) + { + var code = language.ThreeLetterCodeAlt(); + if (string.IsNullOrEmpty(code)) + continue; + + // Throw if the code already exists + if (filteredLanguages.ContainsKey(code)) + throw new DuplicateNameException($"Code {code} already in dictionary"); + + filteredLanguages[code] = language; + totalCount++; + } + + Assert.Equal(totalCount, filteredLanguages.Count); + } + + /// + /// Ensure that every Language that has an ISO 639-1 code is unique + /// + [Fact] + public void Language_TwoLetterCode_NoDuplicates() + { + var fullLanguages = Enum.GetValues().Cast().ToList(); + var filteredLanguages = new Dictionary(); + + int totalCount = 0; + foreach (Language? language in fullLanguages) + { + var code = language.TwoLetterCode(); + if (string.IsNullOrEmpty(code)) + continue; + + // Throw if the code already exists + if (filteredLanguages.ContainsKey(code)) + throw new DuplicateNameException($"Code {code} already in dictionary"); + + filteredLanguages[code] = language; + totalCount++; + } + + Assert.Equal(totalCount, filteredLanguages.Count); + } + + /// + /// Generate a test set of Language values + /// + /// MemberData-compatible list of Language values + public static TheoryData GenerateLanguageTestData() + { + var testData = new TheoryData() { { null, true } }; + foreach (Language? language in Enum.GetValues().Cast()) + { + testData.Add(language, false); + } + + return testData; + } + + #endregion + #region Media Type /// diff --git a/SabreTools.RedumpLib/RedumpInfo/Converters/LanguageConverter.cs b/SabreTools.RedumpLib/RedumpInfo/Converters/LanguageConverter.cs new file mode 100644 index 0000000..0677692 --- /dev/null +++ b/SabreTools.RedumpLib/RedumpInfo/Converters/LanguageConverter.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SabreTools.RedumpLib.RedumpInfo.Data; + +namespace SabreTools.RedumpLib.RedumpInfo.Converters +{ + /// + /// Serialize Language enum values + /// + public class LanguageConverter : JsonConverter + { + public override bool CanRead { get { return true; } } + + public override Language?[] ReadJson(JsonReader reader, Type objectType, Language?[]? existingValue, bool hasExistingValue, JsonSerializer serializer) + { + // If we have a value already, don't overwrite it + if (hasExistingValue) + return existingValue ?? []; + + // Get the current depth for checking + int currentDepth = reader.Depth; + + // Read the array while it exists + List languages = []; + while (reader.Read() && reader.Depth > currentDepth) + { + if (reader.Value is not string value) + continue; + + Language? lang = value.ToLanguage(); + if (lang is not null) + languages.Add(lang.Value); + } + + return [.. languages]; + } + + public override void WriteJson(JsonWriter writer, Language?[]? value, JsonSerializer serializer) + { + if (value is null) + return; + + JArray array = []; + foreach (var val in value) + { + JToken t = JToken.FromObject(val.ShortName() ?? string.Empty); + array.Add(t); + } + + array.WriteTo(writer); + } + } +} diff --git a/SabreTools.RedumpLib/RedumpInfo/Data/Enumerations.cs b/SabreTools.RedumpLib/RedumpInfo/Data/Enumerations.cs index ab1ffc8..eb3c58d 100644 --- a/SabreTools.RedumpLib/RedumpInfo/Data/Enumerations.cs +++ b/SabreTools.RedumpLib/RedumpInfo/Data/Enumerations.cs @@ -80,6 +80,1635 @@ namespace SabreTools.RedumpLib.RedumpInfo.Data Verified, } + /// + /// List of all disc langauges + /// + /// https://www.loc.gov/standards/iso639-2/php/code_list.php + public enum Language + { + #region A + + [Language(LongName = "Abkhazian", TwoLetterCode = "ab", ThreeLetterCode = "abk")] + Abkhazian, + + [Language(LongName = "Achinese", ThreeLetterCode = "ace")] + Achinese, + + [Language(LongName = "Acoli", ThreeLetterCode = "ach")] + Acoli, + + [Language(LongName = "Adangme", ThreeLetterCode = "ada")] + Adangme, + + // Adyghe; Adygei + [Language(LongName = "Adyghe", ThreeLetterCode = "ady")] + Adyghe, + + [Language(LongName = "Afar", TwoLetterCode = "aa", ThreeLetterCode = "aar")] + Afar, + + [Language(LongName = "Afrihili", ThreeLetterCode = "afh")] + Afrihili, + + [Language(LongName = "Afrikaans", TwoLetterCode = "af", ThreeLetterCode = "afr")] + Afrikaans, + + [Language(LongName = "Ainu", ThreeLetterCode = "ain")] + Ainu, + + [Language(LongName = "Akan", TwoLetterCode = "ak", ThreeLetterCode = "aka")] + Akan, + + [Language(LongName = "Akkadian", ThreeLetterCode = "akk")] + Akkadian, + + [Language(LongName = "Albanian", TwoLetterCode = "sq", ThreeLetterCode = "alb", ThreeLetterCodeAlt = "sqi")] + Albanian, + + [Language(LongName = "Aleut", ThreeLetterCode = "ale")] + Aleut, + + [Language(LongName = "Amharic", TwoLetterCode = "am", ThreeLetterCode = "amh")] + Amharic, + + [Language(LongName = "Angika", ThreeLetterCode = "anp")] + Angika, + + [Language(LongName = "Arabic", TwoLetterCode = "ar", ThreeLetterCode = "ara")] + Arabic, + + [Language(LongName = "Aragonese", TwoLetterCode = "an", ThreeLetterCode = "arg")] + Aragonese, + + // Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE) + [Language(LongName = "Aramaic", ThreeLetterCode = "arc")] + Aramaic, + + [Language(LongName = "Armenian", TwoLetterCode = "hy", ThreeLetterCode = "arm", ThreeLetterCodeAlt = "hye")] + Armenian, + + [Language(LongName = "Arapaho", ThreeLetterCode = "arp")] + Arapaho, + + // Aromanian; Arumanian; Macedo-Romanian + [Language(LongName = "Aromanian", ThreeLetterCode = "rup")] + Aromanian, + + [Language(LongName = "Arawak", ThreeLetterCode = "arw")] + Arawak, + + [Language(LongName = "Assamese", TwoLetterCode = "as", ThreeLetterCode = "asm")] + Assamese, + + // Asturian; Bable; Leonese; Asturleonese + [Language(LongName = "Asturian", ThreeLetterCode = "ast")] + Asturian, + + [Language(LongName = "Athapascan", ThreeLetterCode = "den")] + Athapascan, + + [Language(LongName = "Avaric", TwoLetterCode = "av", ThreeLetterCode = "ava")] + Avaric, + + [Language(LongName = "Avestan", TwoLetterCode = "ae", ThreeLetterCode = "ave")] + Avestan, + + [Language(LongName = "Awadhi", ThreeLetterCode = "awa")] + Awadhi, + + [Language(LongName = "Aymara", TwoLetterCode = "ay", ThreeLetterCode = "aym")] + Aymara, + + [Language(LongName = "Azerbaijani", TwoLetterCode = "az", ThreeLetterCode = "aze")] + Azerbaijani, + + #endregion + + #region B + + [Language(LongName = "Balinese", ThreeLetterCode = "ban")] + Balinese, + + [Language(LongName = "Baluchi", ThreeLetterCode = "bal")] + Baluchi, + + [Language(LongName = "Bambara", TwoLetterCode = "bm", ThreeLetterCode = "bam")] + Bambara, + + [Language(LongName = "Basa", ThreeLetterCode = "bas")] + Basa, + + [Language(LongName = "Bashkir", TwoLetterCode = "ba", ThreeLetterCode = "bak")] + Bashkir, + + [Language(LongName = "Basque", TwoLetterCode = "eu", ThreeLetterCode = "baq", ThreeLetterCodeAlt = "eus")] + Basque, + + // Beja; Bedawiyet + [Language(LongName = "Beja", ThreeLetterCode = "bej")] + Beja, + + [Language(LongName = "Belarusian", TwoLetterCode = "be", ThreeLetterCode = "bel")] + Belarusian, + + [Language(LongName = "Bemba", ThreeLetterCode = "bem")] + Bemba, + + [Language(LongName = "Bengali", TwoLetterCode = "bn", ThreeLetterCode = "ben")] + Bengali, + + [Language(LongName = "Bhojpuri", ThreeLetterCode = "bho")] + Bhojpuri, + + [Language(LongName = "Bikol", ThreeLetterCode = "bik")] + Bikol, + + [Language(LongName = "Bini; Edo", ThreeLetterCode = "bin")] + Bini, + + [Language(LongName = "Bislama", TwoLetterCode = "bi", ThreeLetterCode = "bis")] + Bislama, + + // Blin; Bilin + [Language(LongName = "Blin", ThreeLetterCode = "byn")] + Blin, + + // Blissymbols; Blissymbolics; Bliss + [Language(LongName = "Blissymbols", ThreeLetterCode = "zbl")] + Blissymbols, + + [Language(LongName = "Bosnian", TwoLetterCode = "bs", ThreeLetterCode = "bos")] + Bosnian, + + [Language(LongName = "Braj", ThreeLetterCode = "bra")] + Braj, + + [Language(LongName = "Breton", TwoLetterCode = "br", ThreeLetterCode = "bre")] + Breton, + + [Language(LongName = "Buginese", ThreeLetterCode = "bug")] + Buginese, + + [Language(LongName = "Bulgarian", TwoLetterCode = "bg", ThreeLetterCode = "bul")] + Bulgarian, + + [Language(LongName = "Buriat", ThreeLetterCode = "bua")] + Buriat, + + [Language(LongName = "Burmese", TwoLetterCode = "my", ThreeLetterCode = "bur", ThreeLetterCodeAlt = "mya")] + Burmese, + + #endregion + + #region C + + [Language(LongName = "Caddo", ThreeLetterCode = "cad")] + Caddo, + + // Catalan; Valencian + [Language(LongName = "Catalan", TwoLetterCode = "ca", ThreeLetterCode = "cat")] + Catalan, + + [Language(LongName = "Cebuano", ThreeLetterCode = "ceb")] + Cebuano, + + [Language(LongName = "Central Khmer", TwoLetterCode = "km", ThreeLetterCode = "khm")] + CentralKhmer, + + [Language(LongName = "Chagatai", ThreeLetterCode = "chg")] + Chagatai, + + [Language(LongName = "Chamorro", TwoLetterCode = "ch", ThreeLetterCode = "cha")] + Chamorro, + + [Language(LongName = "Chechen", TwoLetterCode = "ce", ThreeLetterCode = "che")] + Chechen, + + [Language(LongName = "Cherokee", ThreeLetterCode = "chr")] + Cherokee, + + [Language(LongName = "Cheyenne", ThreeLetterCode = "chy")] + Cheyenne, + + [Language(LongName = "Chibcha", ThreeLetterCode = "chb")] + Chibcha, + + // Chichewa; Chewa; Nyanja + [Language(LongName = "Chichewa", TwoLetterCode = "ny", ThreeLetterCode = "nya")] + Chichewa, + + [Language(LongName = "Chinese", TwoLetterCode = "zh", ThreeLetterCode = "chi", ThreeLetterCodeAlt = "zho")] + Chinese, + + [Language(LongName = "Chinook jargon", ThreeLetterCode = "chn")] + ChinookJargon, + + // Chipewyan; Dene Suline + [Language(LongName = "Chipewyan", ThreeLetterCode = "chp")] + Chipewyan, + + [Language(LongName = "Choctaw", ThreeLetterCode = "cho")] + Choctaw, + + // Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic + [Language(LongName = "Church Slavic", TwoLetterCode = "cu", ThreeLetterCode = "chu")] + ChurchSlavic, + + [Language(LongName = "Chuukese", ThreeLetterCode = "chk")] + Chuukese, + + [Language(LongName = "Chuvash", TwoLetterCode = "cv", ThreeLetterCode = "chv")] + Chuvash, + + // Classical Newari; Old Newari; Classical Nepal Bhasa + [Language(LongName = "Classical Newari", ThreeLetterCode = "nwc")] + ClassicalNewari, + + [Language(LongName = "Coptic", ThreeLetterCode = "cop")] + Coptic, + + [Language(LongName = "Cornish", TwoLetterCode = "kw", ThreeLetterCode = "cor")] + Cornish, + + [Language(LongName = "Corsican", TwoLetterCode = "co", ThreeLetterCode = "cos")] + Corsican, + + [Language(LongName = "Cree", TwoLetterCode = "cr", ThreeLetterCode = "cre")] + Cree, + + [Language(LongName = "Creek", ThreeLetterCode = "mus")] + Creek, + + [Language(LongName = "Creoles and pidgins", ThreeLetterCode = "crp")] + CreolesAndPidgins, + + [Language(LongName = "Creoles and pidgins (English-based)", ThreeLetterCode = "cpe")] + EnglishCreole, + + [Language(LongName = "Creoles and pidgins (French-based)", ThreeLetterCode = "cpf")] + FrenchCreole, + + [Language(LongName = "Creoles and pidgins (Portuguese-based)", ThreeLetterCode = "cpp")] + PortugueseCreole, + + // Crimean Tatar; Crimean Turkish + [Language(LongName = "Crimean Tatar", ThreeLetterCode = "crh")] + CrimeanTatar, + + [Language(LongName = "Croatian", TwoLetterCode = "hr", ThreeLetterCode = "hrv")] + Croatian, + + [Language(LongName = "Czech", TwoLetterCode = "cs", ThreeLetterCode = "cze", ThreeLetterCodeAlt = "ces")] + Czech, + + #endregion + + #region D + + [Language(LongName = "Dakota", ThreeLetterCode = "dak")] + Dakota, + + [Language(LongName = "Danish", TwoLetterCode = "da", ThreeLetterCode = "dan")] + Danish, + + [Language(LongName = "Dargwa", ThreeLetterCode = "dar")] + Dargwa, + + [Language(LongName = "Delaware", ThreeLetterCode = "del")] + Delaware, + + [Language(LongName = "Dinka", ThreeLetterCode = "din")] + Dinka, + + // Divehi; Dhivehi; Maldivian + [Language(LongName = "Divehi", TwoLetterCode = "dv", ThreeLetterCode = "div")] + Divehi, + + [Language(LongName = "Dogrib", ThreeLetterCode = "dgr")] + Dogrib, + + [Language(LongName = "Dogri", ThreeLetterCode = "doi")] + Dogri, + + [Language(LongName = "Duala", ThreeLetterCode = "dua")] + Duala, + + // Dutch; Flemish + [Language(LongName = "Dutch", TwoLetterCode = "nl", ThreeLetterCode = "dut", ThreeLetterCodeAlt = "nld")] + Dutch, + + [Language(LongName = "Dutch, Middle (ca.1050-1350)", ThreeLetterCode = "dum")] + MiddleDutch, + + [Language(LongName = "Dyula", ThreeLetterCode = "dyu")] + Dyula, + + [Language(LongName = "Dzongkha", TwoLetterCode = "dz", ThreeLetterCode = "dzo")] + Dzongkha, + + #endregion + + #region E + + [Language(LongName = "Eastern Frisian", ThreeLetterCode = "frs")] + EasternFrisian, + + [Language(LongName = "Efik", ThreeLetterCode = "efi")] + Efik, + + [Language(LongName = "Egyptian (Ancient)", ThreeLetterCode = "egy")] + AncientEgyptian, + + [Language(LongName = "Ekajuk", ThreeLetterCode = "eka")] + Ekajuk, + + [Language(LongName = "Elamite", ThreeLetterCode = "elx")] + Elamite, + + [Language(LongName = "English", TwoLetterCode = "en", ThreeLetterCode = "eng")] + English, + + [Language(LongName = "English, Old (ca.450-1100)", ThreeLetterCode = "ang")] + OldEnglish, + + [Language(LongName = "English, Middle (1100-1500)", ThreeLetterCode = "enm")] + MiddleEnglish, + + [Language(LongName = "Erzya", ThreeLetterCode = "myv")] + Erzya, + + [Language(LongName = "Esperanto", TwoLetterCode = "eo", ThreeLetterCode = "epo")] + Esperanto, + + [Language(LongName = "Estonian", TwoLetterCode = "et", ThreeLetterCode = "est")] + Estonian, + + [Language(LongName = "Ewe", TwoLetterCode = "ee", ThreeLetterCode = "ewe")] + Ewe, + + [Language(LongName = "Ewondo", ThreeLetterCode = "ewo")] + Ewondo, + + #endregion + + #region F + + [Language(LongName = "Fang", ThreeLetterCode = "fan")] + Fang, + + [Language(LongName = "Faroese", TwoLetterCode = "fo", ThreeLetterCode = "fao")] + Faroese, + + [Language(LongName = "Fanti", ThreeLetterCode = "fat")] + Fanti, + + [Language(LongName = "Fijian", TwoLetterCode = "fj", ThreeLetterCode = "fij")] + Fijian, + + // Filipino; Pilipino + [Language(LongName = "Filipino", ThreeLetterCode = "fil")] + Filipino, + + [Language(LongName = "Finnish", TwoLetterCode = "fi", ThreeLetterCode = "fin")] + Finnish, + + [Language(LongName = "Fon", ThreeLetterCode = "fon")] + Fon, + + [Language(LongName = "French", TwoLetterCode = "fr", ThreeLetterCode = "fre", ThreeLetterCodeAlt = "fra")] + French, + + [Language(LongName = "French, Middle (ca.1400-1600)", ThreeLetterCode = "frm")] + MiddleFrench, + + [Language(LongName = "French, Old (842-ca.1400)", ThreeLetterCode = "fro")] + OldFrench, + + [Language(LongName = "Friulian", ThreeLetterCode = "fur")] + Friulian, + + [Language(LongName = "Fulah", TwoLetterCode = "ff", ThreeLetterCode = "ful")] + Fulah, + + #endregion + + #region G + + [Language(LongName = "Ga", ThreeLetterCode = "gaa")] + Ga, + + // Gaelic; Scottish Gaelic + [Language(LongName = "Gaelic", TwoLetterCode = "gd", ThreeLetterCode = "gla")] + Gaelic, + + [Language(LongName = "Galibi Carib", ThreeLetterCode = "car")] + GalibiCarib, + + [Language(LongName = "Galician", TwoLetterCode = "gl", ThreeLetterCode = "glg")] + Galician, + + [Language(LongName = "Ganda", TwoLetterCode = "lg", ThreeLetterCode = "lug")] + Ganda, + + [Language(LongName = "Gayo", ThreeLetterCode = "gay")] + Gayo, + + [Language(LongName = "Gbaya", ThreeLetterCode = "gba")] + Gbaya, + + [Language(LongName = "Geez", ThreeLetterCode = "gez")] + Geez, + + [Language(LongName = "Georgian", TwoLetterCode = "ka", ThreeLetterCode = "geo", ThreeLetterCodeAlt = "kat")] + Georgian, + + [Language(LongName = "German", TwoLetterCode = "de", ThreeLetterCode = "ger", ThreeLetterCodeAlt = "deu")] + German, + + [Language(LongName = "German, Middle High (ca.1050-1500)", ThreeLetterCode = "gmh")] + MiddleHighGerman, + + [Language(LongName = "German, Old High (ca.750-1050)", ThreeLetterCode = "goh")] + OldHighGerman, + + [Language(LongName = "Gilbertese", ThreeLetterCode = "gil")] + Gilbertese, + + [Language(LongName = "Gondi", ThreeLetterCode = "gon")] + Gondi, + + [Language(LongName = "Gorontalo", ThreeLetterCode = "gor")] + Gorontalo, + + [Language(LongName = "Gothic", ThreeLetterCode = "got")] + Gothic, + + [Language(LongName = "Grebo", ThreeLetterCode = "grb")] + Grebo, + + [Language(LongName = "Greek", TwoLetterCode = "el", ThreeLetterCode = "gre", ThreeLetterCodeAlt = "eli")] + Greek, + + [Language(LongName = "Greek, Ancient (to 1453)", ThreeLetterCode = "grc")] + AncientGreek, + + [Language(LongName = "Guarani", TwoLetterCode = "gn", ThreeLetterCode = "grn")] + Guarani, + + [Language(LongName = "Gujarati", TwoLetterCode = "gu", ThreeLetterCode = "guj")] + Gujarati, + + [Language(LongName = "Gwich'in", ThreeLetterCode = "gwi")] + Gwichin, + + #endregion + + #region H + + [Language(LongName = "Haida", ThreeLetterCode = "hai")] + Haida, + + // Haitian; Haitian Creole + [Language(LongName = "Haitian", TwoLetterCode = "ht", ThreeLetterCode = "hat")] + Haitian, + + [Language(LongName = "Hausa", TwoLetterCode = "ha", ThreeLetterCode = "gau")] + Hausa, + + [Language(LongName = "Hawaiian", ThreeLetterCode = "haw")] + Hawaiian, + + [Language(LongName = "Hebrew", TwoLetterCode = "he", ThreeLetterCode = "heb")] + Hebrew, + + [Language(LongName = "Herero", TwoLetterCode = "hz", ThreeLetterCode = "her")] + Herero, + + [Language(LongName = "Hiligaynon", ThreeLetterCode = "hil")] + Hiligaynon, + + [Language(LongName = "Hindi", TwoLetterCode = "hi", ThreeLetterCode = "hin")] + Hindi, + + [Language(LongName = "Hiri Motu", ThreeLetterCode = "hmo")] + HiriMotu, + + [Language(LongName = "Hittite", ThreeLetterCode = "hit")] + Hittite, + + // Hmong; Mong + [Language(LongName = "Hmong", ThreeLetterCode = "hmn")] + Hmong, + + [Language(LongName = "Hungarian", TwoLetterCode = "hu", ThreeLetterCode = "hun")] + Hungarian, + + [Language(LongName = "Hupa", ThreeLetterCode = "hup")] + Hupa, + + #endregion + + #region I + + [Language(LongName = "Iban", ThreeLetterCode = "iba")] + Iban, + + [Language(LongName = "Icelandic", TwoLetterCode = "is", ThreeLetterCode = "ice", ThreeLetterCodeAlt = "isl")] + Icelandic, + + [Language(LongName = "Ido", TwoLetterCode = "io", ThreeLetterCode = "ido")] + Ido, + + [Language(LongName = "Igbo", TwoLetterCode = "ig", ThreeLetterCode = "ibo")] + Igbo, + + [Language(LongName = "Iloko", ThreeLetterCode = "ilo")] + Iloko, + + [Language(LongName = "Inari Sami", ThreeLetterCode = "smn")] + InariSami, + + [Language(LongName = "Indonesian", TwoLetterCode = "id", ThreeLetterCode = "ind")] + Indonesian, + + [Language(LongName = "Ingush", ThreeLetterCode = "inh")] + Ingush, + + // Interlingua (International Auxiliary Language Association) + [Language(LongName = "Interlingua", TwoLetterCode = "ia", ThreeLetterCode = "ina")] + Interlingua, + + // Interlingue; Occidental + [Language(LongName = "Interlingue", TwoLetterCode = "ie", ThreeLetterCode = "ile")] + Interlingue, + + [Language(LongName = "Inuktitut", TwoLetterCode = "iu", ThreeLetterCode = "iku")] + Inuktitut, + + [Language(LongName = "Inupiaq", TwoLetterCode = "ik", ThreeLetterCode = "ipk")] + Inupiaq, + + [Language(LongName = "Irish", TwoLetterCode = "ga", ThreeLetterCode = "gle")] + Irish, + + [Language(LongName = "Irish, Middle (900-1200)", ThreeLetterCode = "mga")] + MiddleIrish, + + [Language(LongName = "Irish, Old (to 900)", ThreeLetterCode = "sga")] + OldIrish, + + [Language(LongName = "Italian", TwoLetterCode = "it", ThreeLetterCode = "ita")] + Italian, + + #endregion + + #region J + + [Language(LongName = "Japanese", TwoLetterCode = "ja", ThreeLetterCode = "jap")] + Japanese, + + [Language(LongName = "Javanese", TwoLetterCode = "jv", ThreeLetterCode = "jav")] + Javanese, + + [Language(LongName = "Judeo-Arabic", ThreeLetterCode = "jrb")] + JudeoArabic, + + [Language(LongName = "Judeo-Persian", ThreeLetterCode = "jpr")] + JudeoPersian, + + #endregion + + #region K + + [Language(LongName = "Kabardian", ThreeLetterCode = "kbd")] + Kabardian, + + [Language(LongName = "Kabyle", ThreeLetterCode = "kab")] + Kabyle, + + // Kachin; Jingpho + [Language(LongName = "Kachin", ThreeLetterCode = "kac")] + Kachin, + + // Kalaallisut; Greenlandic + [Language(LongName = "Kalaallisut", TwoLetterCode = "kl", ThreeLetterCode = "kal")] + Kalaallisut, + + // Kalmyk; Oirat + [Language(LongName = "Kalmyk", ThreeLetterCode = "xal")] + Kalmyk, + + [Language(LongName = "Kamba", ThreeLetterCode = "kam")] + Kamba, + + [Language(LongName = "Kannada", TwoLetterCode = "kn", ThreeLetterCode = "kan")] + Kannada, + + [Language(LongName = "Kanuri", TwoLetterCode = "kr", ThreeLetterCode = "kau")] + Kanuri, + + [Language(LongName = "Karachay-Balkar", ThreeLetterCode = "krc")] + KarachayBalkar, + + [Language(LongName = "Kara-Kalpak", ThreeLetterCode = "kaa")] + KaraKalpak, + + [Language(LongName = "Karelian", ThreeLetterCode = "krl")] + Karelian, + + [Language(LongName = "Kashmiri", TwoLetterCode = "ks", ThreeLetterCode = "kas")] + Kashmiri, + + [Language(LongName = "Kashubian", ThreeLetterCode = "csb")] + Kashubian, + + [Language(LongName = "Kawi", ThreeLetterCode = "kaw")] + Kawi, + + [Language(LongName = "Kazakh", TwoLetterCode = "kk", ThreeLetterCode = "kaz")] + Kazakh, + + [Language(LongName = "Khasi", ThreeLetterCode = "kha")] + Khasi, + + // Khotanese; Sakan + [Language(LongName = "Khotanese", ThreeLetterCode = "kho")] + Khotanese, + + // Kikuyu; Gikuyu + [Language(LongName = "Kikuyu", TwoLetterCode = "ki", ThreeLetterCode = "kik")] + Kikuyu, + + [Language(LongName = "Kimbundu", ThreeLetterCode = "kmb")] + Kimbundu, + + [Language(LongName = "Kinyarwanda", TwoLetterCode = "rw", ThreeLetterCode = "kin")] + Kinyarwanda, + + // Kirghiz; Kyrgyz + [Language(LongName = "Kirghiz", TwoLetterCode = "ky", ThreeLetterCode = "kir")] + Kirghiz, + + // Klingon; tlhIngan-Hol + [Language(LongName = "Klingon", ThreeLetterCode = "tlh")] + Klingon, + + [Language(LongName = "Komi", TwoLetterCode = "kv", ThreeLetterCode = "kom")] + Komi, + + [Language(LongName = "Kongo", TwoLetterCode = "kg", ThreeLetterCode = "kon")] + Kongo, + + [Language(LongName = "Konkani", ThreeLetterCode = "kok")] + Konkani, + + [Language(LongName = "Korean", TwoLetterCode = "ko", ThreeLetterCode = "kor")] + Korean, + + [Language(LongName = "Kosraean", ThreeLetterCode = "kos")] + Kosraean, + + [Language(LongName = "Kpelle", ThreeLetterCode = "kpe")] + Kpelle, + + // Kuanyama; Kwanyama + [Language(LongName = "Kuanyama", TwoLetterCode = "kj", ThreeLetterCode = "kua")] + Kuanyama, + + [Language(LongName = "Kumyk", ThreeLetterCode = "kum")] + Kumyk, + + [Language(LongName = "Kurdish", TwoLetterCode = "ku", ThreeLetterCode = "kur")] + Kurdish, + + [Language(LongName = "Kurukh", ThreeLetterCode = "kru")] + Kurukh, + + [Language(LongName = "Kutenai", ThreeLetterCode = "kut")] + Kutenai, + + #endregion + + #region L + + [Language(LongName = "Ladino", ThreeLetterCode = "lad")] + Ladino, + + [Language(LongName = "Lahnda", ThreeLetterCode = "lah")] + Lahnda, + + [Language(LongName = "Lamba", ThreeLetterCode = "lam")] + Lamba, + + [Language(LongName = "Lao", TwoLetterCode = "lo", ThreeLetterCode = "lao")] + Lao, + + [Language(LongName = "Latin", TwoLetterCode = "la", ThreeLetterCode = "lat")] + Latin, + + [Language(LongName = "Latvian", TwoLetterCode = "lv", ThreeLetterCode = "lav")] + Latvian, + + [Language(LongName = "Lezghian", ThreeLetterCode = "lez")] + Lezghian, + + // Limburgan; Limburger; Limburgish + [Language(LongName = "Limburgan", TwoLetterCode = "li", ThreeLetterCode = "lim")] + Limburgan, + + [Language(LongName = "Lingala", TwoLetterCode = "ln", ThreeLetterCode = "lin")] + Lingala, + + [Language(LongName = "Lithuanian", TwoLetterCode = "lt", ThreeLetterCode = "lit")] + Lithuanian, + + [Language(LongName = "Lojban", ThreeLetterCode = "jbo")] + Lojban, + + // Low German; Low Saxon + [Language(LongName = "Low German", ThreeLetterCode = "nds")] + LowGerman, + + [Language(LongName = "Lower Sorbian", ThreeLetterCode = "dsb")] + LowerSorbian, + + [Language(LongName = "Lozi", ThreeLetterCode = "loz")] + Lozi, + + [Language(LongName = "Luba-Katanga", TwoLetterCode = "lu", ThreeLetterCode = "lub")] + LubaKatanga, + + [Language(LongName = "Luba-Lulua", ThreeLetterCode = "lua")] + LubaLulua, + + [Language(LongName = "Luiseno", ThreeLetterCode = "lui")] + Luiseno, + + [Language(LongName = "Lule Sami", ThreeLetterCode = "smj")] + LuleSami, + + [Language(LongName = "Lunda", ThreeLetterCode = "lun")] + Lunda, + + [Language(LongName = "Luo (Kenya and Tanzania)", ThreeLetterCode = "luo")] + Luo, + + [Language(LongName = "Lushai", ThreeLetterCode = "lus")] + Lushai, + + // Luxembourgish; Letzeburgesch + [Language(LongName = "Luxembourgish", TwoLetterCode = "lb", ThreeLetterCode = "ltz")] + Luxembourgish, + + #endregion + + #region M + + [Language(LongName = "Macedonian", TwoLetterCode = "mk", ThreeLetterCode = "mac", ThreeLetterCodeAlt = "mkd")] + Macedonian, + + [Language(LongName = "Madurese", ThreeLetterCode = "mad")] + Madurese, + + [Language(LongName = "Magahi", ThreeLetterCode = "mag")] + Magahi, + + [Language(LongName = "Maithili", ThreeLetterCode = "mai")] + Maithili, + + [Language(LongName = "Makasar", ThreeLetterCode = "mak")] + Makasar, + + [Language(LongName = "Malagasy", TwoLetterCode = "mg", ThreeLetterCode = "mlg")] + Malagasy, + + [Language(LongName = "Malay", TwoLetterCode = "ms", ThreeLetterCode = "may", ThreeLetterCodeAlt = "msa")] + Malay, + + [Language(LongName = "Malayalam", TwoLetterCode = "ml", ThreeLetterCode = "mal")] + Malayalam, + + [Language(LongName = "Maltese", TwoLetterCode = "mt", ThreeLetterCode = "mlt")] + Maltese, + + [Language(LongName = "Manchu", ThreeLetterCode = "mnc")] + Manchu, + + [Language(LongName = "Mandar", ThreeLetterCode = "mdr")] + Mandar, + + [Language(LongName = "Mandingo", ThreeLetterCode = "man")] + Mandingo, + + [Language(LongName = "Manipuri", ThreeLetterCode = "mni")] + Manipuri, + + [Language(LongName = "Manx", TwoLetterCode = "gv", ThreeLetterCode = "glv")] + Manx, + + [Language(LongName = "Maori", TwoLetterCode = "mi", ThreeLetterCode = "mao", ThreeLetterCodeAlt = "mri")] + Maori, + + // Mapudungun; Mapuche + [Language(LongName = "Mapudungun", ThreeLetterCode = "arn")] + Mapudungun, + + [Language(LongName = "Marathi", TwoLetterCode = "mr", ThreeLetterCode = "mar")] + Marathi, + + [Language(LongName = "Mari", ThreeLetterCode = "chm")] + Mari, + + [Language(LongName = "Marshallese", TwoLetterCode = "mh", ThreeLetterCode = "mah")] + Marshallese, + + [Language(LongName = "Marwari", ThreeLetterCode = "mwr")] + Marwari, + + [Language(LongName = "Masai", ThreeLetterCode = "mas")] + Masai, + + [Language(LongName = "Mende", ThreeLetterCode = "men")] + Mende, + + // Mi'kmaq; Micmac + [Language(LongName = "Mi'kmaq", ThreeLetterCode = "mic")] + Mikmaq, + + [Language(LongName = "Minangkabau", ThreeLetterCode = "min")] + Minangkabau, + + [Language(LongName = "Mirandese", ThreeLetterCode = "mwl")] + Mirandese, + + [Language(LongName = "Mohawk", ThreeLetterCode = "moh")] + Mohawk, + + [Language(LongName = "Moksha", ThreeLetterCode = "mdf")] + Moksha, + + [Language(LongName = "Mongo", ThreeLetterCode = "lol")] + Mongo, + + [Language(LongName = "Mongolian", TwoLetterCode = "mn", ThreeLetterCode = "mon")] + Mongolian, + + [Language(LongName = "Montenegrin", ThreeLetterCode = "cnr")] + Montenegrin, + + [Language(LongName = "Mossi", ThreeLetterCode = "mos")] + Mossi, + + #endregion + + #region N + + [Language(LongName = "N'Ko", ThreeLetterCode = "nqo")] + NKo, + + [Language(LongName = "Nauru", TwoLetterCode = "na", ThreeLetterCode = "nau")] + Nauru, + + // Navajo; Navaho + [Language(LongName = "Navajo", TwoLetterCode = "nv", ThreeLetterCode = "nav")] + Navajo, + + [Language(LongName = "Ndonga", TwoLetterCode = "ng", ThreeLetterCode = "ndo")] + Ndonga, + + [Language(LongName = "Neapolitan", ThreeLetterCode = "nap")] + Neapolitan, + + // Nepal Bhasa; Newari + [Language(LongName = "Nepal Bhasa", ThreeLetterCode = "new")] + NepalBhasa, + + [Language(LongName = "Nepali", TwoLetterCode = "ne", ThreeLetterCode = "nep")] + Nepali, + + [Language(LongName = "Nias", ThreeLetterCode = "nia")] + Nias, + + [Language(LongName = "Niuean", ThreeLetterCode = "niu")] + Niuean, + + // Commented out to avoid confusion + //[Language(LongName = "No linguistic content; Not applicable", ThreeLetterCode = "zxx")] + //NoLinguisticContent, + + [Language(LongName = "Nogai", ThreeLetterCode = "nog")] + Nogai, + + [Language(LongName = "Norse, Old", ThreeLetterCode = "non")] + OldNorse, + + [Language(LongName = "North Ndebele", TwoLetterCode = "nd", ThreeLetterCode = "nde")] + NorthNdebele, + + [Language(LongName = "Northern Frisian", ThreeLetterCode = "frr")] + NorthernFrisian, + + [Language(LongName = "Northern Sami", TwoLetterCode = "se", ThreeLetterCode = "sme")] + NorthernSami, + + [Language(LongName = "Norwegian", TwoLetterCode = "no", ThreeLetterCode = "nor")] + Norwegian, + + [Language(LongName = "Norwegian Bokmål", TwoLetterCode = "nb", ThreeLetterCode = "nob")] + NorwegianBokmal, + + [Language(LongName = "Norwegian Nynorsk", TwoLetterCode = "nn", ThreeLetterCode = "nno")] + NorwegianNynorsk, + + [Language(LongName = "Nyamwezi", ThreeLetterCode = "nym")] + Nyamwezi, + + [Language(LongName = "Nyankole", ThreeLetterCode = "nyn")] + Nyankole, + + [Language(LongName = "Nyoro", ThreeLetterCode = "nyo")] + Nyoro, + + [Language(LongName = "Nzima", ThreeLetterCode = "nzi")] + Nzima, + + #endregion + + #region O + + [Language(LongName = "Occitan (post 1500)", TwoLetterCode = "oc", ThreeLetterCode = "oci")] + Occitan, + + // Occitan, Old (to 1500); Provençal, Old (to 1500) + [Language(LongName = "Occitan, Old (to 1500)", ThreeLetterCode = "pro")] + OldOccitan, + + [Language(LongName = "Ojibwa", TwoLetterCode = "oj", ThreeLetterCode = "oji")] + Ojibwa, + + [Language(LongName = "Oriya", TwoLetterCode = "or", ThreeLetterCode = "ori")] + Oriya, + + [Language(LongName = "Oromo", TwoLetterCode = "om", ThreeLetterCode = "orm")] + Oromo, + + [Language(LongName = "Osage", ThreeLetterCode = "osa")] + Osage, + + // Ossetian; Ossetic + [Language(LongName = "Ossetian", TwoLetterCode = "os", ThreeLetterCode = "oss")] + Ossetian, + + #endregion + + #region P + + [Language(LongName = "Pahlavi", ThreeLetterCode = "pal")] + Pahlavi, + + [Language(LongName = "Palauan", ThreeLetterCode = "pau")] + Palauan, + + [Language(LongName = "Pali", TwoLetterCode = "pi", ThreeLetterCode = "pli")] + Pali, + + // Pampanga; Kapampangan + [Language(LongName = "Pampanga", ThreeLetterCode = "pam")] + Pampanga, + + [Language(LongName = "Pangasinan", ThreeLetterCode = "pag")] + Pangasinan, + + // Panjabi; Punjabi + [Language(LongName = "Panjabi", TwoLetterCode = "pa", ThreeLetterCode = "pan")] + Panjabi, + + [Language(LongName = "Papiamento", ThreeLetterCode = "pap")] + Papiamento, + + // Pedi; Sepedi; Northern Sotho + [Language(LongName = "Pedi", ThreeLetterCode = "nso")] + Pedi, + + [Language(LongName = "Persian", TwoLetterCode = "fa", ThreeLetterCode = "per", ThreeLetterCodeAlt = "fas")] + Persian, + + [Language(LongName = "Persian, Old (ca.600-400 B.C.)", ThreeLetterCode = "peo")] + OldPersian, + + [Language(LongName = "Phoenician", ThreeLetterCode = "phn")] + Phoenician, + + [Language(LongName = "Polish", TwoLetterCode = "pl", ThreeLetterCode = "pol")] + Polish, + + [Language(LongName = "Portuguese", TwoLetterCode = "pt", ThreeLetterCode = "por")] + Portuguese, + + // Pushto; Pashto + [Language(LongName = "Pushto", TwoLetterCode = "ps", ThreeLetterCode = "pus")] + Pushto, + + #endregion + + #region Q + + // qaa-qtz: Reserved for local use + + [Language(LongName = "Quechua", TwoLetterCode = "qu", ThreeLetterCode = "que")] + Quechua, + + #endregion + + #region R + + [Language(LongName = "Rajasthani", ThreeLetterCode = "raj")] + Rajasthani, + + [Language(LongName = "Rapanui", ThreeLetterCode = "rap")] + Rapanui, + + // Rarotongan; Cook Islands Maori + [Language(LongName = "Rarotongan", ThreeLetterCode = "rar")] + Rarotongan, + + // Romanian; Moldavian; Moldovan + [Language(LongName = "Romanian", TwoLetterCode = "ro", ThreeLetterCode = "rum", ThreeLetterCodeAlt = "ron")] + Romanian, + + [Language(LongName = "Romansh", TwoLetterCode = "rm", ThreeLetterCode = "roh")] + Romansh, + + [Language(LongName = "Romany", ThreeLetterCode = "rom")] + Romany, + + [Language(LongName = "Rundi", TwoLetterCode = "rn", ThreeLetterCode = "run")] + Rundi, + + [Language(LongName = "Russian", TwoLetterCode = "ru", ThreeLetterCode = "rus")] + Russian, + + #endregion + + #region S + + [Language(LongName = "Samaritan Aramaic", ThreeLetterCode = "sam")] + SamaritanAramaic, + + [Language(LongName = "Samoan", TwoLetterCode = "sm", ThreeLetterCode = "smo")] + Samoan, + + [Language(LongName = "Sandawe", ThreeLetterCode = "sad")] + Sandawe, + + [Language(LongName = "Sango", TwoLetterCode = "sg", ThreeLetterCode = "sag")] + Sango, + + [Language(LongName = "Sanskrit", TwoLetterCode = "sa", ThreeLetterCode = "san")] + Sanskrit, + + [Language(LongName = "Santali", ThreeLetterCode = "sat")] + Santali, + + [Language(LongName = "Sardinian", TwoLetterCode = "sc", ThreeLetterCode = "srd")] + Sardinian, + + [Language(LongName = "Sasak", ThreeLetterCode = "sas")] + Sasak, + + [Language(LongName = "Scots", ThreeLetterCode = "sco")] + Scots, + + [Language(LongName = "Selkup", ThreeLetterCode = "sel")] + Selkup, + + [Language(LongName = "Serbian", TwoLetterCode = "sr", ThreeLetterCode = "srp")] + Serbian, + + [Language(LongName = "Serer", ThreeLetterCode = "srr")] + Serer, + + [Language(LongName = "Shan", ThreeLetterCode = "shn")] + Shan, + + [Language(LongName = "Shona", TwoLetterCode = "sn", ThreeLetterCode = "sna")] + Shona, + + // Sichuan Yi; Nuosu + [Language(LongName = "Sichuan Yi", TwoLetterCode = "ii", ThreeLetterCode = "iii")] + SichuanYi, + + [Language(LongName = "Sicilian", ThreeLetterCode = "scn")] + Sicilian, + + [Language(LongName = "Sidamo", ThreeLetterCode = "sid")] + Sidamo, + + [Language(LongName = "Sign Languages", ThreeLetterCode = "sgn")] + SignLanguages, + + [Language(LongName = "Siksika", ThreeLetterCode = "bla")] + Siksika, + + [Language(LongName = "Sindhi", TwoLetterCode = "sd", ThreeLetterCode = "snd")] + Sindhi, + + // Sinhala; Sinhalese + [Language(LongName = "Sinhala", TwoLetterCode = "si", ThreeLetterCode = "sin")] + Sinhala, + + [Language(LongName = "Skolt Sami", ThreeLetterCode = "sms")] + SkoltSami, + + [Language(LongName = "Slovak", TwoLetterCode = "sk", ThreeLetterCode = "slo", ThreeLetterCodeAlt = "slk")] + Slovak, + + [Language(LongName = "Slovenian", TwoLetterCode = "sl", ThreeLetterCode = "slv")] + Slovenian, + + [Language(LongName = "Sogdian", ThreeLetterCode = "sog")] + Sogdian, + + [Language(LongName = "Somali", TwoLetterCode = "so", ThreeLetterCode = "som")] + Somali, + + [Language(LongName = "Soninke", ThreeLetterCode = "snk")] + Soninke, + + [Language(LongName = "Sotho, Southern", TwoLetterCode = "st", ThreeLetterCode = "sot")] + Sotho, + + [Language(LongName = "South Ndebele", TwoLetterCode = "nr", ThreeLetterCode = "nbl")] + SouthNdebele, + + [Language(LongName = "Southern Altai", ThreeLetterCode = "alt")] + SouthernAltai, + + [Language(LongName = "Southern Sami", ThreeLetterCode = "sma")] + SouthernSami, + + // Spanish; Castilian + [Language(LongName = "Spanish", TwoLetterCode = "es", ThreeLetterCode = "spa")] + Spanish, + + [Language(LongName = "Sranan Tongo", ThreeLetterCode = "srn")] + SrananTongo, + + [Language(LongName = "Standard Moroccan Tamazight", ThreeLetterCode = "zgh")] + StandardMoroccanTamazight, + + [Language(LongName = "Sukuma", ThreeLetterCode = "suk")] + Sukuma, + + [Language(LongName = "Sumerian", ThreeLetterCode = "sux")] + Sumerian, + + [Language(LongName = "Sundanese", TwoLetterCode = "su", ThreeLetterCode = "sun")] + Sundanese, + + [Language(LongName = "Susu", ThreeLetterCode = "sus")] + Susu, + + [Language(LongName = "Susu", TwoLetterCode = "sw", ThreeLetterCode = "swa")] + Swahili, + + [Language(LongName = "Swatio", TwoLetterCode = "ss", ThreeLetterCode = "ssw")] + Swati, + + [Language(LongName = "Swedish", TwoLetterCode = "sv", ThreeLetterCode = "swe")] + Swedish, + + // Swiss German; Alemannic; Alsatian + [Language(LongName = "Swiss German", ThreeLetterCode = "gsw")] + SwissGerman, + + [Language(LongName = "Syriac", ThreeLetterCode = "syr")] + Syriac, + + [Language(LongName = "Syriac, Classical", ThreeLetterCode = "syc")] + ClassicalSyriac, + + #endregion + + #region T + + [Language(LongName = "Tagalog", TwoLetterCode = "tl", ThreeLetterCode = "tgl")] + Tagalog, + + [Language(LongName = "Tahitian", TwoLetterCode = "ty", ThreeLetterCode = "tah")] + Tahitian, + + [Language(LongName = "Tajik", TwoLetterCode = "tg", ThreeLetterCode = "tgk")] + Tajik, + + [Language(LongName = "Tamashek", ThreeLetterCode = "tmh")] + Tamashek, + + [Language(LongName = "Tamil", TwoLetterCode = "ta", ThreeLetterCode = "tam")] + Tamil, + + [Language(LongName = "Tatar", TwoLetterCode = "tt", ThreeLetterCode = "tat")] + Tatar, + + [Language(LongName = "Telugu", TwoLetterCode = "te", ThreeLetterCode = "tel")] + Telugu, + + [Language(LongName = "Tereno", ThreeLetterCode = "ter")] + Tereno, + + [Language(LongName = "Tetum", ThreeLetterCode = "tet")] + Tetum, + + [Language(LongName = "Thai", TwoLetterCode = "th", ThreeLetterCode = "tha")] + Thai, + + [Language(LongName = "Tibetan", TwoLetterCode = "bo", ThreeLetterCode = "tib", ThreeLetterCodeAlt = "bod")] + Tibetan, + + [Language(LongName = "Tigre", ThreeLetterCode = "tig")] + Tigre, + + [Language(LongName = "Tigrinya", TwoLetterCode = "ti", ThreeLetterCode = "tir")] + Tigrinya, + + [Language(LongName = "Timne", ThreeLetterCode = "tem")] + Timne, + + [Language(LongName = "Tiv", ThreeLetterCode = "tiv")] + Tiv, + + [Language(LongName = "Tlingit", ThreeLetterCode = "tli")] + Tlingit, + + [Language(LongName = "Tok Pisin", ThreeLetterCode = "tpi")] + TokPisin, + + [Language(LongName = "Tokelau", ThreeLetterCode = "tkl")] + Tokelau, + + [Language(LongName = "Tonga (Nyasa)", ThreeLetterCode = "tog")] + TongaNyasa, + + [Language(LongName = "Tonga (Tonga Islands)", TwoLetterCode = "to", ThreeLetterCode = "ton")] + TongaIslands, + + [Language(LongName = "Tsimshian", ThreeLetterCode = "tsi")] + Tsimshian, + + [Language(LongName = "Tsonga", TwoLetterCode = "ts", ThreeLetterCode = "tso")] + Tsonga, + + [Language(LongName = "Tswana", TwoLetterCode = "tn", ThreeLetterCode = "tsn")] + Tswana, + + [Language(LongName = "Tumbuka", ThreeLetterCode = "tum")] + Tumbuka, + + [Language(LongName = "Turkish", TwoLetterCode = "tr", ThreeLetterCode = "tur")] + Turkish, + + [Language(LongName = "Turkish, Ottoman (1500-1928)", ThreeLetterCode = "ota")] + OttomanTurkish, + + [Language(LongName = "Turkmen", TwoLetterCode = "tk", ThreeLetterCode = "tuk")] + Turkmen, + + [Language(LongName = "Tuvalu", ThreeLetterCode = "tvl")] + Tuvalu, + + [Language(LongName = "Tuvinian", ThreeLetterCode = "tyv")] + Tuvinian, + + [Language(LongName = "Twi", TwoLetterCode = "tw", ThreeLetterCode = "twi")] + Twi, + + #endregion + + #region U + + [Language(LongName = "Udmurt", ThreeLetterCode = "udm")] + Udmurt, + + [Language(LongName = "Ugaritic", ThreeLetterCode = "uga")] + Ugaritic, + + // Uighur; Uyghur + [Language(LongName = "Uighur", TwoLetterCode = "ug", ThreeLetterCode = "uig")] + Uighur, + + [Language(LongName = "Ukrainian", TwoLetterCode = "uk", ThreeLetterCode = "ukr")] + Ukrainian, + + [Language(LongName = "Umbundu", ThreeLetterCode = "umb")] + Umbundu, + + // Commented out to avoid confusion + //[Language(LongName = "Undetermined", ThreeLetterCode = "und")] + //Undetermined, + + [Language(LongName = "Upper Sorbian", ThreeLetterCode = "hsb")] + UpperSorbian, + + [Language(LongName = "Urdu", TwoLetterCode = "ur", ThreeLetterCode = "urd")] + Urdu, + + [Language(LongName = "Uzbek", TwoLetterCode = "uz", ThreeLetterCode = "uzb")] + Uzbek, + + #endregion + + #region V + + [Language(LongName = "Vai", ThreeLetterCode = "vai")] + Vai, + + [Language(LongName = "Venda", TwoLetterCode = "ve", ThreeLetterCode = "ven")] + Venda, + + [Language(LongName = "Vietnamese", TwoLetterCode = "vi", ThreeLetterCode = "vie")] + Vietnamese, + + [Language(LongName = "Volapük", TwoLetterCode = "vo", ThreeLetterCode = "vol")] + Volapuk, + + [Language(LongName = "Votic", ThreeLetterCode = "vot")] + Votic, + + #endregion + + #region W + + [Language(LongName = "Walloon", TwoLetterCode = "wa", ThreeLetterCode = "wln")] + Walloon, + + [Language(LongName = "Waray", ThreeLetterCode = "war")] + Waray, + + [Language(LongName = "Washo", ThreeLetterCode = "was")] + Washo, + + [Language(LongName = "Welsh", TwoLetterCode = "cy", ThreeLetterCode = "wel", ThreeLetterCodeAlt = "cym")] + Welsh, + + [Language(LongName = "Western Frisian", TwoLetterCode = "fy", ThreeLetterCode = "fry")] + WesternFrisian, + + // Wolaitta; Wolaytta + [Language(LongName = "Wolaitta", ThreeLetterCode = "wal")] + Wolaitta, + + [Language(LongName = "Wolof", TwoLetterCode = "wo", ThreeLetterCode = "wol")] + Wolof, + + #endregion + + #region X + + [Language(LongName = "Xhosa", TwoLetterCode = "xh", ThreeLetterCode = "xho")] + Xhosa, + + #endregion + + #region Y + + [Language(LongName = "Yakut", ThreeLetterCode = "sah")] + Yakut, + + [Language(LongName = "Yao", ThreeLetterCode = "yao")] + Yao, + + [Language(LongName = "Yapese", ThreeLetterCode = "yap")] + Yapese, + + [Language(LongName = "Yiddish", TwoLetterCode = "yi", ThreeLetterCode = "yid")] + Yiddish, + + [Language(LongName = "Yoruba", TwoLetterCode = "yo", ThreeLetterCode = "yor")] + Yoruba, + + #endregion + + #region Z + + [Language(LongName = "Zapotec", ThreeLetterCode = "zap")] + Zapotec, + + // Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki + [Language(LongName = "Zaza", ThreeLetterCode = "zza")] + Zaza, + + [Language(LongName = "Zenaga", ThreeLetterCode = "zen")] + Zenaga, + + // Zhuang; Chuang + [Language(LongName = "Zhuang", TwoLetterCode = "za", ThreeLetterCode = "zha")] + Zhuang, + + [Language(LongName = "Zulu", TwoLetterCode = "zu", ThreeLetterCode = "zul")] + Zulu, + + [Language(LongName = "Zuni", ThreeLetterCode = "zun")] + Zuni, + + #endregion + + #region Language Families + + /* + [Language(LongName = "Afro-Asiatic languages", ThreeLetterCode = "afa")] + AfroAsiaticLanguages, + + [Language(LongName = "Algonquian languages", ThreeLetterCode = "alg")] + AlgonquianLanguages, + + [Language(LongName = "Altaic languages", ThreeLetterCode = "tut")] + AltaicLanguages, + + [Language(LongName = "Apache languages", ThreeLetterCode = "apa")] + ApacheLanguages, + + [Language(LongName = "Artificial languages", ThreeLetterCode = "art")] + ArtificialLanguages, + + [Language(LongName = "Athapascan languages", ThreeLetterCode = "ath")] + AthapascanLanguages, + + [Language(LongName = "Australian languages", ThreeLetterCode = "aus")] + AustralianLanguages, + + [Language(LongName = "Austronesian languages", ThreeLetterCode = "map")] + AustronesianLanguages, + + [Language(LongName = "Baltic languages", ThreeLetterCode = "bat")] + BalticLanguages, + + [Language(LongName = "Bamileke languages", ThreeLetterCode = "bai")] + BamilekeLanguages, + + [Language(LongName = "Banda languages", ThreeLetterCode = "bad")] + BandaLanguages, + + [Language(LongName = "Bantu languages", ThreeLetterCode = "bnt")] + BantuLanguages, + + [Language(LongName = "Batak languages", ThreeLetterCode = "btk")] + BatakLanguages, + + [Language(LongName = "Berber languages", ThreeLetterCode = "ber")] + BerberLanguages, + + [Language(LongName = "Bihari languages", TwoLetterCode = "bh", ThreeLetterCode = "bih")] + BihariLanguages, + + [Language(LongName = "Caucasian languages", ThreeLetterCode = "cau")] + CaucasianLanguages, + + [Language(LongName = "Celtic languages", ThreeLetterCode = "cel")] + CelticLanguages, + + [Language(LongName = "Central American Indian languages", ThreeLetterCode = "cai")] + CentralAmericanIndianLanguages, + + [Language(LongName = "Chamic languages", ThreeLetterCode = "cmc")] + ChamicLanguages, + + [Language(LongName = "Cushitic languages", ThreeLetterCode = "cus")] + CushiticLanguages, + + [Language(LongName = "Dravidian languages", ThreeLetterCode = "dra")] + DravidianLanguages, + + [Language(LongName = "Finno-Ugrian languages", ThreeLetterCode = "fiu")] + FinnoUgrianLanguages, + + [Language(LongName = "Germanic languages", ThreeLetterCode = "gem")] + GermanicLanguages, + + [Language(LongName = "Himachali languages; Western Pahari languages", ThreeLetterCode = "him")] + HimachaliLanguages, + + [Language(LongName = "Ijo languages", ThreeLetterCode = "ijo")] + IjoLanguages, + + [Language(LongName = "Indic languages", ThreeLetterCode = "inc")] + IndicLanguages, + + [Language(LongName = "Indo-European languages", ThreeLetterCode = "ine")] + IndoEuropeanLanguages, + + [Language(LongName = "Iranian languages", ThreeLetterCode = "ira")] + IranianLanguages, + + [Language(LongName = "Iroquoian languages", ThreeLetterCode = "iro")] + IroquoianLanguages, + + [Language(LongName = "Karen languages", ThreeLetterCode = "kar")] + KarenLanguages, + + [Language(LongName = "Khoisan languages", ThreeLetterCode = "khi")] + KhoisanLanguages, + + [Language(LongName = "Kru languages", ThreeLetterCode = "kro")] + KruLanguages, + + [Language(LongName = "Land Dayak languages", ThreeLetterCode = "day")] + LandDayakLanguages, + + [Language(LongName = "Manobo languages", ThreeLetterCode = "mno")] + ManoboLanguages, + + [Language(LongName = "Mayan languages", ThreeLetterCode = "myn")] + MayanLanguages, + + [Language(LongName = "Mon-Khmer languages", ThreeLetterCode = "mkh")] + MonKhmerLanguages, + + // Commented out to avoid confusion + //[Language(LongName = "Multiple languages", ThreeLetterCode = "mul")] + //MultipleLanguages, + + [Language(LongName = "Munda languages", ThreeLetterCode = "mun")] + MundaLanguages, + + [Language(LongName = "Nahuatl languages", ThreeLetterCode = "nah")] + NahuatlLanguages, + + [Language(LongName = "Niger-Kordofanian languages", ThreeLetterCode = "nic")] + NigerKordofanianLanguages, + + [Language(LongName = "Nilo-Saharan languages", ThreeLetterCode = "ssa")] + NiloSaharanLanguages, + + [Language(LongName = "North American Indian languages", ThreeLetterCode = "nai")] + NorthAmericanIndianLanguages, + + [Language(LongName = "Nubian languages", ThreeLetterCode = "nub")] + NubianLanguages, + + [Language(LongName = "Otomian languages", ThreeLetterCode = "oto")] + OtomianLanguages, + + [Language(LongName = "Papuan languages", ThreeLetterCode = "paa")] + PapuanLanguages, + + [Language(LongName = "Philippine languages", ThreeLetterCode = "phi")] + PhilippineLanguages, + + [Language(LongName = "Prakrit languages", ThreeLetterCode = "pra")] + PrakritLanguages, + + [Language(LongName = "Romance languages", ThreeLetterCode = "roa")] + RomanceLanguages, + + [Language(LongName = "Salishan languages", ThreeLetterCode = "sal")] + SalishanLanguages, + + [Language(LongName = "Sami languages", ThreeLetterCode = "smi")] + SamiLanguages, + + [Language(LongName = "Semitic languages", ThreeLetterCode = "sem")] + SemiticLanguages, + + [Language(LongName = "Sino-Tibetan languages", ThreeLetterCode = "sit")] + SinoTibetanLanguages, + + [Language(LongName = "Siouan languages", ThreeLetterCode = "sio")] + SiouanLanguages, + + [Language(LongName = "Slavic languages", ThreeLetterCode = "sla")] + SlavicLanguages, + + [Language(LongName = "Songhai languages", ThreeLetterCode = "son")] + SonghaiLanguages, + + [Language(LongName = "Sorbian languages", ThreeLetterCode = "wen")] + SorbianLanguages, + + [Language(LongName = "South American Indian languages", ThreeLetterCode = "sai")] + SouthAmericanIndianLanguages, + + [Language(LongName = "Tai languages", ThreeLetterCode = "tai")] + TaiLanguages, + + [Language(LongName = "Tupi languages", ThreeLetterCode = "tup")] + TupiLanguages, + + [Language(LongName = "Uncoded languages", ThreeLetterCode = "mis")] + UncodedLanguages, + + [Language(LongName = "Wakashan languages", ThreeLetterCode = "wak")] + WakashanLanguages, + + [Language(LongName = "Yupik languages", ThreeLetterCode = "ypk")] + YupikLanguages, + + [Language(LongName = "Zande languages", ThreeLetterCode = "znd")] + ZandeLanguages, + */ + + #endregion + } + /// /// List of all media types /// diff --git a/SabreTools.RedumpLib/RedumpInfo/Data/Extensions.cs b/SabreTools.RedumpLib/RedumpInfo/Data/Extensions.cs index 343f8dc..2e00de4 100644 --- a/SabreTools.RedumpLib/RedumpInfo/Data/Extensions.cs +++ b/SabreTools.RedumpLib/RedumpInfo/Data/Extensions.cs @@ -1037,6 +1037,128 @@ namespace SabreTools.RedumpLib.RedumpInfo.Data #endregion + #region Language + + /// + /// Get the Redump longnames for each known language + /// + public static string? LongName(this Language language) + => ((Language?)language).LongName(); + + /// + /// Get the Redump longnames for each known language + /// + public static string? LongName(this Language? language) + => AttributeHelper.GetHumanReadableAttribute(language)?.LongName; + + /// + /// Get the Redump shortnames for each known language + /// + public static string? ShortName(this Language language) + => ((Language?)language).ShortName(); + + /// + /// Get the Redump shortnames for each known language + /// + public static string? ShortName(this Language? language) + { + // Some languages need to use the alternate code instead +#pragma warning disable IDE0072 // Add missing cases + return language switch + { + Language.Albanian + or Language.Armenian + or Language.Icelandic + or Language.Macedonian + or Language.Romanian + or Language.Slovak => language.ThreeLetterCodeAlt(), + _ => language.ThreeLetterCode(), + }; +#pragma warning restore IDE0072 // Add missing cases + } + + /// + /// Get the Language enum value for a given string + /// + /// String value to convert + /// Language represented by the string, if possible + public static Language? ToLanguage(this string? lang) + { + // No value means no match + if (lang is null || lang.Length == 0) + return null; + + lang = lang.ToLowerInvariant(); + var languages = (Language[])Enum.GetValues(typeof(Language)); + + // Check ISO 639-1 codes + int index = Array.FindIndex(languages, l => lang == l.TwoLetterCode()); + if (index > -1) + return languages[index]; + + // Check standard ISO 639-2 codes + index = Array.FindIndex(languages, l => lang == l.ThreeLetterCode()); + if (index > -1) + return languages[index]; + + // Check alternate ISO 639-2 codes + index = Array.FindIndex(languages, l => lang == l.ThreeLetterCodeAlt()); + if (index > -1) + return languages[index]; + + return null; + } + + /// + /// Get the ISO 639-2 code for each known language + /// + /// + /// + public static string? ThreeLetterCode(this Language language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.ThreeLetterCode; + + /// + /// Get the ISO 639-2 code for each known language + /// + /// + /// + public static string? ThreeLetterCode(this Language? language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.ThreeLetterCode; + + /// + /// Get the ISO 639-2 alternate code for each known language + /// + /// + /// + public static string? ThreeLetterCodeAlt(this Language language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.ThreeLetterCodeAlt; + + /// + /// Get the ISO 639-2 alternate code for each known language + /// + /// + /// + public static string? ThreeLetterCodeAlt(this Language? language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.ThreeLetterCodeAlt; + + /// + /// Get the ISO 639-1 code for each known language + /// + /// + /// + public static string? TwoLetterCode(this Language language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.TwoLetterCode; + + /// + /// Get the ISO 639-1 code for each known language + /// + /// + /// + public static string? TwoLetterCode(this Language? language) + => (AttributeHelper.GetHumanReadableAttribute(language) as LanguageAttribute)?.TwoLetterCode; + + #endregion + #region Media Type ///