From 7b1c4dbf90f5181fa8d970aa3d9bd7084265f470 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Wed, 17 Jul 2024 16:25:20 -0700 Subject: [PATCH 01/26] Add known issues result type to verification (#253) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Adding known issues to reports * Fixing comment * removing extra file * Structured for known issues in reports * Updated summary page with known issues color * Fix typo * Fixes to testreports --- verifier/detail_template.html | 64 +++++++++-- verifier/report_template.py | 16 ++- verifier/summary_template.html | 8 +- verifier/testreport.py | 200 ++++++++++++++++++++++++--------- verifier/verifier.py | 1 - 5 files changed, 224 insertions(+), 65 deletions(-) diff --git a/verifier/detail_template.html b/verifier/detail_template.html index 0a0f7db4..9c89cae4 100644 --- a/verifier/detail_template.html +++ b/verifier/detail_template.html @@ -84,6 +84,8 @@ .class_error tr:hover {background-color: #ffdd00;} .class_unsupported th {background-color: #777777;} .class_unsupported tr:hover {background-color: #dddddd;} +.class_known_issue th {background-color: #dd8200;} +.class_known_issue tr:hover {background-color: #dd8200;} .class_selected_fails th {background-color: #0000ee;} @@ -142,7 +144,18 @@ widget_label_sets: [], box_labels: [], selected_set: null, + }, + 'known_issue': { + json: null, + all_labels: new Set(), + count: 0, + characterized: null, + check_boxes: [], + widget_label_sets: [], + box_labels: [], + selected_set: null, } + }; // Get the JSON data from the tests. @@ -153,11 +166,13 @@ let p2 = fetch('./failing_tests.json'); let p3 = fetch('./test_errors.json'); let p4 = fetch('./unsupported.json'); + let p5 = fetch('./known_issues.json'); let p_pass_char = fetch('./pass_characterized.json'); let p_fail_char = fetch('./fail_characterized.json'); let p_error_char = fetch('./error_characterized.json') let p_unsupported_char = fetch('./unsupported_characterized.json') + let p_known_issue_char = fetch('./known_issues_characterized.json') // Synchronize all the data loading and charts / pagination Promise.all([ @@ -173,8 +188,12 @@ p4.then((response) => response.json()) .then((data) => { test_results['unsupported'].json = data}), - - // TODO: Make a separate promise.all for this? + p5.then((response) => response.json()) + .then((data) => { + test_results['known_issue'].json = data}), + + + // TODO: Make a separate promise.all for this? p_pass_char.then((response) => response.json()) .then((data) => { test_results['pass'].characterized = data}), @@ -187,11 +206,14 @@ p_unsupported_char.then((response) => response.json()) .then((data) => { test_results['unsupported'].characterized = data}), + p_known_issue_char.then((response) => response.json()) + .then((data) => { + test_results['known_issue'].characterized = data}), new Promise((resolve, reject) => { $(document).ready(resolve); }) - ]).then(([p1, p2, p3, p4, _ready]) => { + ]).then(([p1, p2, p3, p4, p5, _ready]) => { // Load the Visualization API and the corechart package. google.charts.load('current', {'packages':['corechart']}); // Set a callback to run when the Google Visualization API is loaded. @@ -210,8 +232,9 @@ ['Passing', test_results['pass'].json.length, '#44ff77'], ['Failing', test_results['fail'].json.length, '#ff0000'], ['Errors', test_results['error'].json.length, '#ffdd00'], - ['Unsupported', test_results['unsupported'].json.length, '#777777'] - ]; + ['Unsupported', test_results['unsupported'].json.length, '#777777'], + ['Known issues', test_results['known_issue'].json.length, '#ff8200'] + ]; const chart = new google.visualization.BarChart(chart_output_area); let chart_data = google.visualization.arrayToDataTable(input_data); if (chart && chart_data) { @@ -368,7 +391,7 @@ function onloadFn() { // Set up for pagination of each set of results // Do this for each class of results. - const container_types = ['pass', 'fail', 'error', 'unsupported']; + const container_types = ['pass', 'fail', 'error', 'unsupported', 'known_issue']; let total_summary_count = 0; for (c_type of container_types) { let container_type = c_type; @@ -416,6 +439,7 @@ create_widget_area('fail', create_tristate_area); create_widget_area('error', create_tristate_area); create_widget_area('unsupported', create_tristate_area); + create_widget_area('known_issue', create_tristate_area); } function fill_pagination(pagination_container_name, @@ -648,7 +672,8 @@

$platform_info

$total_tests attempted. Pass: $passing_tests, Fail: $failing_tests, Errors: $error_count, - Unsupported: $unsupported

+ Unsupported: $unsupported, + Known issues: $unsupported

@@ -767,6 +792,31 @@

Test Errors ($error_count)

+ +
+ Known issues ($known_issue_count) +
+
+
+
+ Known issues characterized +
+
+

Filtered count = 0 + + +

+
+
+
+
+
+
+
+
+
+
+
diff --git a/verifier/report_template.py b/verifier/report_template.py index cc48b62a..e9b7b6af 100644 --- a/verifier/report_template.py +++ b/verifier/report_template.py @@ -45,12 +45,20 @@ def __init__(self): self.unsupported_table_template = Template( """ - $test_unsupported_table
LabelUnsupported messageDetailsInput data
""") + self.known_issue_table_template = Template( + """ + + + $test_unknown_issue_table +
Labelknown_issue messageDetailsInput data
+ """) self.fail_line_template = Template( '$label$expected$result$input_data' ) @@ -66,8 +74,6 @@ def __init__(self): self.summary_table_template = Template( """ - $table_content
$typeCount
""") @@ -76,6 +82,10 @@ def __init__(self): '$label$unsupported$error_detail$input_data' ) + self.test_known_issue_template = Template( + '$labelknown_issue$error_detail$input_data' + ) + # Template for test failures - will be replaced by html generated in detail_template.html self.checkbox_option_template = Template( '
' diff --git a/verifier/summary_template.html b/verifier/summary_template.html index c8d859a5..38593b5e 100644 --- a/verifier/summary_template.html +++ b/verifier/summary_template.html @@ -140,6 +140,7 @@ let table = document.getElementById('exec_summary_table') let data_groups = ['Result', 'Pass', 'Fail', 'Error', 'Unsupported', + 'known_issue', {role: 'annotation'}]; // Get all the types of tests available @@ -155,7 +156,6 @@ const tests = exec_summary_json[test_type]; for (const node_version of tests) { exec_set.add(node_version['version']['platform']) -// exec_set.add(node_version['exec']); } } @@ -187,7 +187,6 @@ let details = []; for (const report of tests) { if (report['version']['platform'] == exec) { -// if (report['exec'] == exec) { reports.push(report); // Add data for this report. const version_label = report['version']['platformVersion'] + @@ -195,11 +194,11 @@ report['version']['icuVersion']; const report_data = [ version_label, - // report['exec_version'], report['pass_count'], report['fail_count'], report['error_count'], report['unsupported_count'], + report['known_issue_count'], '' ]; data.push(report_data); @@ -224,7 +223,8 @@ 0: {color:'#00dd77'}, // Passing 1: {color:'#dd0000'}, // Failing 2: {color:'#ffdd00'}, // Error - 3: {color: '#777777'} // + 3: {color: '#777777'}, // Unsupported + 4: {color: '#ff8200'} // Known issue (UTK orange) }, }; // Set up options and links diff --git a/verifier/testreport.py b/verifier/testreport.py index 3be8f973..a8071e37 100644 --- a/verifier/testreport.py +++ b/verifier/testreport.py @@ -41,6 +41,17 @@ def sort_dict_by_count(dict_data): key=lambda item: len(item[1]), reverse=True) +class result_class_data(): + # Claas containing results for a type or result, e.g., + # for passing, failing, error, unsupported, known_issue + def __init__(self, class_name, test_template, summary_template, result_table_template, compute_fn): + self.name = class_name + self.test_template = test_template, + self.summary_template = summary_template + self.result_table_template = result_table_template + self.summary_compute_fn = compute_fn + + class DiffSummary: def __init__(self): self.single_diffs = {} @@ -101,34 +112,72 @@ def __init__(self, report_path, report_html_path): self.test_errors = [] self.unsupported_cases = [] - self.test_type = None - self.exec = None - self.library_name = None - - self.platform = None - - self.missing_verify_data = [] - - self.diff_summary = DiffSummary() - - templates = reportTemplate() - self.templates = templates - - self.differ = Differ() + self.templates = templates = reportTemplate() # For a simple template replacement self.report_html_template = templates.reportOutline() self.error_table_template = templates.error_table_template self.test_error_summary_template = templates.test_error_summary_template + self.test_error_detail_template = templates.test_error_detail_template self.unsupported_table_template = templates.unsupported_table_template + self.unsupported_summary_template = templates.unsupported_table_template + + self.known_issue_table_template = templates.known_issue_table_template + self.known_issue_summary_template = templates.known_issue_table_template self.fail_line_template = templates.fail_line_template - self.test_error_detail_template = templates.test_error_detail_template - self.test_unsupported_template = templates.test_unsupported_template + self.passing_data = result_class_data( + 'passing', + None, + None, + None, + None) + + self.failing_data = result_class_data( + 'failing', + None, + templates.fail_line_template, + templates.test_error_summary_template, + None) + + self.error_data = result_class_data( + 'errors', + None, + templates.error_table_template, + templates.test_error_summary_template, + self.compute_test_error_summary) + + self.unsupported_data = result_class_data( + 'unsupported', + None, # ??self.test_unsupported_template, + self.test_error_summary_template, + templates.unsupported_table_template, + self.compute_unsupported_category_summary) + + self.known_issue_data = result_class_data( + 'known_issues', + None, + None, # ?? templates.known_issue_table_template, + templates.known_issue_table_template, + self.compute_known_issue_category_summary) + + self.known_issues = [] + + self.test_type = None + self.exec = None + self.library_name = None + + self.platform = None + + self.missing_verify_data = [] + + self.diff_summary = DiffSummary() + + self.differ = Differ() logging.config.fileConfig("../logging.conf") @@ -204,6 +253,11 @@ def compute_unsupported_category_summary(self, unsupported_cases, group_tag): groups[value] = [label] return groups + def compute_known_issue_category_summary(selfself, cases, group_tag): + # TODO: Fill in for known issues + groups = {} + return groups + def create_report(self): # Make a JSON object with the data report = {} @@ -233,6 +287,7 @@ def create_report(self): report['test_errors'] = self.test_errors report['unsupported'] = self.unsupported_cases + report['known_issues'] = self.known_issues self.report = report return json.dumps(report) @@ -259,7 +314,9 @@ def create_json_report_tree(self): categories = {'pass': self.passing_tests, 'failing_tests': self.failing_tests, 'test_errors': self.test_errors, - 'unsupported': self.unsupported_cases} + 'unsupported': self.unsupported_cases, + 'known_issues': self.known_issues + } for category, case_list in categories.items(): dir_name = self.report_directory # Put .json files in the same directory as the .html for the detail report @@ -329,7 +386,9 @@ def create_html_report(self): 'passing_tests': len(self.passing_tests), 'failing_tests': len(self.failing_tests), 'error_count': len(self.test_errors), - 'unsupported_count': len(self.unsupported_cases) + 'unsupported_count': len(self.unsupported_cases), + 'known_issue_count': len(self.known_issues) + # ... } @@ -362,6 +421,11 @@ def create_html_report(self): flat_combined_unsupported = self.flatten_and_combine(unsupported_characterized, None) self.save_characterized_file(flat_combined_unsupported, "unsupported") + + known_issues_characterized = self.characterize_failures_by_options(self.known_issues) + flat_combined_known_issues = self.flatten_and_combine(known_issues_characterized, None) + self.save_characterized_file(flat_combined_known_issues, "known_issues") + # TODO: Should we compute top 3-5 overlaps for each set? # Flatten and combine the dictionary values fail_characterized = self.characterize_failures_by_options(self.failing_tests) @@ -426,37 +490,19 @@ def create_html_report(self): html_map['error_section'] = 'No test errors found' html_map['error_summary'] = '' - unsupported_lines = [] - if self.unsupported_cases: - # Create a table of all test errors. - for unsupported in self.unsupported_cases: - line = self.test_unsupported_template.safe_substitute(unsupported) - unsupported_lines.append(line) - - unsupported_line_data = '\n'.join(unsupported_lines) - html_map['unsupported_section'] = self.unsupported_table_template.safe_substitute( - {'test_unsupported_table': unsupported_line_data} - ) - unsupported_summary = self.compute_unsupported_category_summary( - self.unsupported_cases, - 'unsupported_options') - - unsupported_summary_lines = [] - for key, labels in unsupported_summary.items(): - count = len(labels) - sub = {'error': key, 'count': count} - unsupported_summary_lines.append( - self.test_error_summary_template.safe_substitute(sub) - ) - unsupported_table = self.templates.summary_table_template.safe_substitute( - {'table_content': '\n'.join(unsupported_summary_lines), - 'type': 'Unsupported options'} - ) - - html_map['unsupported_summary'] = unsupported_table - else: - html_map['unsupported_section'] = 'No unsupported tests found' - html_map['unsupported_summary'] = '' + # Bundle these things in one class for each type of result + self.fill_templates(self.unsupported_data, + self.unsupported_cases, + self.unsupported_table_template, + self.unsupported_summary_template, + html_map + ) + self.fill_templates(self.known_issue_data, + self.known_issues, + self.known_issue_table_template, + self.known_issue_summary_template, + html_map + ) # For each failed test base, add an HTML table element with the info html_output = self.report_html_template.safe_substitute(html_map) @@ -553,7 +599,7 @@ def characterize_failures_by_options(self, failing_tests): results[k][value] = set() results[k][value].add(label) - # Try fields in language_names + # Try fields in lang_names for key in ['language_label', 'locale_label']: try: if input_data.get(key): @@ -904,6 +950,51 @@ def find_replacements_diff(self, s1, s2): index += 1 return diff_count, diffs, last_diff + def fill_templates(self, result_data, result_cases, result_table_template, summary_template, html_map): + # For filling in templates for cases of passing, failing, errors, unsupported, known_issue + result_class = result_data.name + section_name = '%s_section' % result_class + summary_name = '%s_summary % result_class' + + # TODO: Call this for each cases instead of duplicated lines + if result_cases: + case_lines = [] + test_table_name = 'test_%s_' % result_class + options_name = '%s_options' % result_class + options_string = '%s options' % result_class + + # Create a table of all test errors. + for unsupported in result_cases: + line = result_data.result_table_template.safe_substitute(unsupported) + case_lines.append(line) + + case_line_data = '\n'.join(case_lines) + html_map[section_name] = result_data.result_table_template.safe_substitute( + {test_table_name: case_line_data} + ) + + case_summary = {} + if result_data.summary_compute_fn: + case_summary = result_data.summary_compute_fn(result_cases, options_name) + + summary_lines = [] + # ??? TODO: examine if "error" is correct below + for key, labels in case_summary.items(): + count = len(labels) + sub = {'error': key, 'count': count} + summary_lines.append( + result_data.summary_template.safe_substitute(sub) + ) + case_table = result_data.summary_template.safe_substitute( + {'table_content': '\n'.join(summary_lines), + 'type': options_string} + ) + + html_map[summary_name] = case_table + else: + html_map[section_name] = 'No %s tests found' % result_class + html_map[summary_name] = '' + def take_second(elem): return elem[1] @@ -991,6 +1082,7 @@ def summarize_reports(self): icu_version = os.path.basename(os.path.dirname(dir_path)) results = defaultdict(lambda: defaultdict(list)) test_type = None + test_results = {} try: executor = test_environment['test_language'] test_type = test_environment['test_type'] @@ -1018,6 +1110,13 @@ def summarize_reports(self): 'icu_version': icu_version, 'platform_version': '%s %s' % (platform['platform'], platform['platformVersion']) } + + # Handle this sepparately for now as we add known issue support + try: + test_results['known_issue_count'] = len(test_json['known_issue']) + except BaseException as err: + test_results['known_issue_count'] = 0 + except BaseException as err: logging.error('SUMMARIZE REPORTS for file %s. Error: %s' % (filename, err)) @@ -1147,6 +1246,7 @@ def create_summary_html(self): exec_json_file = open(exec_summary_json_path, mode='w', encoding='utf-8') summary_by_test_type = json.dumps(self.summary_by_test_type) exec_json_file.write(summary_by_test_type) + os.fsync(exec_json_file) exec_json_file.close() except BaseException as err: sys.stderr.write('!!! %s: Cannot write exec_summary.json' % err) diff --git a/verifier/verifier.py b/verifier/verifier.py index ebabdff8..7df28707 100644 --- a/verifier/verifier.py +++ b/verifier/verifier.py @@ -213,7 +213,6 @@ def setup_verify_plans(self): new_verify_plan.set_exec(executor) new_verify_plan.set_report(new_report) - # Is this test needed? if os.path.isfile(new_verify_plan.result_path): self.verify_plans.append(new_verify_plan) From 7b85aa1e6474d8fb88a317a219247884f2394cee Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 25 Jul 2024 15:05:29 -0700 Subject: [PATCH 02/26] message_fmt2: Update error types in schema (#254) Update the error list in testgen_schema.json to match the schema in the MFWG spec repo, https://github.com/unicode-org/message-format-wg/blob/main/test/schemas/v0/tests.schema.json Also update function tests to match the schema (just copied the tests from the current MFWG spec repo). --- schema/message_fmt2/testgen_schema.json | 11 ++-- .../functions/date.json | 4 +- .../functions/datetime.json | 6 +-- .../functions/number.json | 50 ++++++------------- .../functions/time.json | 4 +- 5 files changed, 27 insertions(+), 48 deletions(-) diff --git a/schema/message_fmt2/testgen_schema.json b/schema/message_fmt2/testgen_schema.json index e3f9e6e4..9ea4d24e 100644 --- a/schema/message_fmt2/testgen_schema.json +++ b/schema/message_fmt2/testgen_schema.json @@ -351,12 +351,11 @@ "unresolved-variable", "unknown-function", "unsupported-expression", - "invalid-expression", - "operand-mismatch", - "unsupported-statement", - "selection-error", - "formatting-error", - "bad-input" + "bad-selector", + "bad-operand", + "bad-option", + "bad-variant-key", + "unsupported-statement" ] } } diff --git a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/date.json b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/date.json index 472b46d8..8252ab8b 100644 --- a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/date.json +++ b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/date.json @@ -11,7 +11,7 @@ "exp": "{:date}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -20,7 +20,7 @@ "exp": "{|horse|}", "expErrors": [ { - "type": "operand-mismatch" + "type": "bad-operand" } ] }, diff --git a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/datetime.json b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/datetime.json index 18e0cd97..677a3853 100644 --- a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/datetime.json +++ b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/datetime.json @@ -11,7 +11,7 @@ "exp": "{:datetime}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -26,7 +26,7 @@ ], "expErrors": [ { - "type": "bad-input" + "type": "bad-operand" } ] }, @@ -35,7 +35,7 @@ "exp": "{|horse|}", "expErrors": [ { - "type": "operand-mismatch" + "type": "bad-operand" } ] }, diff --git a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/number.json b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/number.json index 515600c4..dc552d32 100644 --- a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/number.json +++ b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/number.json @@ -22,34 +22,34 @@ "exp": "hello {|foo|}", "expErrors": [ { - "type": "operand-mismatch" + "type": "bad-operand" } ] }, { - "src": "invalid number literal {.1 :number}", + "src": "invalid number literal {|.1| :number}", "exp": "invalid number literal {|.1|}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, { - "src": "invalid number literal {1. :number}", + "src": "invalid number literal {|1.| :number}", "exp": "invalid number literal {|1.|}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, { - "src": "invalid number literal {01 :number}", + "src": "invalid number literal {|01| :number}", "exp": "invalid number literal {|01|}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -58,16 +58,16 @@ "exp": "invalid number literal {|+1|}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, { - "src": "invalid number literal {0x1 :number}", + "src": "invalid number literal {|0x1| :number}", "exp": "invalid number literal {|0x1|}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -76,7 +76,7 @@ "exp": "hello {:number}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -139,7 +139,7 @@ "exp": "bar {$bar}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-option" } ] }, @@ -154,7 +154,7 @@ "exp": "bar {$bar}", "expErrors": [ { - "type": "bad-input" + "type": "bad-operand" } ] }, @@ -189,7 +189,7 @@ "exp": "bar {$foo}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-option" } ] }, @@ -204,7 +204,7 @@ "exp": "bar {$foo}", "expErrors": [ { - "type": "bad-input" + "type": "bad-operand" } ] }, @@ -340,26 +340,6 @@ ], "exp": "other" }, - { - "src": ".input {$bar} .match {$bar :number} one {{one}} * {{other}}", - "params": [ - { - "name": "bar", - "value": 1 - } - ], - "exp": "one" - }, - { - "src": ".input {$bar} .match {$bar :number} one {{one}} * {{other}}", - "params": [ - { - "name": "bar", - "value": 2 - } - ], - "exp": "other" - }, { "src": ".input {$none} .match {$foo :number} one {{one}} * {{{$none}}}", "params": [ diff --git a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/time.json b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/time.json index 4c5dd22b..201f8fad 100644 --- a/testgen/icu75/message_fmt2/message-format-wg-tests/functions/time.json +++ b/testgen/icu75/message_fmt2/message-format-wg-tests/functions/time.json @@ -11,7 +11,7 @@ "exp": "{:time}", "expErrors": [ { - "type": "invalid-expression" + "type": "bad-operand" } ] }, @@ -20,7 +20,7 @@ "exp": "{|horse|}", "expErrors": [ { - "type": "operand-mismatch" + "type": "bad-operand" } ] }, From 1ff237c9b089736917f9d18b0d494cd50876d7b9 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 26 Jul 2024 08:52:07 -0700 Subject: [PATCH 03/26] message_fmt2: Add more properties to schema (#255) * message_fmt2: Add more properties to schema Add properties to schema that are used in ICU tests: 'char', 'line', 'comment', 'srcs', 'ignoreJava', and 'ignoreCpp' * message_fmt2: Eliminate `srcs` from schema Allow `src` to be either a string or array of strings, and remove `srcs` * Fix type of `tests` property * Fix comment --- schema/message_fmt2/testgen_schema.json | 63 +++++++++++++++++++++---- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/schema/message_fmt2/testgen_schema.json b/schema/message_fmt2/testgen_schema.json index 9ea4d24e..a329bd34 100644 --- a/schema/message_fmt2/testgen_schema.json +++ b/schema/message_fmt2/testgen_schema.json @@ -68,14 +68,15 @@ }, { "properties": { - "tests": { - "type": "array", - "items": { - "required": [ - "src" + "tests": { + "$comment": "type: array provided for clarity only", + "type": "array", + "items": { + "required": [ + "src" ] - } - } + } + } } } ] @@ -148,6 +149,9 @@ "params": { "$ref": "#/$defs/params" }, + "comment": { + "$ref": "#/$defs/comment" + }, "exp": { "$ref": "#/$defs/exp" }, @@ -160,6 +164,18 @@ "expErrors": { "$ref": "#/$defs/expErrors" }, + "ignoreCpp": { + "$ref": "#/$defs/ignoreCpp" + }, + "ignoreJava": { + "$ref": "#/$defs/ignoreJava" + }, + "char": { + "$ref": "#/$defs/char" + }, + "line": { + "$ref": "#/$defs/line" + }, "only": { "type": "boolean", "description": "Normally not set. A flag to use during development to only run one or more specific tests." @@ -171,8 +187,17 @@ "type": "string" }, "src": { - "description": "The MF2 syntax source.", - "type": "string" + "oneOf": [ + { + "description": "The MF2 syntax source.", + "type": "string" + }, + { + "description": "The MF2 syntax source, as an array of strings to be concatenated.", + "type": "array", + "items": { "type": "string" } + } + ] }, "params": { "description": "Parameters to pass in to the formatter for resolving external variables.", @@ -219,6 +244,10 @@ } ] }, + "comment": { + "description": "A human-readable comment, meant to be ignored by the test runner", + "type": "string" + }, "exp": { "description": "The expected result of formatting the message to a string.", "type": "string" @@ -361,6 +390,22 @@ } } }, + "ignoreCpp": { + "description": "If present, ignore this test when testing ICU4C. The string is an explanation of why the test doesn't pass.", + "type": "string" + }, + "ignoreJava": { + "description": "If present, ignore this test when testing ICU4J. The string is an explanation of why the test doesn't pass.", + "type": "string" + }, + "char": { + "description": "Optional character offset that should appear in syntax error. Only used by ICU4C currently", + "type": "number" + }, + "line": { + "description": "Optional line number that should appear in syntax error. Only used by ICU4C currently", + "type": "number" + }, "anyExp": { "anyOf": [ { From eec52087a7ae74b7ddbc338741dfcca459de6fc2 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 1 Aug 2024 16:45:47 -0700 Subject: [PATCH 04/26] Adding ICU4J list format tests (#258) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Add ICU4J list format tests * Get rid of extra file * Implement enums for style and list_type --- .../unicode/conformance/Icu4jExecutor.java | 3 + .../conformance/testtype/ITestType.java | 4 +- .../listformatter/ListFormatterInputJson.java | 20 ++++ .../ListFormatterOutputJson.java | 16 +++ .../listformatter/ListFormatterTester.java | 113 ++++++++++++++++++ .../listformatter/ListFormatterType.java | 17 +++ .../listformatter/ListFormatterWidth.java | 17 +++ .../listformatter/ListFormatterTest.java | 43 +++++++ run_config.json | 1 + 9 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterOutputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterType.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterWidth.java create mode 100644 executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java index 9c327ecc..41a9aca3 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java @@ -14,6 +14,7 @@ import org.unicode.conformance.testtype.collator.CollatorTester; import org.unicode.conformance.testtype.langnames.LangNamesTester; import org.unicode.conformance.testtype.likelysubtags.LikelySubtagsTester; +import org.unicode.conformance.testtype.listformatter.ListFormatterTester; import org.unicode.conformance.testtype.messageformat2.MessageFormatTester; import org.unicode.conformance.testtype.numberformatter.NumberFormatterTester; @@ -122,6 +123,8 @@ public static String getTestCaseResponse(String inputLine) throws Exception { testType = LangNamesTester.INSTANCE; } else if (testTypeStr.equals("likely_subtags")) { testType = LikelySubtagsTester.INSTANCE; + } else if (testTypeStr.equals("list_fmt")) { + testType = ListFormatterTester.INSTANCE; } else if (testTypeStr.equals("number_fmt")) { testType = NumberFormatterTester.INSTANCE; } else if (testTypeStr.equals("message_fmt2")) { diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/ITestType.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/ITestType.java index 97081ec4..f20cad6b 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/ITestType.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/ITestType.java @@ -13,9 +13,9 @@ default io.lacuna.bifurcan.Map parseInput(String inputLine) { default ITestTypeInputJson parseInputJson(String inputLine) { io.lacuna.bifurcan.Map inputMapData = parseInput(inputLine); - ITestTypeInputJson inputJson = inputMapToJson(inputMapData); + ITestTypeInputJson inputJson = inputMapToJson(inputMapData); - return inputJson; + return inputJson; } ITestTypeOutputJson execute(ITestTypeInputJson inputJson); diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java new file mode 100644 index 00000000..e1052fcd --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java @@ -0,0 +1,20 @@ +package org.unicode.conformance.testtype.listformatter; + +import java.util.Collection; +import org.unicode.conformance.testtype.ITestTypeInputJson; + +public class ListFormatterInputJson implements ITestTypeInputJson { + + public String test_type; + + public String label; + + public String locale; + + public ListFormatterType list_type; + + public ListFormatterWidth style; // e.g., SHORT + + public Collection input_list; + +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterOutputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterOutputJson.java new file mode 100644 index 00000000..7e96c201 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterOutputJson.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.listformatter; + +import org.unicode.conformance.testtype.ITestTypeOutputJson; + +public class ListFormatterOutputJson implements ITestTypeOutputJson { + + public String test_type; + + public String label; + + public String result; + + public String error; + + public String error_message; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java new file mode 100644 index 00000000..c68e18ec --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java @@ -0,0 +1,113 @@ +package org.unicode.conformance.testtype.listformatter; + +import com.ibm.icu.util.ULocale; +import com.ibm.icu.text.ListFormatter.Type; +import com.ibm.icu.text.ListFormatter.Width; +import com.ibm.icu.text.ListFormatter; + +import io.lacuna.bifurcan.IMap; +import io.lacuna.bifurcan.Map; + +import java.util.Collection; + +import java.util.HashMap; +import org.unicode.conformance.ExecutorUtils; +import org.unicode.conformance.testtype.ITestType; +import org.unicode.conformance.testtype.ITestTypeInputJson; +import org.unicode.conformance.testtype.ITestTypeOutputJson; +import org.unicode.conformance.testtype.numberformatter.NumberFormatterTestOptionKey; +import org.unicode.conformance.testtype.numberformatter.StyleVal; + +public class ListFormatterTester implements ITestType { + + public static ListFormatterTester INSTANCE = new ListFormatterTester(); + + @Override + public ITestTypeInputJson inputMapToJson(Map inputMapData) { + ListFormatterInputJson result = new ListFormatterInputJson(); + + result.label = (String) inputMapData.get("label", null); + result.locale = (String) inputMapData.get("locale", null); + + java.util.Map input_options = (java.util.Map) inputMapData.get("options", null); + + result.list_type = ListFormatterType.getFromString( + "" + input_options.get("list_type") + ); + result.style = ListFormatterWidth.getFromString( + "" + input_options.get("style") + ); + + result.input_list = (Collection) inputMapData.get("input_list", null); + + return result; + } + + @Override + public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { + ListFormatterInputJson input = (ListFormatterInputJson) inputJson; + + // partially construct output + ListFormatterOutputJson output = (ListFormatterOutputJson) getDefaultOutputJson(); + output.label = input.label; + + try { + output.result = getListFormatResultString(input); + } catch (Exception e) { + output.error = e.getMessage(); + output.error_message = e.getMessage(); + return output; + } + + // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + return output; + } + + @Override + public ITestTypeOutputJson getDefaultOutputJson() { + return new ListFormatterOutputJson(); + } + + @Override + public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { + ListFormatterOutputJson output = (ListFormatterOutputJson) outputJson; + return new io.lacuna.bifurcan.Map() + .put("label", output.label) + .put("result", output.result); + } + + @Override + public String formatOutputJson(ITestTypeOutputJson outputJson) { + return ExecutorUtils.GSON.toJson((ListFormatterOutputJson) outputJson); + } + + public String getListFormatResultString(ListFormatterInputJson input) { + ListFormatter.Type list_type; + ListFormatter.Width list_width; + ULocale locale = ULocale.forLanguageTag(input.locale); + + switch (input.list_type) { + case DISJUNCTION: list_type = Type.OR; + break; + case UNIT: list_type = Type.UNITS; + break; + default: + case CONJUNCTION: list_type = Type.AND; + break; + } + + switch (input.style) { + case NARROW: list_width = Width.NARROW; + break; + case SHORT: list_width = Width.SHORT; + break; + default: + case LONG: list_width = Width.WIDE; + break; + } + + ListFormatter lf = ListFormatter.getInstance(locale, list_type, list_width); + + return lf.format(input.input_list); + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterType.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterType.java new file mode 100644 index 00000000..0590b6c3 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterType.java @@ -0,0 +1,17 @@ +package org.unicode.conformance.testtype.listformatter; + +public enum ListFormatterType { + CONJUNCTION, + DISJUNCTION, + UNIT; + + public static org.unicode.conformance.testtype.listformatter.ListFormatterType DEFAULT = CONJUNCTION; + + public static org.unicode.conformance.testtype.listformatter.ListFormatterType getFromString(String s) { + try { + return org.unicode.conformance.testtype.listformatter.ListFormatterType.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterWidth.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterWidth.java new file mode 100644 index 00000000..3982c0b7 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterWidth.java @@ -0,0 +1,17 @@ +package org.unicode.conformance.testtype.listformatter; + +public enum ListFormatterWidth { + NARROW, + SHORT, + LONG; + + public static org.unicode.conformance.testtype.listformatter.ListFormatterWidth DEFAULT = LONG; + + public static org.unicode.conformance.testtype.listformatter.ListFormatterWidth getFromString(String s) { + try { + return org.unicode.conformance.testtype.listformatter.ListFormatterWidth.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java new file mode 100644 index 00000000..a9fb512b --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java @@ -0,0 +1,43 @@ +package org.unicode.conformance.listformatter; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.unicode.conformance.testtype.listformatter.ListFormatterOutputJson; +import org.unicode.conformance.testtype.listformatter.ListFormatterTester; + +public class ListFormatterTest { + + @Test + public void testEnConjunction() { + String testInput = + "\t{\"input_list\":[\"dog\",\"cat\"],\"options\":{\"style\":\"long\",\"list_type\":\"conjunction\"},\"hexhash\":\"9cdda56a2d84e4cecd3f60d1a6f815ad36ea3df9\",\"label\":\"0\",\"locale\":\"en\"}"; + + ListFormatterOutputJson output = + (ListFormatterOutputJson) ListFormatterTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("dog and cat", output.result); + } + + @Test + public void testDeConjunction() { + String testInput = + "\t{\"input_list\":[\"katze\",\"hund\"],\"options\":{\"style\":\"long\",\"list_type\":\"disjunction\"},\"hexhash\":\"9cdda56a2d84e4cecd3f60d1a6f815ad36ea3df9\",\"label\":\"17\",\"locale\":\"de\"}"; + + ListFormatterOutputJson output = + (ListFormatterOutputJson) ListFormatterTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("katze oder hund", output.result); + } + + @Test + public void testUndUnit() { + String testInput = + "\t{\"input_list\":[\"dog\",\"cat\", \"fish\"],\"options\":{\"style\":\"long\",\"list_type\":\"unit\",\"type\":\"unit\"},\"hexhash\":\"8ea46dfaeb658975ff2f4f7ece1421a504eec5d7\",\"label\":\"18\",\"locale\":\"und\"}"; + + ListFormatterOutputJson output = + (ListFormatterOutputJson) ListFormatterTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("dog, cat, fish", output.result); + } +} diff --git a/run_config.json b/run_config.json index 5f5b3251..ebdb1daa 100644 --- a/run_config.json +++ b/run_config.json @@ -319,6 +319,7 @@ "collation_short", "lang_names", "likely_subtags", + "list_fmt", "number_fmt" ], "per_execution": 10000 From ce8f82e84f743c02a29e1005f8ea3f65be0b262e Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Fri, 2 Aug 2024 16:21:17 -0700 Subject: [PATCH 05/26] This adds plural rules testing to ICU4J (#259) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Add ICU4J list format tests * Get rid of extra file * Implement enums for style and list_type * Add ICU4J tests for plural rules * Update executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java Co-authored-by: Elango Cheran * Implementing ICU4J ListFormatter --------- Co-authored-by: Elango Cheran --- .../unicode/conformance/Icu4jExecutor.java | 3 + .../pluralrules/PluralRulesInputJson.java | 15 +++ .../pluralrules/PluralRulesOutputJson.java | 16 +++ .../pluralrules/PluralRulesTester.java | 98 +++++++++++++++++++ .../testtype/pluralrules/PluralRulesType.java | 16 +++ .../pluralrules/PluralRulesTest.java | 97 ++++++++++++++++++ run_config.json | 3 +- 7 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesOutputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesType.java create mode 100644 executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java index 41a9aca3..9a59cca0 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java @@ -17,6 +17,7 @@ import org.unicode.conformance.testtype.listformatter.ListFormatterTester; import org.unicode.conformance.testtype.messageformat2.MessageFormatTester; import org.unicode.conformance.testtype.numberformatter.NumberFormatterTester; +import org.unicode.conformance.testtype.pluralrules.PluralRulesTester; /** * Hello world! @@ -129,6 +130,8 @@ public static String getTestCaseResponse(String inputLine) throws Exception { testType = NumberFormatterTester.INSTANCE; } else if (testTypeStr.equals("message_fmt2")) { testType = MessageFormatTester.INSTANCE; + } else if (testTypeStr.equals("plural_rules")) { + testType = PluralRulesTester.INSTANCE; } else { io.lacuna.bifurcan.IMap response = parsedInputPersistentMap diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java new file mode 100644 index 00000000..e8898ac0 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java @@ -0,0 +1,15 @@ +package org.unicode.conformance.testtype.pluralrules; + +import org.unicode.conformance.testtype.ITestTypeInputJson; + +public class PluralRulesInputJson implements ITestTypeInputJson { + public String test_type; + + public String label; + + public String locale; + + public PluralRulesType plural_type; + + public double sample; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesOutputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesOutputJson.java new file mode 100644 index 00000000..c507969f --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesOutputJson.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.pluralrules; + +import org.unicode.conformance.testtype.ITestTypeOutputJson; + +public class PluralRulesOutputJson implements ITestTypeOutputJson { + + public String test_type; + + public String label; + + public String result; + + public String error; + + public String error_message; +} \ No newline at end of file diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java new file mode 100644 index 00000000..cac589b2 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java @@ -0,0 +1,98 @@ +package org.unicode.conformance.testtype.pluralrules; + +import com.ibm.icu.util.ULocale; +import com.ibm.icu.text.PluralRules.PluralType; +import com.ibm.icu.text.PluralRules; + +import io.lacuna.bifurcan.IMap; +import io.lacuna.bifurcan.Map; + +import java.util.Collection; + +import java.util.HashMap; +import org.unicode.conformance.ExecutorUtils; +import org.unicode.conformance.testtype.ITestType; +import org.unicode.conformance.testtype.ITestTypeInputJson; +import org.unicode.conformance.testtype.ITestTypeOutputJson; +import org.unicode.conformance.testtype.pluralrules.PluralRulesInputJson; +import org.unicode.conformance.testtype.pluralrules.PluralRulesOutputJson; + + +public class PluralRulesTester implements ITestType { + + public static PluralRulesTester INSTANCE = new PluralRulesTester(); + + public ITestTypeInputJson inputMapToJson(Map inputMapData) { + PluralRulesInputJson result = new PluralRulesInputJson(); + + result.label = (String) inputMapData.get("label", null); + result.locale = (String) inputMapData.get("locale", null); + + result.plural_type = PluralRulesType.getFromString( + "" + inputMapData.get("plural_type", null) + ); + + // Consider compact number format, too. + String sample_string = (String) inputMapData.get("sample", null); + // Convert this to a number. + result.sample = Double.parseDouble(sample_string); + + return result; + } + + @Override + public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { + PluralRulesInputJson input = (PluralRulesInputJson) inputJson; + + // partially construct output + PluralRulesOutputJson output = (PluralRulesOutputJson) getDefaultOutputJson(); + output.label = input.label; + + try { + output.result = getPluralRulesResultString(input); + } catch (Exception e) { + output.error = e.getMessage(); + output.error_message = e.getMessage(); + return output; + } + + // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + return output; + } + + public ITestTypeOutputJson getDefaultOutputJson() { + return new PluralRulesOutputJson(); + } + + @Override + public String formatOutputJson(ITestTypeOutputJson outputJson) { + return ExecutorUtils.GSON.toJson((PluralRulesOutputJson) outputJson); + } + + @Override + public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { + PluralRulesOutputJson output = (PluralRulesOutputJson) outputJson; + return new io.lacuna.bifurcan.Map() + .put("label", output.label) + .put("result", output.result); + } + + public String getPluralRulesResultString(PluralRulesInputJson input) { + PluralRules.PluralType plural_type; + ULocale locale = ULocale.forLanguageTag(input.locale); + + switch (input.plural_type) { + case ORDINAL: + plural_type = PluralRules.PluralType.ORDINAL; + break; + default: + case CARDINAL: + plural_type = PluralRules.PluralType.CARDINAL; + break; + } + + PluralRules pl_rules = PluralRules.forLocale(locale, plural_type); + + return pl_rules.select(input.sample); + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesType.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesType.java new file mode 100644 index 00000000..56e0d8ae --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesType.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.pluralrules; + +public enum PluralRulesType { + CARDINAL, + ORDINAL; + + public static org.unicode.conformance.testtype.pluralrules.PluralRulesType DEFAULT = CARDINAL; + + public static org.unicode.conformance.testtype.pluralrules.PluralRulesType getFromString(String s) { + try { + return org.unicode.conformance.testtype.pluralrules.PluralRulesType.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java new file mode 100644 index 00000000..5cb2745e --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java @@ -0,0 +1,97 @@ +package org.unicode.conformance.pluralrules; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.unicode.conformance.testtype.pluralrules.PluralRulesOutputJson; +import org.unicode.conformance.testtype.pluralrules.PluralRulesTester; +public class PluralRulesTest { + + @Test + public void testEnOne() { + String testInput = + "{\t\"locale\": \"en\", \"label\": \"en1\", \"plural_type\": \"cardinal\", \"sample\": \"1\", \"hexhash\": \"0d045ce8\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("one", output.result); + } + + @Test + public void testEnOneOrdinal() { + String testInput = + "{\t\"locale\": \"en\", \"label\": \"en1Oridinal\", \"plural_type\": \"ordinal\", \"sample\": \"1\", \"hexhash\": \"0d045ce8\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("one", output.result); + } + + @Test + public void testFrOne() { + String testInput = + "{\t\"locale\": \"fr\", \"label\": \"fr0\", \"plural_type\": \"cardinal\", \"sample\": \"0\", \"hexhash\": \"0d045ce9\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("one", output.result); + } + + @Test + public void tesCyOther() { + String testInput = + "{\t\"locale\": \"cy\", \"label\": \"en0\", \"plural_type\": \"cardinal\", \"sample\": \"0\", \"hexhash\": \"0d045ce9\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("zero", output.result); + } + + @Test + public void testEnOther() { + String testInput = + "{\t\"locale\": \"en\", \"label\": \"en17\", \"plural_type\": \"cardinal\", \"sample\": \"17\", \"hexhash\": \"0d045ce9\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("other", output.result); + } + + @Test + public void testBmOther() { + String testInput = + "{\t\"locale\": \"bm\", \"label\": \"bm1\", \"plural_type\": \"cardinal\", \"sample\": \"1\", \"hexhash\": \"0d045ce9\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("other", output.result); + } + + @Test + public void testIuOther() { + String testInput = + "{\t\"locale\": \"iu\", \"label\": \"iu3495\", \"plural_type\": \"cardinal\", \"sample\": \"2.0\", \"hexhash\": \"0d045ce9\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("two", output.result); + } + + @Test + public void testFrManyOther() { + String testInput = + "{\t\"locale\": \"fr\", \"label\": \"4007\", \"plural_type\": \"cardinal\", \"sample\": \"1000000\", \"hexhash\": \"8dd05e1e6479f1d8ce7e261d94d22b96e1d01238\"}"; + + PluralRulesOutputJson output = + (PluralRulesOutputJson) PluralRulesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("many", output.result); + } +} diff --git a/run_config.json b/run_config.json index ebdb1daa..648a65aa 100644 --- a/run_config.json +++ b/run_config.json @@ -320,7 +320,8 @@ "lang_names", "likely_subtags", "list_fmt", - "number_fmt" + "number_fmt", + "plural_rules" ], "per_execution": 10000 } From 4832ddb198149a8b85349c7c98a4d54f2660b9f3 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 5 Aug 2024 14:17:05 -0700 Subject: [PATCH 06/26] ICU4J relative date time format (#262) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Making RDTF work in ICU4J * Add ICU4J rdt_fmt to execution --- .../unicode/conformance/Icu4jExecutor.java | 6 +- .../RelativeDateTimeFormatInputJson.java | 22 ++++ .../RelativeDateTimeFormatOutputJson.java | 16 +++ .../RelativeDateTimeFormatStyle.java | 17 +++ .../RelativeDateTimeFormatTester.java | 124 ++++++++++++++++++ .../RelativeDateTimeFormatUnits.java | 22 ++++ .../RelativeDateTimeFormatTest.java | 88 +++++++++++++ executors/rust/1.3/src/relativedatetimefmt.rs | 104 +++++++++++++++ run_config.json | 3 +- 9 files changed, 398 insertions(+), 4 deletions(-) create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatOutputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatStyle.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatUnits.java create mode 100644 executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java create mode 100644 executors/rust/1.3/src/relativedatetimefmt.rs diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java index 9a59cca0..cc1edb47 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java @@ -1,8 +1,5 @@ package org.unicode.conformance; -import com.google.gson.reflect.TypeToken; -import com.ibm.icu.impl.locale.XCldrStub.ImmutableMap; -import com.ibm.icu.number.NumberFormatter; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -18,6 +15,7 @@ import org.unicode.conformance.testtype.messageformat2.MessageFormatTester; import org.unicode.conformance.testtype.numberformatter.NumberFormatterTester; import org.unicode.conformance.testtype.pluralrules.PluralRulesTester; +import org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatTester; /** * Hello world! @@ -132,6 +130,8 @@ public static String getTestCaseResponse(String inputLine) throws Exception { testType = MessageFormatTester.INSTANCE; } else if (testTypeStr.equals("plural_rules")) { testType = PluralRulesTester.INSTANCE; + } else if (testTypeStr.equals("rdt_fmt")) { + testType = RelativeDateTimeFormatTester.INSTANCE; } else { io.lacuna.bifurcan.IMap response = parsedInputPersistentMap diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java new file mode 100644 index 00000000..5f9328bb --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java @@ -0,0 +1,22 @@ +package org.unicode.conformance.testtype.relativedatetimeformat; + +import org.unicode.conformance.testtype.ITestTypeInputJson; + +public class RelativeDateTimeFormatInputJson implements ITestTypeInputJson { + + public String test_type; + + public String label; + + public String locale; + + public String numberingSystem; + + public String count; + + public RelativeDateTimeFormatUnits unit; + + public RelativeDateTimeFormatStyle style; // E.g., SHORT + + public double quantity; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatOutputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatOutputJson.java new file mode 100644 index 00000000..674a6d41 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatOutputJson.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.relativedatetimeformat; + +import org.unicode.conformance.testtype.ITestTypeOutputJson; + +public class RelativeDateTimeFormatOutputJson implements ITestTypeOutputJson { + + public String test_type; + + public String label; + + public String result; + + public String error; + + public String error_message; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatStyle.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatStyle.java new file mode 100644 index 00000000..6f439ac1 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatStyle.java @@ -0,0 +1,17 @@ +package org.unicode.conformance.testtype.relativedatetimeformat; + +public enum RelativeDateTimeFormatStyle { + LONG, + NARROW, + SHORT; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatStyle DEFAULT = LONG; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatStyle getFromString(String s) { + try { + return org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatStyle.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java new file mode 100644 index 00000000..2ea01d4a --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java @@ -0,0 +1,124 @@ + package org.unicode.conformance.testtype.relativedatetimeformat; + + import com.ibm.icu.text.DisplayContext; + import com.ibm.icu.text.NumberFormat; + import com.ibm.icu.text.RelativeDateTimeFormatter; + import com.ibm.icu.text.RelativeDateTimeFormatter.Style; + import com.ibm.icu.util.ULocale; + + import io.lacuna.bifurcan.IMap; + import io.lacuna.bifurcan.Map; + + import org.unicode.conformance.ExecutorUtils; + import org.unicode.conformance.testtype.ITestType; + import org.unicode.conformance.testtype.ITestTypeInputJson; + import org.unicode.conformance.testtype.ITestTypeOutputJson; + + public class RelativeDateTimeFormatTester implements ITestType { + + public static RelativeDateTimeFormatTester INSTANCE = new RelativeDateTimeFormatTester(); + + @Override + public ITestTypeInputJson inputMapToJson(Map inputMapData) { + RelativeDateTimeFormatInputJson result = new RelativeDateTimeFormatInputJson(); + + result.label = (String) inputMapData.get("label", null); + result.locale = (String) inputMapData.get("locale", null); + result.count = (String) inputMapData.get("count", "0"); + result.quantity = Double.parseDouble(result.count); + + result.numberingSystem = (String) inputMapData.get("numbering_system", null); + + java.util.Map inputOptions = + (java.util.Map) inputMapData.get("options", null); + + result.style = RelativeDateTimeFormatStyle.getFromString( + "" + inputOptions.get("style") + ); + + String unitInput = (String) inputMapData.get("unit", "0"); + result.unit = RelativeDateTimeFormatUnits.getFromString( + unitInput); + + return result; + } + + @Override + public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { + RelativeDateTimeFormatInputJson input = (RelativeDateTimeFormatInputJson) inputJson; + + // partially construct output + RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) getDefaultOutputJson(); + output.label = input.label; + + try { + output.result = getRelativeDateTimeFormatResultString(input); + } catch (Exception e) { + output.error = e.getMessage(); + output.error_message = e.getMessage(); + return output; + } + + // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + return output; + } + + @Override + public ITestTypeOutputJson getDefaultOutputJson() { + return new RelativeDateTimeFormatOutputJson(); + } + + public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { + RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) outputJson; + return new io.lacuna.bifurcan.Map() + .put("label", output.label) + .put("result", output.result); + } + + public String formatOutputJson(ITestTypeOutputJson outputJson) { + return ExecutorUtils.GSON.toJson(outputJson); + } + public String getRelativeDateTimeFormatResultString(RelativeDateTimeFormatInputJson input) { + ULocale locale = ULocale.forLanguageTag(input.locale); + Style style; + RelativeDateTimeFormatter.RelativeDateTimeUnit unit; + + switch (input.unit) { + default: + case DAY: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.DAY; + break; + case HOUR: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.HOUR; + break; + case MINUTE: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MINUTE; + break; + case MONTH: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MONTH; + break; + case QUARTER: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.QUARTER; + break; + case SECOND: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.SECOND; + break; + case WEEK: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.WEEK; + break; + case YEAR: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.YEAR; + break; + } + + switch (input.style) { + case NARROW: style = RelativeDateTimeFormatter.Style.NARROW; + break; + case SHORT: style = RelativeDateTimeFormatter.Style.SHORT; + break; + default: + case LONG: style = RelativeDateTimeFormatter.Style.LONG; + break; + } + + NumberFormat nf = null; + DisplayContext dc = DisplayContext.CAPITALIZATION_NONE; + + RelativeDateTimeFormatter rdtf = + RelativeDateTimeFormatter.getInstance(locale, nf, style, dc); + + return rdtf.format(input.quantity, unit); + } + } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatUnits.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatUnits.java new file mode 100644 index 00000000..ac96fe91 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatUnits.java @@ -0,0 +1,22 @@ +package org.unicode.conformance.testtype.relativedatetimeformat; + +public enum RelativeDateTimeFormatUnits { + DAY, + HOUR, + MINUTE, + MONTH, + QUARTER, + SECOND, + WEEK, + YEAR; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatUnits DEFAULT = DAY; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatUnits getFromString(String s) { + try { + return org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatUnits.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java new file mode 100644 index 00000000..74553f7e --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java @@ -0,0 +1,88 @@ +package org.unicode.conformance.relativedatetimeformat; + +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; +import org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatOutputJson; +import org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateTimeFormatTester; + +public class RelativeDateTimeFormatTest { + + @Test + public void testEn100SecondsAgo() { + String testInput = + "\t{\"unit\":\"second\",\"count\":\"-100\",\"locale\":\"en-US\",\"options\":{},\"hexhash\":\"ab5dfa48d57aac79202e8e4dfd12b729b8e4a74a\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("100 seconds ago", output.result); + } + + @Test + public void testEnIn100Sec() { + String testInput = + "\t{\"unit\":\"second\",\"count\":\"100\",\"locale\":\"en-US\",\"options\":{\"style\":\"short\"},\"hexhash\":\"ab5dfa48d57aac79202e8e4dfd12b729b8e4a74a\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("in 100 sec.", output.result); + } + + @Test + public void testEnIn100Seconds() { + String testInput = + "\t{\"unit\":\"second\",\"count\":\"100\",\"locale\":\"en-US\",\"options\":{\"style\":\"long\"},\"hexhash\":\"ab5dfa48d57aac79202e8e4dfd12b729b8e4a74a\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("in 100 seconds", output.result); + } + + @Test + public void testEn100SecAgo() { + String testInput = + "\t{\"unit\":\"second\",\"count\":\"-100\",\"locale\":\"en-US\",\"options\":{\"style\":\"short\"},\"hexhash\":\"ab5dfa48d57aac79202e8e4dfd12b729b8e4a74a\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("100 sec. ago", output.result); + } + + @Test + public void testEn100SAgo() { + String testInput = + "\t{\"unit\":\"second\",\"count\":\"-100\",\"locale\":\"en-US\",\"options\":{\"style\":\"narrow\"},\"hexhash\":\"a57aac792\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("100s ago", output.result); + } + + @Ignore + // This doesn't yet handle non-ASCII numbering systems + // https://github.com/unicode-org/conformance/issues/261 + @Test + public void testAdlamIn1Year() { + // Adlam string in output + // + String testInput = + "\t{\"unit\":\"second\",\"count\":\"-100\",\"locale\":\"en-US\",\"options\":{\"style\":\"narrow\"},\"numberingSystem\":\"adlm\",\"hexhash\":\"79202e8e\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("in 𞥑𞥐y", output.result); + } +} diff --git a/executors/rust/1.3/src/relativedatetimefmt.rs b/executors/rust/1.3/src/relativedatetimefmt.rs new file mode 100644 index 00000000..3f1fe0cf --- /dev/null +++ b/executors/rust/1.3/src/relativedatetimefmt.rs @@ -0,0 +1,104 @@ + // https://docs.rs/icu/1.3.2/icu/datetime/struct.DateTimeFormatter.html + +use icu::calendar::DateTime; +use icu::calendar::{buddhist::Buddhist, + chinese::Chinese, + coptic::Coptic, + dangi::Dangi, + ethopian::Ethopian, + gergorian::Gregorian, + hewbrew::Hebrew, + indian::Indian, + iso::ISO, + japanese::Japanese, + julian::Julian, + persian::Persian, + roc::Roc, + Date}; + +use icu::datetime::{options::length, DateTimeFormatter}; +// use icu::datetime::input::DateTimeInput; +use icu_provider::DataLocale; + +use icu::locid::Locale; + +use serde_json::{json, Value}; +use serde::{Deserialize,Serialize}; + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct DateTimeFormatOptions { + date_style: Option, + time_style: Option, + time_zone: Option, + era: Option, + calendar: Option, + numbering_system: Option +} + +pub fn run_datetimeformat_test(json_obj: &Value) -> Result { + let label = &json_obj["label"].as_str().unwrap(); + + let langid: Locale = json_obj + .get("locale") + .map(|locale_name| locale_name.as_str().unwrap().parse().unwrap()) + .unwrap_or_default(); + + let data_locale = DataLocale::from(langid); + + // If there are unsupported values, return + // "unsupported" rather than an error. + let options = &json_obj["options"]; // This will be an array. + + let mut _unsupported_options: Vec<&str> = Vec::new(); + + // handle options - maybe done? + + // TODO: handle calendar + // TODO: dateStyle + // TODO: timeStyle + // TODO: timeZone + // TODO: era + // TODO: skeleton + + // Set up DT options + let dt_options = length::Bag::from_date_time_style( + length::Date::Medium, + length::Time::Short + ); + + let option_struct: DateTimeFormatOptions = + serde_json::from_str(&options.to_string()).unwrap(); + + // TODO: !!! time input in ISO format. + // let input_string = &json_obj["input_string"].as_str().unwrap(); + + // let iso_input = DateTime::try_new_iso_datetime(input_string); + + let dtf = DateTimeFormatter::try_new( + &data_locale, + dt_options.into(), + ) + .expect("Failed to create DateTimeFormatter instance."); + + // !!! TEMPORARY ! + let date_iso = DateTime::try_new_iso_datetime(2020, 9, 1, 12, 34, 28) + .expect("Failed to construct DateTime."); + let any_datetime = date_iso.to_any(); + + // !!! Calendar. + let calendar_type = gregorian; + let calendar_date = date_iso.to_calendar(calendar_type); + + // Result to stdout. + // TODO: get the date/time info from a skeleton. + let formatted_dt = dtf.format(&any_datetime).expect("should work"); + let result_string = formatted_dt.to_string(); + + Ok(json!({ + "label": label, + "result": result_string, + "actual_options": format!("{option_struct:?}, {options:?}"), + })) + +} diff --git a/run_config.json b/run_config.json index 648a65aa..f0492b28 100644 --- a/run_config.json +++ b/run_config.json @@ -321,7 +321,8 @@ "likely_subtags", "list_fmt", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" ], "per_execution": 10000 } From ad78cbb617c26a2f66e3942c7459c5dfddbf037a Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 5 Aug 2024 14:49:57 -0700 Subject: [PATCH 07/26] ICU4J clear up imports and variable names in listFormat and pluralRules (#265) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Clean up imports and variable names - listFormat and pluralRules --- .../listformatter/ListFormatterInputJson.java | 6 ++-- .../listformatter/ListFormatterTester.java | 35 +++++++++---------- .../pluralrules/PluralRulesInputJson.java | 2 +- .../pluralrules/PluralRulesTester.java | 24 +++++-------- 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java index e1052fcd..b49c4b6f 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterInputJson.java @@ -5,16 +5,16 @@ public class ListFormatterInputJson implements ITestTypeInputJson { - public String test_type; + public String testType; public String label; public String locale; - public ListFormatterType list_type; + public ListFormatterType listType; public ListFormatterWidth style; // e.g., SHORT - public Collection input_list; + public Collection inputList; } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java index c68e18ec..d9b953ea 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java @@ -10,13 +10,10 @@ import java.util.Collection; -import java.util.HashMap; import org.unicode.conformance.ExecutorUtils; import org.unicode.conformance.testtype.ITestType; import org.unicode.conformance.testtype.ITestTypeInputJson; import org.unicode.conformance.testtype.ITestTypeOutputJson; -import org.unicode.conformance.testtype.numberformatter.NumberFormatterTestOptionKey; -import org.unicode.conformance.testtype.numberformatter.StyleVal; public class ListFormatterTester implements ITestType { @@ -29,16 +26,16 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { result.label = (String) inputMapData.get("label", null); result.locale = (String) inputMapData.get("locale", null); - java.util.Map input_options = (java.util.Map) inputMapData.get("options", null); + java.util.Map inputOptions = (java.util.Map) inputMapData.get("options", null); - result.list_type = ListFormatterType.getFromString( - "" + input_options.get("list_type") + result.listType = ListFormatterType.getFromString( + "" + inputOptions.get("list_type") ); result.style = ListFormatterWidth.getFromString( - "" + input_options.get("style") + "" + inputOptions.get("style") ); - result.input_list = (Collection) inputMapData.get("input_list", null); + result.inputList = (Collection) inputMapData.get("input_list", null); return result; } @@ -82,32 +79,32 @@ public String formatOutputJson(ITestTypeOutputJson outputJson) { } public String getListFormatResultString(ListFormatterInputJson input) { - ListFormatter.Type list_type; - ListFormatter.Width list_width; + ListFormatter.Type listType; + ListFormatter.Width listWidth; ULocale locale = ULocale.forLanguageTag(input.locale); - switch (input.list_type) { - case DISJUNCTION: list_type = Type.OR; + switch (input.listType) { + case DISJUNCTION: listType = Type.OR; break; - case UNIT: list_type = Type.UNITS; + case UNIT: listType = Type.UNITS; break; default: - case CONJUNCTION: list_type = Type.AND; + case CONJUNCTION: listType = Type.AND; break; } switch (input.style) { - case NARROW: list_width = Width.NARROW; + case NARROW: listWidth = Width.NARROW; break; - case SHORT: list_width = Width.SHORT; + case SHORT: listWidth = Width.SHORT; break; default: - case LONG: list_width = Width.WIDE; + case LONG: listWidth = Width.WIDE; break; } - ListFormatter lf = ListFormatter.getInstance(locale, list_type, list_width); + ListFormatter lf = ListFormatter.getInstance(locale, listType, listWidth); - return lf.format(input.input_list); + return lf.format(input.inputList); } } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java index e8898ac0..10aae758 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesInputJson.java @@ -9,7 +9,7 @@ public class PluralRulesInputJson implements ITestTypeInputJson { public String locale; - public PluralRulesType plural_type; + public PluralRulesType pluralType; public double sample; } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java index cac589b2..23897816 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/pluralrules/PluralRulesTester.java @@ -1,21 +1,15 @@ package org.unicode.conformance.testtype.pluralrules; import com.ibm.icu.util.ULocale; -import com.ibm.icu.text.PluralRules.PluralType; import com.ibm.icu.text.PluralRules; import io.lacuna.bifurcan.IMap; import io.lacuna.bifurcan.Map; -import java.util.Collection; - -import java.util.HashMap; import org.unicode.conformance.ExecutorUtils; import org.unicode.conformance.testtype.ITestType; import org.unicode.conformance.testtype.ITestTypeInputJson; import org.unicode.conformance.testtype.ITestTypeOutputJson; -import org.unicode.conformance.testtype.pluralrules.PluralRulesInputJson; -import org.unicode.conformance.testtype.pluralrules.PluralRulesOutputJson; public class PluralRulesTester implements ITestType { @@ -28,14 +22,14 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { result.label = (String) inputMapData.get("label", null); result.locale = (String) inputMapData.get("locale", null); - result.plural_type = PluralRulesType.getFromString( + result.pluralType = PluralRulesType.getFromString( "" + inputMapData.get("plural_type", null) ); // Consider compact number format, too. - String sample_string = (String) inputMapData.get("sample", null); + String sampleString = (String) inputMapData.get("sample", null); // Convert this to a number. - result.sample = Double.parseDouble(sample_string); + result.sample = Double.parseDouble(sampleString); return result; } @@ -78,21 +72,21 @@ public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { } public String getPluralRulesResultString(PluralRulesInputJson input) { - PluralRules.PluralType plural_type; + PluralRules.PluralType pluralType; ULocale locale = ULocale.forLanguageTag(input.locale); - switch (input.plural_type) { + switch (input.pluralType) { case ORDINAL: - plural_type = PluralRules.PluralType.ORDINAL; + pluralType = PluralRules.PluralType.ORDINAL; break; default: case CARDINAL: - plural_type = PluralRules.PluralType.CARDINAL; + pluralType = PluralRules.PluralType.CARDINAL; break; } - PluralRules pl_rules = PluralRules.forLocale(locale, plural_type); + PluralRules pluralRules = PluralRules.forLocale(locale, pluralType); - return pl_rules.select(input.sample); + return pluralRules.select(input.sample); } } From 7db1d6aca77d8ebf96e30b03d251c6ce310dec2c Mon Sep 17 00:00:00 2001 From: Elango Cheran Date: Tue, 6 Aug 2024 15:16:05 -0700 Subject: [PATCH 08/26] Enable multiple ICU4J versions (#264) * Enable profiles to control ICU4J dep version * Configure unit test inclusion path(s) in build profile for icu74 * Create version-based subpackages for the ICU4J executor unit tests * Configure only ICU v74 unit tests to run with the ICU 74 dep * Configure relative datetime format tests for ICU 74 * Enable and fix unit tests for MF2 in ICU 75 * Update ICU4J executor command to use binary already compiled for ICU4J version * Add ICU 75 tests for ICU4J to run_config.json * Add build profile and run_config for ICU 73 for ICU4J (sharing unit tests with v74) --- executors/icu4j/74/executor-icu4j/pom.xml | 102 ++++++++++- .../collator/{ => icu74}/CollatorTest.java | 2 +- .../langnames/{ => icu74}/LangNamesTest.java | 2 +- .../{ => icu74}/LikelySubtagsTest.java | 2 +- .../{ => icu74}/ListFormatterTest.java | 2 +- .../{ => icu74}/MessageFormatterTest.java | 11 +- .../icu75/MessageFormatterTest.java | 163 ++++++++++++++++++ .../{ => icu74}/NumberFormatterTest.java | 2 +- .../{ => icu74}/PluralRulesTest.java | 2 +- .../RelativeDateTimeFormatTest.java | 2 +- run_config.json | 48 +++++- testdriver/datasets.py | 2 +- 12 files changed, 316 insertions(+), 24 deletions(-) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/{ => icu74}/CollatorTest.java (95%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/{ => icu74}/LangNamesTest.java (92%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/{ => icu74}/LikelySubtagsTest.java (95%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/{ => icu74}/ListFormatterTest.java (96%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/{ => icu74}/MessageFormatterTest.java (94%) create mode 100644 executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu75/MessageFormatterTest.java rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/{ => icu74}/NumberFormatterTest.java (97%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/{ => icu74}/PluralRulesTest.java (98%) rename executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/{ => icu74}/RelativeDateTimeFormatTest.java (98%) diff --git a/executors/icu4j/74/executor-icu4j/pom.xml b/executors/icu4j/74/executor-icu4j/pom.xml index 3d8050be..3f9a2427 100644 --- a/executors/icu4j/74/executor-icu4j/pom.xml +++ b/executors/icu4j/74/executor-icu4j/pom.xml @@ -19,6 +19,100 @@ jar + + + + icu73 + + + com.ibm.icu + icu4j + 73.2 + + + + + + maven-surefire-plugin + + + + **/collator/icu74/*Test.java + **/langnames/icu74/*Test.java + **/likelysubtags/icu74/*Test.java + **/listformatter/icu74/*Test.java + + **/numberformatter/icu74/*Test.java + **/pluralrules/icu74/*Test.java + **/relativedatetimeformat/icu74/*Test.java + + + + + + + + icu74 + + + com.ibm.icu + icu4j + 74.2 + + + + + + maven-surefire-plugin + + + + **/collator/icu74/*Test.java + **/langnames/icu74/*Test.java + **/likelysubtags/icu74/*Test.java + **/listformatter/icu74/*Test.java + **/messageformat2/icu74/*Test.java + **/numberformatter/icu74/*Test.java + **/pluralrules/icu74/*Test.java + **/relativedatetimeformat/icu74/*Test.java + + + + + + + + icu75 + + + com.ibm.icu + icu4j + 75.1 + + + + + + maven-surefire-plugin + + + + **/collator/icu74/*Test.java + **/langnames/icu74/*Test.java + **/likelysubtags/icu74/*Test.java + **/listformatter/icu74/*Test.java + **/messageformat2/icu75/*Test.java + **/numberformatter/icu74/*Test.java + **/pluralrules/icu74/*Test.java + **/relativedatetimeformat/icu74/*Test.java + + + + + + + + junit @@ -27,12 +121,8 @@ test - - - com.ibm.icu - icu4j - 74.2 - + diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/CollatorTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/icu74/CollatorTest.java similarity index 95% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/CollatorTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/icu74/CollatorTest.java index 62af0a33..0115ca86 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/CollatorTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/collator/icu74/CollatorTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.collator; +package org.unicode.conformance.collator.icu74; import static org.junit.Assert.assertTrue; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/LangNamesTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java similarity index 92% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/LangNamesTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java index 80b34e3a..6cfa35b4 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/LangNamesTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.langnames; +package org.unicode.conformance.langnames.icu74; import static org.junit.Assert.assertEquals; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/LikelySubtagsTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/icu74/LikelySubtagsTest.java similarity index 95% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/LikelySubtagsTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/icu74/LikelySubtagsTest.java index 7956470c..a3e3fd63 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/LikelySubtagsTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/likelysubtags/icu74/LikelySubtagsTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.likelysubtags; +package org.unicode.conformance.likelysubtags.icu74; import static org.junit.Assert.assertEquals; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/icu74/ListFormatterTest.java similarity index 96% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/icu74/ListFormatterTest.java index a9fb512b..cbda3962 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/ListFormatterTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/listformatter/icu74/ListFormatterTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.listformatter; +package org.unicode.conformance.listformatter.icu74; import static org.junit.Assert.assertEquals; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/MessageFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu74/MessageFormatterTest.java similarity index 94% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/MessageFormatterTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu74/MessageFormatterTest.java index 426b7f4b..f936bb46 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/MessageFormatterTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu74/MessageFormatterTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.messageformat2; +package org.unicode.conformance.messageformat2.icu74; import static org.junit.Assert.assertEquals; @@ -120,9 +120,6 @@ public void testGetFormattedMessage() { } - // ICU 75 impl output differs from MF2 spec defined at same time point (CLDR 45) - // in what to return in message for non-provided args / formatting errors - @Ignore @Test public void testGetFormattedMessage_usingNonProvidedArg() { // Setup @@ -138,11 +135,11 @@ public void testGetFormattedMessage_usingNonProvidedArg() { String formattedString = MessageFormatTester.INSTANCE.getFormattedMessage(inputJson); // Expect & assert test - String expected = "{:date}"; + String expected = ":date"; assertEquals(expected, formattedString); } - // ICU 75 impl output differs from MF2 spec defined at same time point (CLDR 45) + // TODO: figure out expected output, and then reenable? @Ignore @Test public void testGetFormattedMessage_numberLiteralOperand() { @@ -150,7 +147,7 @@ public void testGetFormattedMessage_numberLiteralOperand() { MessageFormatInputJson inputJson = new MessageFormatInputJson(); inputJson.label = "00035"; inputJson.locale = "en-US"; - inputJson.src = "hello {4.2 :integer}"; + inputJson.src = "{hello {|4.2| :integer}}"; inputJson.test_description = "Test of formatting a pattern using an input arg that isn't provided"; List inputs = new ArrayList<>(); inputJson.params = inputs; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu75/MessageFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu75/MessageFormatterTest.java new file mode 100644 index 00000000..b52ba8f4 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/messageformat2/icu75/MessageFormatterTest.java @@ -0,0 +1,163 @@ +package org.unicode.conformance.messageformat2.icu75; + +import static org.junit.Assert.assertEquals; + +import com.ibm.icu.util.ULocale; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.unicode.conformance.testtype.messageformat2.IMFInputParam; +import org.unicode.conformance.testtype.messageformat2.MFInputParamDatetime; +import org.unicode.conformance.testtype.messageformat2.MFInputParamObject; +import org.unicode.conformance.testtype.messageformat2.MessageFormatInputJson; +import org.unicode.conformance.testtype.messageformat2.MessageFormatTester; + +public class MessageFormatterTest { + + /** + * The default locale used for all of our tests. Used in @Before + */ + protected final static Locale defaultLocale = Locale.US; + + /** + * The default time zone for all of our tests. Used in @Before + */ + protected final static TimeZone defaultTimeZone = TimeZone.getTimeZone("America/Los_Angeles"); + + private com.ibm.icu.util.TimeZone testStartDefaultIcuTz; + + private TimeZone testStartDefaultJdkTz; + + private ULocale testStartDefaultULocale; + + private Locale testStartDefaultLocale; + + @Rule + public TestName name = new TestName(); + + // Copying test setup behavior from ICU4J CoreTestFmwk / TestFmwk, which + // ensures we pin the default locale and TZ during the test. ICU Formatters + // implicitly use the system's default locale and TZ. + @Before + public final void setup() { + // Just like TestFmwk initializes JDK TimeZone and Locale before every test, + // do the same for ICU TimeZone and ULocale. + ULocale.setDefault(ULocale.forLocale(defaultLocale)); + com.ibm.icu.util.TimeZone.setDefault( + com.ibm.icu.util.TimeZone.getTimeZone(defaultTimeZone.getID())); + + // Save starting timezones + testStartDefaultIcuTz = com.ibm.icu.util.TimeZone.getDefault(); + testStartDefaultJdkTz = TimeZone.getDefault(); + + // Save starting locales + testStartDefaultULocale = ULocale.getDefault(); + testStartDefaultLocale = Locale.getDefault(); + } + + // Copying test teardown beahvior from ICU4J CoreTestFmwk, corresponding to + // the setup work. + @After + public final void teardown() { + String testMethodName = name.getMethodName(); + + // Assert that timezones are in a good state + + com.ibm.icu.util.TimeZone testEndDefaultIcuTz = com.ibm.icu.util.TimeZone.getDefault(); + TimeZone testEndDefaultJdkTz = TimeZone.getDefault(); + + assertEquals("In [" + testMethodName + "] Test should keep in sync ICU & JDK TZs", + testEndDefaultIcuTz.getID(), + testEndDefaultJdkTz.getID()); + + assertEquals("In [" + testMethodName + "] Test should reset ICU default TZ", + testStartDefaultIcuTz.getID(), testEndDefaultIcuTz.getID()); + assertEquals("In [" + testMethodName + "] Test should reset JDK default TZ", + testStartDefaultJdkTz.getID(), testEndDefaultJdkTz.getID()); + + // Assert that locales are in a good state + + ULocale testEndDefaultULocale = ULocale.getDefault(); + Locale testEndDefaultLocale = Locale.getDefault(); + + assertEquals("In [" + testMethodName + "] Test should reset ICU ULocale", + testStartDefaultULocale.toLanguageTag(), testEndDefaultULocale.toLanguageTag()); + assertEquals("In [" + testMethodName + "] Test should reset JDK Locale", + testStartDefaultLocale.toLanguageTag(), testEndDefaultLocale.toLanguageTag()); + } + + @Test + public void testGetFormattedMessage() { + // Setup + MessageFormatInputJson inputJson = new MessageFormatInputJson(); + inputJson.label = "00001"; + inputJson.locale = "en-GB"; + inputJson.src = "Hello {$name}, your card expires on {$exp :datetime skeleton=yMMMdE}!"; + inputJson.test_description = "Test using the ICU4J API doc example for the MessageFormatter class"; + List inputs = new ArrayList<>(); + MFInputParamObject nameArg = new MFInputParamObject(); + nameArg.name = "name"; + nameArg.value = "John"; + inputs.add(nameArg); + MFInputParamDatetime expArg = new MFInputParamDatetime("exp", "2023-03-27T19:42:51"); // March 27, 2023, 7:42:51 PM + expArg.name = "exp"; + inputs.add(expArg); + inputJson.params = inputs; + + // Actual + String formattedString = MessageFormatTester.INSTANCE.getFormattedMessage(inputJson); + + // Expect & assert test + String expected = "Hello John, your card expires on 27/03/2023, 12:42!"; + assertEquals(expected, formattedString); + + } + + // ICU 75 impl output differs from MF2 spec defined at same time point (CLDR 45) + // in what to return in message for non-provided args / formatting errors + @Test + public void testGetFormattedMessage_usingNonProvidedArg() { + // Setup + MessageFormatInputJson inputJson = new MessageFormatInputJson(); + inputJson.label = "00020"; + inputJson.locale = "en-US"; + inputJson.src = ":date"; + inputJson.test_description = "Test of formatting a pattern using an input arg that isn't provided"; + List inputs = new ArrayList<>(); + inputJson.params = inputs; + + // Actual + String formattedString = MessageFormatTester.INSTANCE.getFormattedMessage(inputJson); + + // Expect & assert test + String expected = ":date"; + assertEquals(expected, formattedString); + } + + @Test + public void testGetFormattedMessage_numberLiteralOperand() { + // Setup + MessageFormatInputJson inputJson = new MessageFormatInputJson(); + inputJson.label = "00035"; + inputJson.locale = "en-US"; + inputJson.src = "hello {4.2 :integer}"; + inputJson.test_description = "Test of formatting a pattern using an input arg that isn't provided"; + List inputs = new ArrayList<>(); + inputJson.params = inputs; + + // Actual + String formattedString = MessageFormatTester.INSTANCE.getFormattedMessage(inputJson); + + // Expect & assert test + String expected = "hello 4"; + assertEquals(expected, formattedString); + } + +} diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/NumberFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/icu74/NumberFormatterTest.java similarity index 97% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/NumberFormatterTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/icu74/NumberFormatterTest.java index a3ae7a50..271e8dcd 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/NumberFormatterTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/numberformatter/icu74/NumberFormatterTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.numberformatter; +package org.unicode.conformance.numberformatter.icu74; import static org.junit.Assert.assertEquals; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/icu74/PluralRulesTest.java similarity index 98% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/icu74/PluralRulesTest.java index 5cb2745e..3635d41a 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/PluralRulesTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/pluralrules/icu74/PluralRulesTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.pluralrules; +package org.unicode.conformance.pluralrules.icu74; import static org.junit.Assert.assertEquals; diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java similarity index 98% rename from executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java rename to executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java index 74553f7e..2e6ac272 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/RelativeDateTimeFormatTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java @@ -1,4 +1,4 @@ -package org.unicode.conformance.relativedatetimeformat; +package org.unicode.conformance.relativedatetimeformat.icu74; import static org.junit.Assert.assertEquals; diff --git a/run_config.json b/run_config.json index f0492b28..ff64329a 100644 --- a/run_config.json +++ b/run_config.json @@ -306,11 +306,32 @@ "per_execution": 10000 } }, + { + "prereq": { + "name": "mvn-icu4j-73-shaded", + "version": "73", + "command": "mvn -q -P icu73 -f ../executors/icu4j/74/executor-icu4j/pom.xml package" + }, + "run": { + "icu_version": "icu73", + "exec": "icu4j", + "test_type": [ + "collation_short", + "lang_names", + "likely_subtags", + "list_fmt", + "number_fmt", + "plural_rules", + "rdt_fmt" + ], + "per_execution": 10000 + } + }, { "prereq": { "name": "mvn-icu4j-74-shaded", "version": "74", - "command": "mvn -q -f ../executors/icu4j/74/executor-icu4j/pom.xml package" + "command": "mvn -q -P icu74 -f ../executors/icu4j/74/executor-icu4j/pom.xml package" }, "run": { "icu_version": "icu74", @@ -327,11 +348,32 @@ "per_execution": 10000 } }, + { + "prereq": { + "name": "mvn-icu4j-75-shaded", + "version": "75", + "command": "mvn -q -P icu75 -f ../executors/icu4j/74/executor-icu4j/pom.xml package" + }, + "run": { + "icu_version": "icu75", + "exec": "icu4j", + "test_type": [ + "collation_short", + "lang_names", + "likely_subtags", + "list_fmt", + "number_fmt", + "plural_rules", + "rdt_fmt" + ], + "per_execution": 10000 + } + }, { "prereq": { "name": "mvn-icu4j-74-shaded", - "version": "74", - "command": "mvn -q -f ../executors/icu4j/74/executor-icu4j/pom.xml package" + "version": "75", + "command": "mvn -q -P icu75 -f ../executors/icu4j/74/executor-icu4j/pom.xml package -DskipTests=true" }, "run": { "icu_version": "icu75", diff --git a/testdriver/datasets.py b/testdriver/datasets.py index c8a59151..eb102729 100644 --- a/testdriver/datasets.py +++ b/testdriver/datasets.py @@ -206,7 +206,7 @@ class ExecutorLang(Enum): "dart_native" : "../executors/dart_native/bin/executor/executor.exe", "rust" : "../executors/rust/target/release/executor", "cpp": "LD_LIBRARY_PATH=/tmp/icu/icu/usr/local/lib ../executors/cpp/executor", - "icu4j" : "mvn -q -f ../executors/icu4j/74/executor-icu4j/pom.xml compile exec:java -Dexec.mainClass=org.unicode.conformance.Icu4jExecutor" + "icu4j" : "java -jar ../executors/icu4j/74/executor-icu4j/target/executor-icu4j-1.0-SNAPSHOT-shaded.jar" } class ParallelMode(Enum): From 6c137c5ca4f3d9d858dda4f622455c63d1ccfa87 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 8 Aug 2024 15:39:49 -0700 Subject: [PATCH 09/26] ICU4J: adding datetime fmt (#266) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * ICU4J: adding date time format * ICU4J DateTimeFormat tests starting to work * Added two tests and reformatted some code * Add Java date time formatter tests for ICU73 and ICU 75 * Removing unused code --- .../unicode/conformance/Icu4jExecutor.java | 3 + .../DateTimeFormatterDateStyle.java | 21 ++ .../DateTimeFormatterInputJson.java | 37 +++ .../DateTimeFormatterOutputJson.java | 16 ++ .../DateTimeFormatterTester.java | 167 ++++++++++++++ .../DateTimeFormatterTimeStyle.java | 22 ++ .../listformatter/ListFormatterTester.java | 25 +- .../RelativeDateTimeFormatTester.java | 214 +++++++++--------- .../DateTimeFormatterTest.java | 73 ++++++ run_config.json | 3 + 10 files changed, 471 insertions(+), 110 deletions(-) create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterDateStyle.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterInputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterOutputJson.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTester.java create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTimeStyle.java create mode 100644 executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/datetimeformatter/DateTimeFormatterTest.java diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java index cc1edb47..3ed36d33 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/Icu4jExecutor.java @@ -9,6 +9,7 @@ import org.unicode.conformance.testtype.ITestType; import org.unicode.conformance.testtype.ITestTypeOutputJson; import org.unicode.conformance.testtype.collator.CollatorTester; +import org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterTester; import org.unicode.conformance.testtype.langnames.LangNamesTester; import org.unicode.conformance.testtype.likelysubtags.LikelySubtagsTester; import org.unicode.conformance.testtype.listformatter.ListFormatterTester; @@ -118,6 +119,8 @@ public static String getTestCaseResponse(String inputLine) throws Exception { ITestType testType; if (testTypeStr.equals("collation_short")) { testType = CollatorTester.INSTANCE; + } else if (testTypeStr.equals("datetime_fmt")) { + testType = DateTimeFormatterTester.INSTANCE; } else if (testTypeStr.equals("lang_names")) { testType = LangNamesTester.INSTANCE; } else if (testTypeStr.equals("likely_subtags")) { diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterDateStyle.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterDateStyle.java new file mode 100644 index 00000000..0a78718a --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterDateStyle.java @@ -0,0 +1,21 @@ +package org.unicode.conformance.testtype.datetimeformatter; + +public enum DateTimeFormatterDateStyle { + FULL, + LONG, + MEDIUM, + SHORT; + + public static org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterDateStyle DEFAULT = MEDIUM; + + public static org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterDateStyle getFromString( + String s) { + try { + return org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterDateStyle.valueOf( + s.toUpperCase()); + } catch (Exception e) { + return DEFAULT; + } + } + +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterInputJson.java new file mode 100644 index 00000000..46f9e408 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterInputJson.java @@ -0,0 +1,37 @@ +package org.unicode.conformance.testtype.datetimeformatter; + +import java.util.Date; +import com.ibm.icu.util.Calendar; + +import org.unicode.conformance.testtype.ITestTypeInputJson; + +public class DateTimeFormatterInputJson implements ITestTypeInputJson { + + public String testType; + + public String label; + + public String locale; + + // UTC formatted time + public String inputString; + + public Date myDate; + + public String skeleton; + + public DateTimeFormatterDateStyle dateStyle; + + public DateTimeFormatterTimeStyle timeStyle; + + // TODO!!! + public String calendarString; + // Set calendar from calendarString! + public Calendar calendar; + + public String numberingSystem; + + public String timeZone; + + public String timeZoneName; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterOutputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterOutputJson.java new file mode 100644 index 00000000..fd948e10 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterOutputJson.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.datetimeformatter; + +import org.unicode.conformance.testtype.ITestTypeOutputJson; + +public class DateTimeFormatterOutputJson implements ITestTypeOutputJson { + + public String test_type; + + public String label; + + public String result; + + public String error; + + public String error_message; +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTester.java new file mode 100644 index 00000000..953403bb --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTester.java @@ -0,0 +1,167 @@ +package org.unicode.conformance.testtype.datetimeformatter; + +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import java.util.Date; + +import com.ibm.icu.util.Calendar; +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.util.ULocale; + +import io.lacuna.bifurcan.IMap; +import io.lacuna.bifurcan.Map; + + +import org.unicode.conformance.ExecutorUtils; +import org.unicode.conformance.testtype.ITestType; +import org.unicode.conformance.testtype.ITestTypeInputJson; +import org.unicode.conformance.testtype.ITestTypeOutputJson; + +public class DateTimeFormatterTester implements ITestType { + + public static DateTimeFormatterTester INSTANCE = new DateTimeFormatterTester(); + + @Override + public ITestTypeInputJson inputMapToJson(Map inputMapData) { + DateTimeFormatterInputJson result = new DateTimeFormatterInputJson(); + + result.label = (String) inputMapData.get("label", null); + result.locale = (String) inputMapData.get("locale", null); + result.skeleton = (String) inputMapData.get("skeleton", null); + + result.inputString = (String) inputMapData.get("input_string", null); + + java.util.Map inputOptions = + (java.util.Map) inputMapData.get("options", null); + + result.timeZone = (String) inputOptions.get("timeZone"); + ZoneId thisZoneId; + if (result.timeZone == null) { + thisZoneId = ZoneId.systemDefault(); + } else { + thisZoneId = ZoneId.of(result.timeZone); + } + + // Extract ISO part of the input string to parse. + String inputStringDateTime = result.inputString.substring(0, 25); + + // For parsing the input string and converting to java.util.date + LocalDateTime parsedLocalDateTime = + LocalDateTime.parse(inputStringDateTime, DateTimeFormatter.ISO_OFFSET_DATE_TIME); + result.myDate = + java.util.Date.from(parsedLocalDateTime.atZone(thisZoneId) + .toInstant()); + + result.dateStyle = DateTimeFormatterDateStyle.getFromString( + "" + inputOptions.get("dateStyle") + ); + + result.timeStyle = DateTimeFormatterTimeStyle.getFromString( + "" + inputOptions.get("timeStyle") + ); + + result.calendarString = (String) inputOptions.get("calendar"); + + // TODO!!! Get calendar object. Depends on timezone and locale. + // Just a placeholder for now. + result.calendar = Calendar.getInstance(); + + result.numberingSystem = (String) inputOptions.get("numberingSystem"); + + result.timeZoneName = (String) inputOptions.get("timeZoneName"); + + return result; + } + + public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { + DateTimeFormatterInputJson input = (DateTimeFormatterInputJson) inputJson; + + // partially construct output + DateTimeFormatterOutputJson output = (DateTimeFormatterOutputJson) getDefaultOutputJson(); + output.label = input.label; + + try { + output.result = getDateTimeFormatterResultString(input); + } catch (Exception e) { + output.error = e.getMessage(); + output.error_message = e.getMessage(); + return output; + } + + // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + return output; + } + + @Override + public ITestTypeOutputJson getDefaultOutputJson() { + return new DateTimeFormatterOutputJson(); + } + + public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { + DateTimeFormatterOutputJson output = (DateTimeFormatterOutputJson) outputJson; + return new io.lacuna.bifurcan.Map() + .put("label", output.label) + .put("result", output.result); + } + + @Override + public String formatOutputJson(ITestTypeOutputJson outputJson) { + return ExecutorUtils.GSON.toJson((DateTimeFormatterOutputJson) outputJson); + } + + public String getDateTimeFormatterResultString(DateTimeFormatterInputJson input) { + + ULocale locale = ULocale.forLanguageTag(input.locale); + + int dateStyle; + switch (input.dateStyle) { + case FULL: + dateStyle = DateFormat.FULL; + break; + case LONG: + dateStyle = DateFormat.LONG; + break; + default: + case MEDIUM: + dateStyle = DateFormat.MEDIUM; + break; + case SHORT: + dateStyle = DateFormat.SHORT; + break; + } + + int timeStyle; + switch (input.timeStyle) { + case FULL: + timeStyle = DateFormat.FULL; + break; + case LONG: + timeStyle = DateFormat.LONG; + break; + default: + case MEDIUM: + timeStyle = DateFormat.MEDIUM; + break; + case SHORT: + timeStyle = DateFormat.SHORT; + break; + + } + + // Get calendar and timezone as needed. + Calendar cal = input.calendar; + + DateFormat dtf; + if (input.skeleton != null) { + dtf = DateFormat.getInstanceForSkeleton(cal, input.skeleton, locale); + } else { + dtf = DateFormat.getDateTimeInstance(cal, dateStyle, timeStyle, locale); + } + + return dtf.format(input.myDate); + } + +} \ No newline at end of file diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTimeStyle.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTimeStyle.java new file mode 100644 index 00000000..50842fe9 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/datetimeformatter/DateTimeFormatterTimeStyle.java @@ -0,0 +1,22 @@ +package org.unicode.conformance.testtype.datetimeformatter; + +public enum DateTimeFormatterTimeStyle { + FULL, + LONG, + MEDIUM, + SHORT; + + public static org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterTimeStyle DEFAULT = MEDIUM; + + public static org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterTimeStyle getFromString( + String s) { + try { + return org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterTimeStyle.valueOf( + s.toUpperCase()); + } catch (Exception e) { + return DEFAULT; + } + } + +} + diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java index d9b953ea..cdc00f0f 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/listformatter/ListFormatterTester.java @@ -26,7 +26,8 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { result.label = (String) inputMapData.get("label", null); result.locale = (String) inputMapData.get("locale", null); - java.util.Map inputOptions = (java.util.Map) inputMapData.get("options", null); + java.util.Map inputOptions = (java.util.Map) inputMapData.get( + "options", null); result.listType = ListFormatterType.getFromString( "" + inputOptions.get("list_type") @@ -68,7 +69,7 @@ public ITestTypeOutputJson getDefaultOutputJson() { @Override public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { ListFormatterOutputJson output = (ListFormatterOutputJson) outputJson; - return new io.lacuna.bifurcan.Map() + return new io.lacuna.bifurcan.Map() .put("label", output.label) .put("result", output.result); } @@ -84,27 +85,33 @@ public String getListFormatResultString(ListFormatterInputJson input) { ULocale locale = ULocale.forLanguageTag(input.locale); switch (input.listType) { - case DISJUNCTION: listType = Type.OR; + case DISJUNCTION: + listType = Type.OR; break; - case UNIT: listType = Type.UNITS; + case UNIT: + listType = Type.UNITS; break; default: - case CONJUNCTION: listType = Type.AND; + case CONJUNCTION: + listType = Type.AND; break; } switch (input.style) { - case NARROW: listWidth = Width.NARROW; + case NARROW: + listWidth = Width.NARROW; break; - case SHORT: listWidth = Width.SHORT; + case SHORT: + listWidth = Width.SHORT; break; default: - case LONG: listWidth = Width.WIDE; + case LONG: + listWidth = Width.WIDE; break; } ListFormatter lf = ListFormatter.getInstance(locale, listType, listWidth); - return lf.format(input.inputList); + return lf.format(input.inputList); } } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java index 2ea01d4a..426ee5c9 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java @@ -1,124 +1,136 @@ - package org.unicode.conformance.testtype.relativedatetimeformat; +package org.unicode.conformance.testtype.relativedatetimeformat; - import com.ibm.icu.text.DisplayContext; - import com.ibm.icu.text.NumberFormat; - import com.ibm.icu.text.RelativeDateTimeFormatter; - import com.ibm.icu.text.RelativeDateTimeFormatter.Style; - import com.ibm.icu.util.ULocale; +import com.ibm.icu.text.DisplayContext; +import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.text.RelativeDateTimeFormatter; +import com.ibm.icu.text.RelativeDateTimeFormatter.Style; +import com.ibm.icu.util.ULocale; - import io.lacuna.bifurcan.IMap; - import io.lacuna.bifurcan.Map; +import io.lacuna.bifurcan.IMap; +import io.lacuna.bifurcan.Map; - import org.unicode.conformance.ExecutorUtils; - import org.unicode.conformance.testtype.ITestType; - import org.unicode.conformance.testtype.ITestTypeInputJson; - import org.unicode.conformance.testtype.ITestTypeOutputJson; +import org.unicode.conformance.ExecutorUtils; +import org.unicode.conformance.testtype.ITestType; +import org.unicode.conformance.testtype.ITestTypeInputJson; +import org.unicode.conformance.testtype.ITestTypeOutputJson; - public class RelativeDateTimeFormatTester implements ITestType { +public class RelativeDateTimeFormatTester implements ITestType { - public static RelativeDateTimeFormatTester INSTANCE = new RelativeDateTimeFormatTester(); + public static RelativeDateTimeFormatTester INSTANCE = new RelativeDateTimeFormatTester(); - @Override - public ITestTypeInputJson inputMapToJson(Map inputMapData) { - RelativeDateTimeFormatInputJson result = new RelativeDateTimeFormatInputJson(); + @Override + public ITestTypeInputJson inputMapToJson(Map inputMapData) { + RelativeDateTimeFormatInputJson result = new RelativeDateTimeFormatInputJson(); - result.label = (String) inputMapData.get("label", null); - result.locale = (String) inputMapData.get("locale", null); - result.count = (String) inputMapData.get("count", "0"); - result.quantity = Double.parseDouble(result.count); + result.label = (String) inputMapData.get("label", null); + result.locale = (String) inputMapData.get("locale", null); + result.count = (String) inputMapData.get("count", "0"); + result.quantity = Double.parseDouble(result.count); - result.numberingSystem = (String) inputMapData.get("numbering_system", null); + result.numberingSystem = (String) inputMapData.get("numbering_system", null); - java.util.Map inputOptions = - (java.util.Map) inputMapData.get("options", null); + java.util.Map inputOptions = + (java.util.Map) inputMapData.get("options", null); - result.style = RelativeDateTimeFormatStyle.getFromString( - "" + inputOptions.get("style") - ); + result.style = RelativeDateTimeFormatStyle.getFromString( + "" + inputOptions.get("style") + ); - String unitInput = (String) inputMapData.get("unit", "0"); - result.unit = RelativeDateTimeFormatUnits.getFromString( - unitInput); + String unitInput = (String) inputMapData.get("unit", "0"); + result.unit = RelativeDateTimeFormatUnits.getFromString( + unitInput); - return result; - } - - @Override - public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { - RelativeDateTimeFormatInputJson input = (RelativeDateTimeFormatInputJson) inputJson; + return result; + } - // partially construct output - RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) getDefaultOutputJson(); - output.label = input.label; + @Override + public ITestTypeOutputJson execute(ITestTypeInputJson inputJson) { + RelativeDateTimeFormatInputJson input = (RelativeDateTimeFormatInputJson) inputJson; - try { - output.result = getRelativeDateTimeFormatResultString(input); - } catch (Exception e) { - output.error = e.getMessage(); - output.error_message = e.getMessage(); - return output; - } + // partially construct output + RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) getDefaultOutputJson(); + output.label = input.label; - // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + try { + output.result = getRelativeDateTimeFormatResultString(input); + } catch (Exception e) { + output.error = e.getMessage(); + output.error_message = e.getMessage(); return output; } - @Override - public ITestTypeOutputJson getDefaultOutputJson() { - return new RelativeDateTimeFormatOutputJson(); - } + // If we get here, it's a pass/fail result (supported options and no runtime errors/exceptions) + return output; + } - public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { - RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) outputJson; - return new io.lacuna.bifurcan.Map() - .put("label", output.label) - .put("result", output.result); - } + @Override + public ITestTypeOutputJson getDefaultOutputJson() { + return new RelativeDateTimeFormatOutputJson(); + } - public String formatOutputJson(ITestTypeOutputJson outputJson) { - return ExecutorUtils.GSON.toJson(outputJson); + public IMap convertOutputToMap(ITestTypeOutputJson outputJson) { + RelativeDateTimeFormatOutputJson output = (RelativeDateTimeFormatOutputJson) outputJson; + return new io.lacuna.bifurcan.Map() + .put("label", output.label) + .put("result", output.result); + } + + public String formatOutputJson(ITestTypeOutputJson outputJson) { + return ExecutorUtils.GSON.toJson(outputJson); + } + + public String getRelativeDateTimeFormatResultString(RelativeDateTimeFormatInputJson input) { + ULocale locale = ULocale.forLanguageTag(input.locale); + Style style; + RelativeDateTimeFormatter.RelativeDateTimeUnit unit; + + switch (input.unit) { + default: + case DAY: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.DAY; + break; + case HOUR: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.HOUR; + break; + case MINUTE: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MINUTE; + break; + case MONTH: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MONTH; + break; + case QUARTER: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.QUARTER; + break; + case SECOND: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.SECOND; + break; + case WEEK: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.WEEK; + break; + case YEAR: + unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.YEAR; + break; } - public String getRelativeDateTimeFormatResultString(RelativeDateTimeFormatInputJson input) { - ULocale locale = ULocale.forLanguageTag(input.locale); - Style style; - RelativeDateTimeFormatter.RelativeDateTimeUnit unit; - - switch (input.unit) { - default: - case DAY: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.DAY; - break; - case HOUR: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.HOUR; - break; - case MINUTE: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MINUTE; - break; - case MONTH: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.MONTH; - break; - case QUARTER: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.QUARTER; - break; - case SECOND: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.SECOND; - break; - case WEEK: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.WEEK; - break; - case YEAR: unit = RelativeDateTimeFormatter.RelativeDateTimeUnit.YEAR; - break; - } - - switch (input.style) { - case NARROW: style = RelativeDateTimeFormatter.Style.NARROW; - break; - case SHORT: style = RelativeDateTimeFormatter.Style.SHORT; - break; - default: - case LONG: style = RelativeDateTimeFormatter.Style.LONG; - break; - } - - NumberFormat nf = null; - DisplayContext dc = DisplayContext.CAPITALIZATION_NONE; - - RelativeDateTimeFormatter rdtf = - RelativeDateTimeFormatter.getInstance(locale, nf, style, dc); - - return rdtf.format(input.quantity, unit); + + switch (input.style) { + case NARROW: + style = RelativeDateTimeFormatter.Style.NARROW; + break; + case SHORT: + style = RelativeDateTimeFormatter.Style.SHORT; + break; + default: + case LONG: + style = RelativeDateTimeFormatter.Style.LONG; + break; } + + NumberFormat nf = null; + DisplayContext dc = DisplayContext.CAPITALIZATION_NONE; + + RelativeDateTimeFormatter rdtf = + RelativeDateTimeFormatter.getInstance(locale, nf, style, dc); + + return rdtf.format(input.quantity, unit); } +} diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/datetimeformatter/DateTimeFormatterTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/datetimeformatter/DateTimeFormatterTest.java new file mode 100644 index 00000000..07f12318 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/datetimeformatter/DateTimeFormatterTest.java @@ -0,0 +1,73 @@ +package org.unicode.conformance.datetimeformatter; + +import org.junit.Ignore; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterOutputJson; +import org.unicode.conformance.testtype.datetimeformatter.DateTimeFormatterTester; + +public class DateTimeFormatterTest { + + @Test + public void TestDateTime49() { + String testInput = + "{\"test_type\": \"datetime_fmt\", \"input_string\":\"2024-03-07T00:00:01-08:00[America/Los_Angeles][u-ca=gregory]\",\"skeleton\":\"j\",\"locale\":\"en-US\",\"options\":{\"hour\":\"numeric\",\"calendar\":\"gregory\",\"timeZone\":\"America/Los_Angeles\",\"numberingSystem\":\"latn\"},\"hexhash\":\"30c5191c8041eb6d8afa05aab80f811753bc082f\",\"label\":\"49\"}"; + + DateTimeFormatterOutputJson output = + (DateTimeFormatterOutputJson) DateTimeFormatterTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + assertEquals("12 AM", output.result); + } + + @Test + public void TestDateTime15455() { + String testInput = + "{\"test_type\": \"datetime_fmt\", \"input_string\":\"2001-09-09T01:46:40-07:00[America/Los_Angeles]\",\"skeleton\":\"vvvv\",\"locale\":\"zu\",\"options\":{\"timeZoneName\":\"longGeneric\",\"calendar\":\"persian\",\"timeZone\":\"America/Los_Angeles\",\"numberingSystem\":\"latn\"},\"hexhash\":\"d4cfde2db66f8d4aec9254fc66ef2db298d7a0ba\",\"label\":\"15455\"}"; + + DateTimeFormatterOutputJson output = + (DateTimeFormatterOutputJson) DateTimeFormatterTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + assertEquals("Isikhathi sase-North American Pacific", output.result); + } + + @Ignore + @Test + public void testDateTime0() { + String testInput = + "{\"test_type\":\"datetime_fmt\", \"input_string\":\"2024-03-07T00:00:01+00:00[UTC][u-ca=gregory]\",\"locale\":\"en-US\",\"options\":{\"dateStyle\":\"short\",\"timeStyle\":\"short\",\"calendar\":\"gregory\",\"timeZone\":\"UTC\",\"numberingSystem\":\"latn\"},\"hexhash\":\"048d17f248ef4f6835d6b9b3bcbfdc934f3fcad5\",\"label\":\"0\"}"; + + DateTimeFormatterOutputJson output = + (DateTimeFormatterOutputJson) DateTimeFormatterTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("3/7/24, 12:00 AM", output.result); + } + + @Ignore + @Test + public void testDateTime3864() { + String testInput = + "{\"test_type\":\"datetime_fmt\",\"input_string\":\"2024-03-07T00:00:01+00:00[UTC][u-ca=gregory]\",\"locale\":\"zh-TW\",\"options\":{\"dateStyle\":\"short\",\"timeStyle\":\"short\",\"calendar\":\"gregory\",\"timeZone\":\"UTC\",\"numberingSystem\":\"latn\"},\"hexhash\":\"2f22cb2c0656fd092d12c17b2545cec4ca9f23b3\",\"label\":\"3864\"}"; + + DateTimeFormatterOutputJson output = + (DateTimeFormatterOutputJson) DateTimeFormatterTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("2024/3/7 凌晨12:00", output.result); + } + + @Ignore + @Test + public void testDateTime17387() { + + String testInput = "\t{\"test_type\":\"datetime_fmt\",\"input_string\":\"2001-09-09T01:46:40+10:00[Australia/Brisbane]\",\"skeleton\":\"vvvv\",\"locale\":\"und\",\"options\":{\"timeZoneName\":\"longGeneric\",\"calendar\":\"persian\",\"timeZone\":\"Australia/Brisbane\",\"numberingSystem\":\"latn\"},\"hexhash\":\"8a39dcac98f0487ead82dedd3447bdf393b35081\",\"label\":\"17387\"}"; + + DateTimeFormatterOutputJson output = + (DateTimeFormatterOutputJson) DateTimeFormatterTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("3/7/24, 12:00 AM", output.result); + } + +} \ No newline at end of file diff --git a/run_config.json b/run_config.json index ff64329a..e86e3ee8 100644 --- a/run_config.json +++ b/run_config.json @@ -317,6 +317,7 @@ "exec": "icu4j", "test_type": [ "collation_short", + "datetime_fmt", "lang_names", "likely_subtags", "list_fmt", @@ -338,6 +339,7 @@ "exec": "icu4j", "test_type": [ "collation_short", + "datetime_fmt", "lang_names", "likely_subtags", "list_fmt", @@ -359,6 +361,7 @@ "exec": "icu4j", "test_type": [ "collation_short", + "datetime_fmt", "lang_names", "likely_subtags", "list_fmt", From 9fb3f87263efea40153f742bda7d22a0b6d24c5c Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 8 Aug 2024 17:15:05 -0700 Subject: [PATCH 10/26] Add known issues to Summary page and details for DateTime formatting (#256) * Add plural rules to CPP * Add the Rust datetime fmt code * Rust datetime fmt and updates to ICU4C and NodeJS (#240) * Add plural rules to CPP * Starting ICU4X datetime fmt * DateTime format: Set default timezone explicitly * Fix formatting * Added ICU4X timezone computation - not working yet! * DateTime generator updated to ISO formatted string * DateTime updates for Node and ICU4C. * Formatted src/datetimefmt.rs * Updated using CustomTimeZone in ICU4X date time fmt * Cargo clippified * Remove unused function * Update version to ~1.3 * Known issues now being computed and shown in reports * Add diff output for both failing tests and known issues * Known issues for date/time now displayed * Removing this unneeded file * Remove unused known_issues_data.csv * Update schema/check_test_output.py Co-authored-by: Elango Cheran * Update testdriver/ddtargs.py Co-authored-by: Elango Cheran * Update testdriver/ddtargs.py Co-authored-by: Elango Cheran * Changed structure of code computing known issues. * Reorder and rename functions in check_known_issues.py * renaming test_data --> test * Update test for replaced digits * Update verifier/check_known_issues.py Co-authored-by: Elango Cheran --------- Co-authored-by: Elango Cheran --- schema/check_test_output.py | 2 +- testdriver/ddtargs.py | 7 +- testdriver/testdriver.py | 6 +- verifier/check_known_issues.py | 172 +++++++++++++++++++++ verifier/detail_template.html | 76 +++++----- verifier/testreport.py | 264 ++++++++++++++++----------------- verifier/verifier.py | 34 +++-- 7 files changed, 374 insertions(+), 187 deletions(-) create mode 100644 verifier/check_known_issues.py diff --git a/schema/check_test_output.py b/schema/check_test_output.py index fb5fadf6..68a6a5da 100644 --- a/schema/check_test_output.py +++ b/schema/check_test_output.py @@ -55,7 +55,7 @@ def main(args): test_type = schema_files.TEST_FILE_TO_TEST_TYPE_MAP[test_file_prefix] test_type_set.add(test_type) except BaseException as err: - logging.error('!!! %s for file %s', err, file + logging.info('No file (%s) during schema check output: %s', file, err ) for dir in icu_dirs: icu_version_set.add(os.path.basename(dir)) diff --git a/testdriver/ddtargs.py b/testdriver/ddtargs.py index 4ebdc317..6a2a07bb 100644 --- a/testdriver/ddtargs.py +++ b/testdriver/ddtargs.py @@ -60,8 +60,8 @@ def __init__(self, args): self.parser.add_argument('--custom_verifier', default=None) # self.parser.add_argument( - '--run_serially', default=None, - help='Execute tests in series rather than in parallel') + '--run_serial', default=None, + help='Set if execution should be done serially. Parallel is the default.') self.options = self.parser.parse_args(args) @@ -93,6 +93,9 @@ def __init__(self, args): self.parser.add_argument('--test_verifier', help='Flag to run in test mode', default=None) + self.parser.add_argument('--run_serial', default=None, + help='Set if execution should be done serially. Parallel is the default.') + self.options = self.parser.parse_args(args) return diff --git a/testdriver/testdriver.py b/testdriver/testdriver.py index 95e5c893..a696acfd 100644 --- a/testdriver/testdriver.py +++ b/testdriver/testdriver.py @@ -29,7 +29,7 @@ def __init__(self): self.test_plans = [] self.debug = False - self.run_serially = False # Default is to operate in parallel + self.run_serial = False # Default is to operate in parallel logging.config.fileConfig("../logging.conf") @@ -40,7 +40,7 @@ def set_args(self, arg_options): self.icuVersion = arg_options.icu_version self.cldrVersion = arg_options.cldr - self.run_serially = arg_options.run_serially + self.run_serial = arg_options.run_serial # Create "test plans" for each option for test_type in arg_options.test_type: @@ -125,7 +125,7 @@ def main(args): # print('ARGS = %s' % (args)) driver.parse_args(args[1:]) - if driver.run_serially: + if driver.run_serial: driver.run_plans() else: driver.run_plans_parallel() diff --git a/verifier/check_known_issues.py b/verifier/check_known_issues.py new file mode 100644 index 00000000..f5e59cec --- /dev/null +++ b/verifier/check_known_issues.py @@ -0,0 +1,172 @@ +# Functions to handle Known Issue category of results + + +from report_template import reportTemplate + +from collections import defaultdict +from enum import Enum + +from difflib import HtmlDiff +from difflib import Differ +from difflib import SequenceMatcher + +from datetime import datetime + +import glob +import json +import logging +import logging.config +import os +from string import Template +import sys + +sys.path.append('../testdriver') +import datasets as ddt_data + +# For information on characters and scripts +import unicodedata + +# Handle known issues database + +# Automatically compute some known issues with certain patterns of differences +# in actual output vs. expected + +# E.g., NBSP vs SP in NodeJS DateTime in ICU73, ... + +# Constants +NBSP = '\u202f' +SP = '\u0020' + + +# Global KnownIssue Info types and strings +class knownIssueType(Enum): + known_issue_nbsp_sp = 'ASCII Space instead of NBSP' + known_issue_replaced_numerals = 'Not creating non-ASCII numerals' + +# TODO! Load known issues from file of known problems rather than hardcoding the detection in each test + +# Tests for specific kinds of known issues +def diff_nbsp_vs_ascii_space(actual, expected_value): + # Returns the ID of this if the only difference in the two strings + # is Narrow Non-breaking Space (NBSP) in expected vs. ASCII space in the actual result. + # Found in datetime testing. + if not expected_value or not actual: + return None + + # If replacing all the NBSP characdters in expected gives the actual result, + # then the only differences were with this type of space in formatted output. + if expected_value.replace(NBSP, SP) == actual: + return knownIssueType.known_issue_nbsp_sp + else: + return None + + +def numerals_replaced_by_another_numbering_system(expected, actual): + # If the only difference are one type of digit + # where other digits were expected, return True + # Found in datetime testing. + # Returns an known issue ID (or string) if the the numbering system changed + + # sm_opcodes describe the change to turn expected string into the actual string + # See https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.get_opcodes + sm = SequenceMatcher(None, expected, actual) + sm_opcodes = sm.get_opcodes() + + digit_replace = False + non_digit_replacement = False + + # sm_opcodes describe the changes to turn expected string into the actual string + # See https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.get_opcodes + # The tuple is [tag, i1, i2, j1, j2] + # Tag indicates the type of change. + # i1:i2 is the range of the substring in expected + # j1:j2 is the range of the substring in actual + + for diff in sm_opcodes: + tag = diff[0] # 'replace', 'delete', 'insert', or 'equal' + old_val = expected[diff[1]:diff[2]] + new_val = actual[diff[3]:diff[4]] + if tag == 'replace': + # expected[i1:i2] was replaced by actual[j1:j2] + if old_val.isdigit() and new_val.isdigit(): + # TODO!! : check the value of the numeral + # If the same value, then its a numbering system difference + if unicodedata.numeric(old_val) == unicodedata.numeric(new_val): + digit_replace = True + else: + # Both were digits but different numeric values + non_digit_replacement = True + else: + # a digit was replaced with a non-digit + non_digit_replacement = True + + # Only true if the only changes were replacing digits + if digit_replace and not non_digit_replace: + return knownIssueType.known_issue_replaced_numerals + else: + return None + + +def check_datetime_known_issues(test): + # Examine a single test for date/time isses + # Returns known issues identified for this test in this category + remove_this_one = False + try: + result = test['result'] + expected = test['expected'] + is_ki = diff_nbsp_vs_ascii_space(result, expected) + if is_ki: + # Mark the test with this issue + test['known_issue'] = knownIssueType.known_issue_nbsp_sp.value + remove_this_one = True + + is_ki = numerals_replaced_by_another_numbering_system(result, expected) + if is_ki: + test['known_issue_id'] = knownIssueType.known_issue_replaced_numerals.value + remove_this_one = True + + except BaseException as err: + # Can't get the info + pass + + return remove_this_one + + +def compute_known_issues_for_single_test(test_type, test): + # Based on the type of test, check known issues against the expected vs. actual + # results + + # Returns True if this single test is an example of one or moore known issues, + known_issue_found = False + if test_type == ddt_data.testType.datetime_fmt.value: + known_issue_found = check_datetime_known_issues(test) + + # TODO: Add checks here for known issues in other test types + + return known_issue_found + +def check_issues(test_type, test_results_to_check): + # Look at the array of test result types, failure, error, unsupported + # Extract any tests from these that are known issues + # Return the list of tests that are known issues + # + known_issues_list = [] + + for category in test_results_to_check: + test_indices_with_known_issues = set() + index = 0 + + for test in category: + is_known_issue = compute_known_issues_for_single_test(test_type, test) + if is_known_issue: + known_issues_list.append(test) + test_indices_with_known_issues.add(index) + index += 1 + + # Remove those that were marked as known issues + # Reverse order to not confuse the position while deleting + rev_indices = sorted(test_indices_with_known_issues, reverse=True) + for index in rev_indices: + del category[index] + + return known_issues_list diff --git a/verifier/detail_template.html b/verifier/detail_template.html index 9c89cae4..2cad2d56 100644 --- a/verifier/detail_template.html +++ b/verifier/detail_template.html @@ -34,7 +34,7 @@ font-size:20px; } - #diff_area { + .diff_area { font-size: 24px; font-color: blue; } @@ -231,9 +231,9 @@ ['Results', 'Count', {role:'style'}], ['Passing', test_results['pass'].json.length, '#44ff77'], ['Failing', test_results['fail'].json.length, '#ff0000'], + ['Known issues', test_results['known_issue'].json.length, '#ff8200'], ['Errors', test_results['error'].json.length, '#ffdd00'], - ['Unsupported', test_results['unsupported'].json.length, '#777777'], - ['Known issues', test_results['known_issue'].json.length, '#ff8200'] + ['Unsupported', test_results['unsupported'].json.length, '#777777'] ]; const chart = new google.visualization.BarChart(chart_output_area); let chart_data = google.visualization.arrayToDataTable(input_data); @@ -347,13 +347,19 @@ fill_pagination("#characterized-pagination-container_" + item_type, "#characterized-data-container_" + item_type, selected_json_data, - "selected_" + item_type); + item_type); } // UL Template for pagination.js function simpleTemplating(data, c_type) { let possible_fields = ['label', 'expected', 'result', 'error', 'error_detail', 'options', 'input_data', 'actual_options']; + // Support output to different regions, depending on the type + // of the data, e.g., "fail", "known_issue", etc. + const diff_area_name = "diff_area_" + c_type; + const onclick_call = + '"captureInputDataOnClick(this);" onmouseover="hoverDiffText(this,' + diff_area_name + ');"'; + let table_opening = ''; @@ -377,7 +383,7 @@ } else { output = item[key]; } - html.push(''); + html.push(''); } } html.push(""); @@ -637,8 +643,9 @@ navigator.clipboard.writeText(output); } - // On hover, show the differen between expected and actual result. - function hoverDiffText(element) { + // On hover, show the difference between expected and actual result + // in the named area. + function hoverDiffText(element, diff_area) { // First, get the row of this item. const row = element.parentNode; const text1 = row.children[1].innerHTML; @@ -651,7 +658,6 @@ dmp.diff_cleanupSemantic(diff_text); // And show the difference nicely. const ds = dmp.diff_prettyHtml(diff_text); - const diff_area = document.getElementById("diff_area"); diff_area.innerHTML = ds; } @@ -672,7 +678,7 @@

$platform_info

$total_tests attempted. Pass: $passing_tests, Fail: $failing_tests, Errors: $error_count, - Unsupported: $unsupported, + Unsupported: $unsupported

, Known issues: $unsupported

@@ -717,7 +723,7 @@

Acknowledgements

Failing tests ($failing_tests) -

+

@@ -741,6 +747,32 @@

Acknowledgements

+
+ Known issues ($known_issue_count) +

+
+
+
+
+ Known issues characterized +
+
+

Filtered count = 0 + + +

+
+
+
+
+
+
+
+
+
+
+
+
Test errors ($error_count)

Test Errors ($error_count)

@@ -793,30 +825,6 @@

Test Errors ($error_count)

-
- Known issues ($known_issue_count) -
-
-
-
- Known issues characterized -
-
-

Filtered count = 0 - - -

-
-
-
-
-
-
-
-
-
-
-
diff --git a/verifier/testreport.py b/verifier/testreport.py index a8071e37..1a79eb56 100644 --- a/verifier/testreport.py +++ b/verifier/testreport.py @@ -3,6 +3,9 @@ # TODO: get templates from this module instead of local class from report_template import reportTemplate +# For identifying test cases that are known problems +from check_known_issues import check_issues + from collections import defaultdict from difflib import HtmlDiff @@ -111,6 +114,7 @@ def __init__(self, report_path, report_html_path): self.passing_tests = [] self.test_errors = [] self.unsupported_cases = [] + self.known_issues = [] self.templates = templates = reportTemplate() @@ -161,7 +165,7 @@ def __init__(self, report_path, report_html_path): self.known_issue_data = result_class_data( 'known_issues', None, - None, # ?? templates.known_issue_table_template, + self.known_issue_summary_template, templates.known_issue_table_template, self.compute_known_issue_category_summary) @@ -196,6 +200,9 @@ def record_test_error(self, test): def record_unsupported(self, test): self.unsupported_cases.append(test) + def record_known_issue(self, test): + self.known_issues.append(test) + def record_missing_verify_data(self, test): self.missing_verify_data.append(test) @@ -208,21 +215,21 @@ def compute_test_error_summary(self, test_errors, group_tag): for error in test_errors: try: label = error['label'] - details = error.get('error_detail') + details = error.get('error_detail', None) if not details: # Try getting the group_tag - details = error.get(group_tag) + details = error.get(group_tag, None) if isinstance(details, str): detail = details group = group_tag else: - detail = details.get(group_tag) + detail = details.get(group_tag, None) group = group_tag if group: - if not groups.get(group): + if not groups.get(group, None): groups[group] = {detail: []} # insert empty list - if not groups[group].get(detail): + if not groups[group].get(detail, None): groups[group][detail] = [label] else: groups[group][detail].append(label) @@ -235,19 +242,19 @@ def compute_unsupported_category_summary(self, unsupported_cases, group_tag): # For the items, count messages and arguments for each groups = {} for case in unsupported_cases: - error_detail = case.get('error_detail') + error_detail = case.get('error_detail', None) label = case['label'] if isinstance(error_detail, str): detail = error_detail else: if isinstance(error_detail, dict): - detail = error_detail.get(group_tag) + detail = error_detail.get(group_tag, None) else: detail = error_detail # Specific for unsupported options - count instances of the detail value = str(detail) - if groups.get(value): + if groups.get(value, None): groups[value].append(label) else: groups[value] = [label] @@ -278,16 +285,22 @@ def create_report(self): report['platform'] = self.platform_info report['test_environment'] = self.test_environment report['timestamp'] = self.timestamp - report['failCount'] = len(self.failing_tests) + report['passCount'] = len(self.passing_tests) report['failingTests'] = self.failing_tests - report['unsupportedTests'] = len(self.unsupported_cases) - report['missing_verify_data'] = self.missing_verify_data - report['test_error_count'] = len(self.test_errors) + report['failCount'] = len(self.failing_tests) report['test_errors'] = self.test_errors + report['test_error_count'] = len(self.test_errors) + report['unsupported'] = self.unsupported_cases + report['unsupportedTests'] = len(self.unsupported_cases) + report['known_issues'] = self.known_issues + report['known_issue_count'] = len(self.known_issues) + + report['missing_verify_data'] = self.missing_verify_data + self.report = report return json.dumps(report) @@ -361,6 +374,17 @@ def combine_same_sets_of_labels(self, label_sets): return combined_dictionary + + def add_known_issues(self): + # Call functions to identify known issues, moving things from fail, error, and unsupported + # to known_issues as needed + new_known_issues = check_issues( + self.test_type, + [self.failing_tests, self.test_errors, self.unsupported_cases]) + + if new_known_issues: + self.known_issues.extend(new_known_issues) + def create_html_report(self): # Human-readable summary of test results if self.platform_info['icuVersion'] == 'unknown': @@ -387,8 +411,8 @@ def create_html_report(self): 'failing_tests': len(self.failing_tests), 'error_count': len(self.test_errors), 'unsupported_count': len(self.unsupported_cases), - 'known_issue_count': len(self.known_issues) - + 'known_issue_count': len(self.known_issues), + 'known_issues': self.known_issues # ... } @@ -405,31 +429,38 @@ def create_html_report(self): line = self.fail_line_template.safe_substitute(fail) fail_lines.append(line) - #html_map['failure_table_lines'] = '\n'.join(fail_lines) + # Call functions to identify known issues, moving things from fail, error, and unsupported + # to known_issues as needed + new_known_issues = check_issues( + self.test_type, + [self.failing_tests, self.test_errors, self.unsupported_cases]) + + if new_known_issues: + self.known_issues.extend(new_known_issues) + # Characterize successes, too. - pass_characterized = self.characterize_failures_by_options(self.passing_tests) + pass_characterized = self.characterize_results_by_options(self.passing_tests, 'pass') flat_combined_passing = self.flatten_and_combine(pass_characterized, None) self.save_characterized_file(flat_combined_passing, "pass") # Get and save failures, errors, unsupported - error_characterized = self.characterize_failures_by_options(self.test_errors) + error_characterized = self.characterize_results_by_options(self.test_errors, 'error') flat_combined_errors = self.flatten_and_combine(error_characterized, None) self.save_characterized_file(flat_combined_errors, "error") - unsupported_characterized = self.characterize_failures_by_options(self.unsupported_cases) + unsupported_characterized = self.characterize_results_by_options(self.unsupported_cases, 'unsupported') flat_combined_unsupported = self.flatten_and_combine(unsupported_characterized, None) self.save_characterized_file(flat_combined_unsupported, "unsupported") - - known_issues_characterized = self.characterize_failures_by_options(self.known_issues) + known_issues_characterized = self.characterize_results_by_options(self.known_issues, 'known_issue') flat_combined_known_issues = self.flatten_and_combine(known_issues_characterized, None) self.save_characterized_file(flat_combined_known_issues, "known_issues") # TODO: Should we compute top 3-5 overlaps for each set? # Flatten and combine the dictionary values - fail_characterized = self.characterize_failures_by_options(self.failing_tests) - fail_simple_diffs = self.check_simple_text_diffs() + fail_characterized = self.characterize_results_by_options(self.failing_tests, 'fail') + fail_simple_diffs = self.check_simple_text_diffs(self.failing_tests, 'fail') flat_combined_dict = self.flatten_and_combine(fail_characterized, fail_simple_diffs) self.save_characterized_file(flat_combined_dict, "fail") @@ -551,45 +582,26 @@ def flatten_and_combine(self, input_dict, input_simple): flat_combined_dict = self.combine_same_sets_of_labels(flat_items) return dict(sort_dict_by_count(flat_combined_dict)) - def characterize_failures_by_options(self, failing_tests): + def characterize_results_by_options(self, test_list, category): # User self.failing_tests, looking at options results = defaultdict(lambda : defaultdict(list)) results['locale'] = {} # Dictionary of labels for each locale - for test in failing_tests: + for test in test_list: # Get input_data, if available - input_data = test.get('input_data') + input_data = test.get('input_data', None) - try: - label = test['label'] - except: - label = '' - key_list = ['locale', 'locale_label', 'option', 'options', - 'language_label', - # Collation - # 'ignorePunctuation', 'compare_result', - 'compare_type', 'test_description', 'unsupported_options', 'rules', 'test_description', - 'warning' - # Number format - 'input_data', - 'notation', 'compactDisplay', 'style', 'currency', 'unit', 'roundingMode', - # list_fmt - 'type', 'input_list', - # date/time format - 'skeleton'] - - option_keys = ['notation', 'compactDisplay', 'style', 'currency', 'unit', 'roundingMode'] + label = test.get('label', '') + key_list = ['locale', 'locale_label', 'option', 'options'] + # Special case for locales for key in key_list: - try: - locale = input_data.get('locale') - except: - locale = None + locale = input_data.get('locale', None) if locale: if locale not in results['locale']: results['locale'][locale] = set() results['locale'][locale].add(label) - options = input_data.get('options') + options = input_data.get('options', None) if options: # Get each combo of key/value for k, value in options.items(): @@ -599,43 +611,41 @@ def characterize_failures_by_options(self, failing_tests): results[k][value] = set() results[k][value].add(label) - # Try fields in lang_names - for key in ['language_label', 'locale_label']: - try: - if input_data.get(key): - value = input_data[key] - if key not in results: - results[key] = {} - if value in results[key]: - results[key][value] = set() - results[key][value].add(label) - except: - continue - - # Try fields in likely_subtags - for key in ['option', 'locale']: - try: - if input_data.get(key): - value = input_data[key] - if key not in results: - results[key] = {} - if value not in results[key]: - results[key][value] = set() - results[key][value].add(label) - except: - continue - - for key in ['language_label', 'ignorePunctuation', 'compare_result', 'compare_type', 'test_description']: - try: - if test.get(key): # For collation results - value = test[key] - if key not in results: - results[key] = {} - if value not in results[key]: - results[key][value] = set() - results[key][value] = set(label) - except: - continue + key_list = ['locale', 'locale_label', 'option', 'options', + 'language_label', + # Collation + # 'ignorePunctuation', 'compare_result', + 'compare_type', 'test_description', 'unsupported_options', 'rules', 'test_description', + 'warning' + # Number format + 'input_data', + 'notation', 'compactDisplay', 'style', 'currency', 'unit', 'roundingMode', + # list_fmt + 'type', 'input_list', + # date/time format + 'skeleton', + 'language_label', 'locale_label', # in lang_names + 'option', 'locale', # in likely_subtags + 'language_label', 'ignorePunctuation', 'compare_result', 'compare_type', 'test_description' + ] + for key in key_list: + if test.get(key, None): # For collation results + value = test[key] + if key not in results: + results[key] = {} + if value not in results[key]: + results[key][value] = set() + results[key][value].add(label) + + ki_key_list = ['known_issue', 'known_issue_id'] + for key in ki_key_list: + if test.get(key, None): # For collation results + value = test[key] + if key not in results: + results[key] = {} + if value not in results[key]: + results[key][value] = set() + results[key][value].add(label) # Look at the input_data part of the test result # TODO: Check the error_detail and error parts, too. @@ -663,11 +673,11 @@ def characterize_failures_by_options(self, failing_tests): # Special case for input_data / options. special_key = 'options' - if input_data and input_data.get(special_key): + if input_data and input_data.get(special_key, None): options = input_data[special_key] self.add_to_results_by_key(label, results, options, test, options.keys()) - error_detail = test.get('error_detail') + error_detail = test.get('error_detail', None) if error_detail: error_keys = error_detail.keys() # ['options'] self.add_to_results_by_key(label, results, error_detail, test, error_keys) @@ -676,52 +686,42 @@ def characterize_failures_by_options(self, failing_tests): # TODO: Add replacing (...) with "-" for numbers # TODO: Find the largest intersections of these sets and sort by size - pass - return results # TODO: Use the following function to update lists. def add_to_results_by_key(self, label, results, input_data, test, key_list): if input_data: for key in key_list: - try: - if input_data.get(key): # For collation results - value = input_data.get(key) - if key == 'input_list': - if 'input_size' not in results: - results['input_size'] = {} - else: - results['input_size'].add(len(value)) - if key == 'rules': - value = 'RULE' # A special case to avoid over-characterization - if key not in results: - results[key] = {} - if value in results[key]: - results[key][value].add(label) + if input_data.get(key, None): # For collation results + value = input_data.get(key, None) + if key == 'input_list': + if 'input_size' not in results: + results['input_size'] = {} else: + results['input_size'].add(len(value)) + if key == 'rules': + value = 'RULE' # A special case to avoid over-characterization + if key not in results: + results[key] = {} + try: + if not results[key].get(value, None): results[key][value] = set() - results[key][value].add(label) - except: - continue - - def check_simple_text_diffs(self): + results[key][value].add(label) + except TypeError as err: + # value may not be hashable. This should be skipped + pass + def check_simple_text_diffs(self, test_list, category): results = defaultdict(list) - results['insert'] = set() - results['delete'] = set() - results['insert_digit'] = set() - results['insert_space'] = set() - results['delete_digit'] = set() - results['delete_space'] = set() - results['replace_digit'] = set() - results['replace_dff'] = set() - results['whitespace_diff'] = set() - results['replace'] = set() - results['parens'] = set() # Substitions of brackets for parens, etc. + all_checks = ['insert', 'delete', 'insert_digit', 'insert_space', 'delete_digit', + 'delete_space', 'replace_digit', 'replace_dff', 'whitespace_diff', + 'replace', 'parens'] + for check in all_checks: + results[check] = set() - for fail in self.failing_tests: + for fail in test_list: label = fail['label'] - actual = fail.get('result') - expected = fail.get('expected') + actual = fail.get('result', None) + expected = fail.get('expected', None) if (actual is None) or (expected is None): continue # Special case for differing by a single character. @@ -954,16 +954,16 @@ def fill_templates(self, result_data, result_cases, result_table_template, summa # For filling in templates for cases of passing, failing, errors, unsupported, known_issue result_class = result_data.name section_name = '%s_section' % result_class - summary_name = '%s_summary % result_class' + summary_name = '%s_summary' % result_class # TODO: Call this for each cases instead of duplicated lines if result_cases: case_lines = [] - test_table_name = 'test_%s_' % result_class + test_table_name = 'test_%s' % result_class options_name = '%s_options' % result_class options_string = '%s options' % result_class - # Create a table of all test errors. + # Create a table of all test results in this category. for unsupported in result_cases: line = result_data.result_table_template.safe_substitute(unsupported) case_lines.append(line) @@ -981,7 +981,7 @@ def fill_templates(self, result_data, result_cases, result_table_template, summa # ??? TODO: examine if "error" is correct below for key, labels in case_summary.items(): count = len(labels) - sub = {'error': key, 'count': count} + sub = {'known_issue': key, 'count': count} summary_lines.append( result_data.summary_template.safe_substitute(sub) ) @@ -1103,6 +1103,7 @@ def summarize_reports(self): 'pass_count': int(test_json['passCount']), 'error_count': int(test_json['test_error_count']), 'unsupported_count': len(test_json['unsupported']), + 'known_issue_count': int(test_json['known_issue_count']), 'missing_verify_count': len(test_json['missing_verify_data']), 'json_file_name': filename, 'html_file_name': relative_html_path, # Relative to the report base @@ -1110,13 +1111,6 @@ def summarize_reports(self): 'icu_version': icu_version, 'platform_version': '%s %s' % (platform['platform'], platform['platformVersion']) } - - # Handle this sepparately for now as we add known issue support - try: - test_results['known_issue_count'] = len(test_json['known_issue']) - except BaseException as err: - test_results['known_issue_count'] = 0 - except BaseException as err: logging.error('SUMMARIZE REPORTS for file %s. Error: %s' % (filename, err)) diff --git a/verifier/verifier.py b/verifier/verifier.py index 7df28707..da6e890b 100644 --- a/verifier/verifier.py +++ b/verifier/verifier.py @@ -47,6 +47,8 @@ def __init__(self): self.report = None self.reports = [] + self.run_in_parallel = True + # Set of [result filepath, verify filepath, report path] self.result_timestamp = None @@ -222,15 +224,20 @@ def setup_verify_plans(self): # Verify plans in parallel def parallel_verify_data_results(self): - num_processors = mp.cpu_count() - verify_plans = self.verify_plans - logging.info('JSON validation: %s processors for %s plans', - num_processors, len(verify_plans)) - - processor_pool = mp.Pool(num_processors) - with processor_pool as p: - result = p.map(self.verify_one_plan, verify_plans) - return result + if not self.options.run_serial: + num_processors = mp.cpu_count() + verify_plans = self.verify_plans + logging.info('JSON validation: %s processors for %s plans', + num_processors, len(verify_plans)) + + processor_pool = mp.Pool(num_processors) + with processor_pool as p: + result = p.map(self.verify_one_plan, verify_plans) + return result + else: + logging.info('Running serially!') + for vplan in self.verify_plans: + self.verify_one_plan(vplan) # For one VerifyPlan, get data and run verification def verify_one_plan(self, vplan): @@ -249,16 +256,19 @@ def verify_one_plan(self, vplan): vplan.setup_report_data() result = {'compare_success': True} + + # Do more analysis on the failures and compute known issues + vplan.report.summarize_failures() + + vplan.report.add_known_issues() # Save the results + if not vplan.report.save_report(): logging.error('!!! Could not save report for (%s, %s)', vplan.test_type, vplan.exec) else: vplan.report.create_html_report() - # Do more analysis on the failures - vplan.report.summarize_failures() - logging.debug('\nTEST RESULTS in %s for %s. %d tests found', vplan.exec, vplan.test_type, len(vplan.test_results)) From 13caff15fa6f1ad5787ad52cabdb1280b4fcc374 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 15 Aug 2024 14:09:05 -0700 Subject: [PATCH 11/26] Add CPP relative date time format (#270) * Add CPP relative date time format * Add numbering system to locale string * Fix many rdt_fmt tests in ICU4C. Add unsupported units as known issue * Add details to error return --- executors/cpp/Makefile | 2 +- executors/cpp/main.cpp | 6 +- executors/cpp/relativedatetime_fmt.cpp | 207 +++++++++++++++++++++++++ run_config.json | 12 +- verifier/check_known_issues.py | 36 +++++ verifier/testreport.py | 7 +- 6 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 executors/cpp/relativedatetime_fmt.cpp diff --git a/executors/cpp/Makefile b/executors/cpp/Makefile index 54bf418d..e0f9d312 100644 --- a/executors/cpp/Makefile +++ b/executors/cpp/Makefile @@ -15,7 +15,7 @@ TARGET=executor # All object files (C or C++) -OBJECTS=main.o coll.o datetime_fmt.o langnames.o likely_subtags.o list_fmt.o number_fmt.o plural_rules.o +OBJECTS=main.o coll.o datetime_fmt.o langnames.o likely_subtags.o list_fmt.o number_fmt.o plural_rules.o relativedatetime_fmt.o #### rules # Load in standard makefile definitions diff --git a/executors/cpp/main.cpp b/executors/cpp/main.cpp index c3639fef..ffa267d9 100644 --- a/executors/cpp/main.cpp +++ b/executors/cpp/main.cpp @@ -46,6 +46,7 @@ extern const string TestLikelySubtags(json_object *json_in); extern const string TestListFmt(json_object *json_in); extern const string TestNumfmt(json_object *json_in); extern const string TestPluralRules(json_object *json_in); +extern const string TestRelativeDateTimeFmt(json_object *json_in); /** * Main -- process command line, call tests or return data @@ -63,7 +64,8 @@ int main(int argc, const char** argv) { "list_fmt", "lang_names", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" }; for (std::string line; std::getline(cin, line);) { @@ -118,6 +120,8 @@ int main(int argc, const char** argv) { outputLine = TestLangNames(json_input); } else if (test_type == "plural_rules") { outputLine = TestPluralRules(json_input); + } else if (test_type == "rdt_fmt") { + outputLine = TestRelativeDateTimeFmt(json_input); } else { outputLine = "# BAD TEST " + test_type; } diff --git a/executors/cpp/relativedatetime_fmt.cpp b/executors/cpp/relativedatetime_fmt.cpp new file mode 100644 index 00000000..df425f57 --- /dev/null +++ b/executors/cpp/relativedatetime_fmt.cpp @@ -0,0 +1,207 @@ +/******************************************************************** + * testing icu4c relative datetime format + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "unicode/utypes.h" +#include "unicode/unistr.h" +#include "unicode/locid.h" +#include "unicode/numfmt.h" +#include "unicode/reldatefmt.h" +#include "unicode/udisplaycontext.h" + +using icu::Locale; +using icu::NumberFormat; +using icu::RelativeDateTimeFormatter; +using icu::UnicodeString; + +using std::cout; +using std::endl; +using std::string; + +UDateRelativeDateTimeFormatterStyle StringToStyleEnum(string style_string) { + if (style_string == "long") return UDAT_STYLE_LONG; + if (style_string == "short") return UDAT_STYLE_SHORT; + if (style_string == "narrow") return UDAT_STYLE_NARROW; + return UDAT_STYLE_LONG; // Default +} + +UDateRelativeUnit StringToRelativeUnitEnum(string unit_string) { + UDateRelativeUnit rel_unit; + if (unit_string == "day") { + return UDAT_RELATIVE_DAYS; + } else if (unit_string == "hour") { + return UDAT_RELATIVE_HOURS; + } else if (unit_string == "minute") { + return UDAT_RELATIVE_MINUTES; + } else if (unit_string == "month") { + return UDAT_RELATIVE_MONTHS; + } else if (unit_string == "second") { + return UDAT_RELATIVE_SECONDS; + } else if (unit_string == "week") { + return UDAT_RELATIVE_WEEKS; + } else if (unit_string == "year") { + return UDAT_RELATIVE_YEARS; + } + // A default + return UDAT_RELATIVE_DAYS; +} + +const string TestRelativeDateTimeFmt(json_object *json_in) { + UErrorCode status = U_ZERO_ERROR; + + json_object *label_obj = json_object_object_get(json_in, "label"); + string label_string = json_object_get_string(label_obj); + + UDisplayContext cap_context = UDISPCTX_CAPITALIZATION_NONE; + NumberFormat *nf = nullptr; + + // The locale for formatted output + json_object *locale_label_obj = json_object_object_get(json_in, "locale"); + string locale_string; + if (locale_label_obj) { + locale_string = json_object_get_string(locale_label_obj); + } else { + locale_string = "und"; + } + + json_object *unit_obj = json_object_object_get(json_in, "unit"); + string unit_string = json_object_get_string(unit_obj); + + json_object *count_obj = json_object_object_get(json_in, "count"); + string count_string = json_object_get_string(count_obj); + double quantity = std::stod(count_string); + + json_object *return_json = json_object_new_object(); + json_object_object_add(return_json, "label", label_obj); + + // Get fields out of the options if present + json_object* options_obj = json_object_object_get(json_in, "options"); + + string style_string = "long"; // Default + string numbering_system_string = ""; // Default + if (options_obj) { + json_object *style_obj = json_object_object_get(options_obj, "style"); + if (style_obj) { + style_string = json_object_get_string(style_obj); + } + json_object *ns_obj = json_object_object_get(options_obj, "numberingSystem"); + if (ns_obj) { + numbering_system_string = json_object_get_string(ns_obj); + } + } + + UDateRelativeDateTimeFormatterStyle + rdtf_style = StringToStyleEnum(style_string); + + UDateRelativeUnit rel_unit; + if (unit_string != "quarter") { + rel_unit = StringToRelativeUnitEnum(unit_string); + } else { + // This is not supported. + json_object_object_add( + return_json, + "error", + json_object_new_string("unsupported unit")); + json_object_object_add( + return_json, + "error_type", + json_object_new_string("unsupported")); + json_object_object_add( + return_json, + "unsupported", + json_object_new_string("Bad relative date time unit")); + + json_object *unit_name_obj = + json_object_new_string(unit_string.c_str()); + + // Include details about the failure + json_object *detail_obj = json_object_new_object(); + json_object_object_add(detail_obj, "unsupported_unit", + unit_name_obj); + json_object_object_add( + return_json, + "error_detail", + detail_obj); + + // This can't be processed so return now. + return json_object_to_json_string(return_json); + } + + // Add variants to the locale. + string locale_selection_string = locale_string; + if (numbering_system_string != "") { + locale_selection_string = + locale_string + "-u-nu-" + numbering_system_string; + } + + Locale display_locale(locale_selection_string.c_str()); + + // Construct a formatter + RelativeDateTimeFormatter + rdtf(display_locale, nf, rdtf_style, cap_context, status); + + if (U_FAILURE(status)) { + json_object_object_add( + return_json, + "error", + json_object_new_string("Error creating RelativeDateTimeFormatter")); + json_object_object_add( + return_json, + "error_detail", + json_object_new_string("no detail available")); + return json_object_to_json_string(return_json); + } + + UDateDirection direction = UDAT_DIRECTION_NEXT; + if (quantity < 0.0) { + direction = UDAT_DIRECTION_LAST; + } else if (quantity > 0.0) { + direction = UDAT_DIRECTION_NEXT; + } + + // The output of the formatting + UnicodeString formatted_result; + + rdtf.format(fabs(quantity), direction, rel_unit, formatted_result, status); + + if (U_FAILURE(status)) { + json_object_object_add( + return_json, + "error", + json_object_new_string("Error calling rdtf.format")); + return json_object_to_json_string(return_json); + } + + // Get the resulting value as a string + char test_result_string[1000] = ""; + formatted_result.extract( + test_result_string, 1000, nullptr, status); // ignore return value + + if (U_FAILURE(status)) { + json_object_object_add( + return_json, + "error", + json_object_new_string("Failed extracting test result")); + json_object_object_add( + return_json, + "error_detail", + json_object_new_string("no detail available")); + } else { + // Good calls all around. Send the result! + json_object_object_add(return_json, + "result", + json_object_new_string(test_result_string)); + } + + return json_object_to_json_string(return_json); +} diff --git a/run_config.json b/run_config.json index e86e3ee8..6b944052 100644 --- a/run_config.json +++ b/run_config.json @@ -36,7 +36,8 @@ "likely_subtags", "list_fmt", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" ], "per_execution": 10000 } @@ -57,7 +58,8 @@ "likely_subtags", "list_fmt", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" ], "per_execution": 10000 } @@ -78,7 +80,8 @@ "list_fmt", "likely_subtags", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" ], "per_execution": 10000 } @@ -99,7 +102,8 @@ "likely_subtags", "list_fmt", "number_fmt", - "plural_rules" + "plural_rules", + "rdt_fmt" ], "per_execution": 10000 } diff --git a/verifier/check_known_issues.py b/verifier/check_known_issues.py index f5e59cec..b12db7f4 100644 --- a/verifier/check_known_issues.py +++ b/verifier/check_known_issues.py @@ -43,6 +43,9 @@ class knownIssueType(Enum): known_issue_nbsp_sp = 'ASCII Space instead of NBSP' known_issue_replaced_numerals = 'Not creating non-ASCII numerals' + # Relative Date Time Format + known_issue_unsupported_unit = 'Unsupported unit' # https://github.com/unicode-org/conformance/issues/274 + # TODO! Load known issues from file of known problems rather than hardcoding the detection in each test # Tests for specific kinds of known issues @@ -106,6 +109,13 @@ def numerals_replaced_by_another_numbering_system(expected, actual): else: return None +def unsupported_unit_quarter(test): + input_data = test['input_data'] + if 'error' in test and test['error'] == 'unsupported unit': + return True + + return None + def check_datetime_known_issues(test): # Examine a single test for date/time isses @@ -131,6 +141,30 @@ def check_datetime_known_issues(test): return remove_this_one +def check_rdt_known_issues(test): + # ??? Do wwe need platform ID and/or icu version? + remove_this_one = False + try: + try: + result = test['result'] + except BaseException: + result = None + + try: + expected = test['expected'] + except BaseException: + expected = None + + is_ki = unsupported_unit_quarter(test) + if is_ki: + test['known_issue_id'] = knownIssueType.known_issue_unsupported_unit.value + remove_this_one = True + + except BaseException as err: + pass + + return remove_this_one + def compute_known_issues_for_single_test(test_type, test): # Based on the type of test, check known issues against the expected vs. actual @@ -140,6 +174,8 @@ def compute_known_issues_for_single_test(test_type, test): known_issue_found = False if test_type == ddt_data.testType.datetime_fmt.value: known_issue_found = check_datetime_known_issues(test) + elif test_type == ddt_data.testType.rdt_fmt.value: + known_issue_found = check_rdt_known_issues(test) # TODO: Add checks here for known issues in other test types diff --git a/verifier/testreport.py b/verifier/testreport.py index 1a79eb56..487275a2 100644 --- a/verifier/testreport.py +++ b/verifier/testreport.py @@ -679,8 +679,11 @@ def characterize_results_by_options(self, test_list, category): error_detail = test.get('error_detail', None) if error_detail: - error_keys = error_detail.keys() # ['options'] - self.add_to_results_by_key(label, results, error_detail, test, error_keys) + try: + error_keys = error_detail.keys() # ['options'] + self.add_to_results_by_key(label, results, error_detail, test, error_keys) + except AttributeError: + pass # TODO: Add substitution of [] for () # TODO: Add replacing (...) with "-" for numbers From 3a39ec1cd455eadb230c8074eab32c1a173feb69 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 15 Aug 2024 14:09:30 -0700 Subject: [PATCH 12/26] ICU4J Relative Date Time Format: Add number system to locale (#275) --- .../RelativeDateTimeFormatTester.java | 9 +++++++-- .../icu74/RelativeDateTimeFormatTest.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java index 426ee5c9..553ce97d 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java @@ -26,11 +26,16 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { result.locale = (String) inputMapData.get("locale", null); result.count = (String) inputMapData.get("count", "0"); result.quantity = Double.parseDouble(result.count); - - result.numberingSystem = (String) inputMapData.get("numbering_system", null); + result.numberingSystem = ""; java.util.Map inputOptions = (java.util.Map) inputMapData.get("options", null); + if (inputOptions != null) { + result.numberingSystem = (String) inputOptions.get("numberingSystem"); + if (result.numberingSystem != "") { + result.locale = result.locale + "-u-nu-" + result.numberingSystem; + } + } result.style = RelativeDateTimeFormatStyle.getFromString( "" + inputOptions.get("style") diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java index 2e6ac272..b03b4c93 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java @@ -85,4 +85,19 @@ public void testAdlamIn1Year() { assertEquals("in 𞥑𞥐y", output.result); } + + @Test + public void testArabicNumSystem() { + + // Expect Eastern Arabic numerals in the output + String testInput = + "\t{\"test_type\": \"rdt_fmt\", \"unit\":\"second\",\"count\":\"-100\",\"locale\":\"en-US\",\"options\":{\"numberingSystem\":\"arab\"},\"hexhash\":\"d12df88777f8c7f60130df51d2954e18ec42b9c8\",\"label\":\"704\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("١٠٠ seconds ago",output.result); +} + } From f3918c51b3c2a94eb7b9faffef0efeb12acec409 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 15 Aug 2024 14:13:14 -0700 Subject: [PATCH 13/26] message_fmt2: Add duplicate-variant error (#273) This error was recently added to the spec (see https://github.com/unicode-org/message-format-wg/commit/5612f3b0508d63770b218d581c465aae878f5573 ) --- schema/message_fmt2/testgen_schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/schema/message_fmt2/testgen_schema.json b/schema/message_fmt2/testgen_schema.json index a329bd34..d47e14a0 100644 --- a/schema/message_fmt2/testgen_schema.json +++ b/schema/message_fmt2/testgen_schema.json @@ -377,6 +377,7 @@ "missing-selector-annotation", "duplicate-declaration", "duplicate-option-name", + "duplicate-variant", "unresolved-variable", "unknown-function", "unsupported-expression", From 694cad24ec463f6a077b8ae9312f59666f8ca53c Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Fri, 16 Aug 2024 16:08:33 -0700 Subject: [PATCH 14/26] Adding ICU4C message format2 testing (#278) * Moving ahead on MF2 in CPP * More mf2 progerss * MF2 in ICU4C is compiling! * Restrict ICU4C MF2 to >= ICU 75 * Restrict ICU4C MF2 to >= ICU 75 * Add general method to check and return ICU errors * Add details on parse error * Updating error resturns --- executors/cpp/Makefile | 3 +- executors/cpp/main.cpp | 10 ++ executors/cpp/message_fmt2.cpp | 187 +++++++++++++++++++++++++++++++++ executors/cpp/util.cpp | 38 +++++++ run_config.json | 1 + 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 executors/cpp/message_fmt2.cpp create mode 100644 executors/cpp/util.cpp diff --git a/executors/cpp/Makefile b/executors/cpp/Makefile index e0f9d312..0534c2f4 100644 --- a/executors/cpp/Makefile +++ b/executors/cpp/Makefile @@ -15,7 +15,8 @@ TARGET=executor # All object files (C or C++) -OBJECTS=main.o coll.o datetime_fmt.o langnames.o likely_subtags.o list_fmt.o number_fmt.o plural_rules.o relativedatetime_fmt.o + +OBJECTS=main.o coll.o datetime_fmt.o langnames.o likely_subtags.o list_fmt.o message_fmt2.o number_fmt.o plural_rules.o relativedatetime_fmt.o util.o #### rules # Load in standard makefile definitions diff --git a/executors/cpp/main.cpp b/executors/cpp/main.cpp index ffa267d9..a703f718 100644 --- a/executors/cpp/main.cpp +++ b/executors/cpp/main.cpp @@ -44,6 +44,12 @@ extern const string TestDatetimeFmt(json_object *json_in); extern const string TestLangNames(json_object *json_in); extern const string TestLikelySubtags(json_object *json_in); extern const string TestListFmt(json_object *json_in); + +// This API was added in ICU75.1 +#if U_ICU_VERSION_MAJOR_NUM >= 75 +extern const string TestMessageFormat2(json_object *json_in); +#endif + extern const string TestNumfmt(json_object *json_in); extern const string TestPluralRules(json_object *json_in); extern const string TestRelativeDateTimeFmt(json_object *json_in); @@ -110,6 +116,10 @@ int main(int argc, const char** argv) { outputLine = TestCollator(json_input); } else if (test_type == "datetime_fmt") { outputLine = TestDatetimeFmt(json_input); +#if U_ICU_VERSION_MAJOR_NUM >= 75 + } else if (test_type == "message_fmt2") { + outputLine = TestMessageFormat2(json_input); +#endif } else if (test_type == "number_fmt") { outputLine = TestNumfmt(json_input); } else if (test_type == "likely_subtags") { diff --git a/executors/cpp/message_fmt2.cpp b/executors/cpp/message_fmt2.cpp new file mode 100644 index 00000000..bbff8288 --- /dev/null +++ b/executors/cpp/message_fmt2.cpp @@ -0,0 +1,187 @@ +/******************************************************************** + * testing message format 2 in C++ + */ + +#include + +#include + +// This API was added in ICU75.1 +#if U_ICU_VERSION_MAJOR_NUM >= 75 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +using icu::Locale; +using icu::message2::MessageFormatter; +using icu::message2::MessageArguments; +using icu::message2::Formattable; + +using icu::UnicodeString; + +using std::string; + +/* + * Check for ICU errors and add to output if needed. + */ + +extern const bool check_icu_error(UErrorCode error_code, + json_object *return_json, + string message_to_add_if_error); + +/* Based on this test file: + * https://github.com/unicode-org/icu/blob/main/icu4c/source/test/intltest/messageformat2test.cpp + */ +const string TestMessageFormat2(json_object *json_in) { + // label information + json_object *label_obj = json_object_object_get(json_in, "label"); + string label_string = json_object_get_string(label_obj); + + json_object *locale_label_obj = json_object_object_get(json_in, "locale"); + string locale_string = "und"; + if (locale_label_obj) { + locale_string = json_object_get_string(locale_label_obj); + } + + const Locale displayLocale(locale_string.c_str()); + + string src_string; + json_object *src_obj = json_object_object_get(json_in, "src"); + UnicodeString u_src; + if (src_obj) { + src_string = json_object_get_string(src_obj); + u_src = src_string.c_str(); + } + + string test_description_string; + json_object *test_description_obj = + json_object_object_get(json_in, "test_description"); + if (test_description_obj) { + test_description_string = json_object_get_string(test_description_obj); + } + + // Start filling the return data. + json_object *return_json = json_object_new_object(); + json_object_object_add(return_json, "label", label_obj); + + json_object* param_list_obj = json_object_object_get(json_in, "params"); + + string params_name; + UnicodeString u_params_name; + string params_value; + UnicodeString u_params_value; + + // Get all the argements from test params + std::map argsBuilder; + + if (param_list_obj) { + array_list* param_list = json_object_get_array(param_list_obj); + + // For each item in the params list, get the name and value. + // Add to the builder. + int params_length = json_object_array_length(param_list_obj); + + // Construct the list of Unicode Strings + for (int i = 0; i < params_length; i++) { + json_object* param_obj = json_object_array_get_idx(param_list_obj, i); + + // Get the fields from this indexed element of the param_list + json_object *params_name_obj = json_object_object_get(param_obj, "name"); + json_object *params_value_obj = + json_object_object_get(param_obj, "value"); + + if (params_name_obj && params_value_obj) { + params_name = json_object_get_string(params_name_obj); + u_params_name = params_name.c_str(); + + params_value = json_object_get_string(params_value_obj); + u_params_value = params_value.c_str(); + + argsBuilder[u_params_name] = Formattable(u_params_value); + } else { + // Bail out due to incomplete parameter + if (check_icu_error( + U_MESSAGE_PARSE_ERROR, + return_json, "incomplete param name / value")) { + return json_object_to_json_string(return_json); + } + } + } // End of parameter loop + } // End parameter list processing + + UParseError parseError; + UErrorCode errorCode = U_ZERO_ERROR; + + MessageFormatter::Builder builder(errorCode); + if (check_icu_error(errorCode, return_json, "contructing builder")) { + return json_object_to_json_string(return_json); + } + + MessageFormatter mf = builder.setPattern(u_src, parseError, errorCode) + .setLocale(displayLocale) + .build(errorCode); + if (parseError.line > 0) { + // Information on position and preContext / postContext of parse error + string precontext_string, postcontext_string; + UnicodeString preContext = parseError.preContext; + preContext.toUTF8String(precontext_string); + UnicodeString postContext = parseError.postContext; + postContext.toUTF8String(postcontext_string); + + // Build a message with all parsing info. + string message = "Parse error on line: " + + std::to_string(parseError.line) + + " at offset: " + + std::to_string(parseError.offset) + + " precontext: " + + precontext_string + + " postcontext: " + + postcontext_string; + + if (check_icu_error(U_PARSE_ERROR, return_json, message.c_str())) { + return json_object_to_json_string(return_json); + } + } + + if (check_icu_error(errorCode, return_json, "build.setPattern")) { + return json_object_to_json_string(return_json); + } + + MessageArguments args(argsBuilder, errorCode); + if (check_icu_error(errorCode, return_json, "construction args")) { + return json_object_to_json_string(return_json); + } + + UnicodeString result_ustring = mf.formatToString(args, errorCode); + if (check_icu_error(errorCode, return_json, "formatToString")) { + return json_object_to_json_string(return_json); + } + + int32_t chars_out; // Extracted characters from Unicode string + char test_result[1000] = ""; + + // Get the resulting value and return JSON result. + string result_string; + result_ustring.toUTF8String(result_string); + + // It worked! + json_object_object_add(return_json, + "result", json_object_new_string(result_string.c_str())); + + return json_object_to_json_string(return_json); +} + +#endif // U_ICU_VERSION_MAJOR_NUM >= 75 diff --git a/executors/cpp/util.cpp b/executors/cpp/util.cpp new file mode 100644 index 00000000..7a66e52a --- /dev/null +++ b/executors/cpp/util.cpp @@ -0,0 +1,38 @@ +/* + * Common functions for dealing with JSON data in conformance testing + */ + +#include + +#include + +#include +#include + +using std::string; + +/* Checks if the result is an error. If not, return false. + If there's an error, add an error field and the given message + to the return_json object and return true. +*/ +const bool check_icu_error(UErrorCode error_code, + json_object *return_json, + string message_to_add_if_error) { + bool is_error = false; + + if (!U_FAILURE(error_code)) { + return is_error; + } + + is_error = true; + + const char* error_name = u_errorName(error_code); + json_object_object_add( + return_json, + "error", json_object_new_string(message_to_add_if_error.c_str())); + json_object_object_add( + return_json, + "error_detail", json_object_new_string(error_name)); + + return is_error; +} diff --git a/run_config.json b/run_config.json index 6b944052..90bf3fcb 100644 --- a/run_config.json +++ b/run_config.json @@ -101,6 +101,7 @@ "lang_names", "likely_subtags", "list_fmt", + "message_fmt2", "number_fmt", "plural_rules", "rdt_fmt" From 369f1e3a6042e8e6146ce108ba12bd599b3f8100 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 19 Aug 2024 14:29:21 -0700 Subject: [PATCH 15/26] relative date time format: add numeric options and use in format testing (#280) * Update relative date time data for both auto and always options * Add numberic option auto to test data for RDFT * Update CPP RDTF to handle numeric options * Respond to suggestions * Picky change --- executors/cpp/relativedatetime_fmt.cpp | 151 ++++++------------ .../RelativeDateFormatNumeric.java | 16 ++ .../RelativeDateTimeFormatInputJson.java | 2 + .../RelativeDateTimeFormatTester.java | 18 ++- .../icu74/RelativeDateTimeFormatTest.java | 23 +++ testgen/generators/rdt_fmt_gen.js | 149 ++++++++++++----- 6 files changed, 217 insertions(+), 142 deletions(-) create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateFormatNumeric.java diff --git a/executors/cpp/relativedatetime_fmt.cpp b/executors/cpp/relativedatetime_fmt.cpp index df425f57..7110c403 100644 --- a/executors/cpp/relativedatetime_fmt.cpp +++ b/executors/cpp/relativedatetime_fmt.cpp @@ -1,33 +1,37 @@ -/******************************************************************** +/* * testing icu4c relative datetime format */ +#include + #include -#include +#include +#include +#include +#include + #include #include -#include #include #include - -#include "unicode/utypes.h" -#include "unicode/unistr.h" -#include "unicode/locid.h" -#include "unicode/numfmt.h" -#include "unicode/reldatefmt.h" -#include "unicode/udisplaycontext.h" +#include using icu::Locale; using icu::NumberFormat; using icu::RelativeDateTimeFormatter; using icu::UnicodeString; -using std::cout; -using std::endl; using std::string; +/* + * Check for ICU errors and add to output if needed. + */ +extern const bool check_icu_error(UErrorCode error_code, + json_object *return_json, + string message_to_add_if_error); + UDateRelativeDateTimeFormatterStyle StringToStyleEnum(string style_string) { if (style_string == "long") return UDAT_STYLE_LONG; if (style_string == "short") return UDAT_STYLE_SHORT; @@ -35,25 +39,27 @@ UDateRelativeDateTimeFormatterStyle StringToStyleEnum(string style_string) { return UDAT_STYLE_LONG; // Default } -UDateRelativeUnit StringToRelativeUnitEnum(string unit_string) { - UDateRelativeUnit rel_unit; +URelativeDateTimeUnit StringToRelativeUnitEnum(string unit_string) { + URelativeDateTimeUnit rel_unit; if (unit_string == "day") { - return UDAT_RELATIVE_DAYS; + return UDAT_REL_UNIT_DAY; } else if (unit_string == "hour") { - return UDAT_RELATIVE_HOURS; + return UDAT_REL_UNIT_HOUR; } else if (unit_string == "minute") { - return UDAT_RELATIVE_MINUTES; + return UDAT_REL_UNIT_MINUTE; } else if (unit_string == "month") { - return UDAT_RELATIVE_MONTHS; + return UDAT_REL_UNIT_MONTH; } else if (unit_string == "second") { - return UDAT_RELATIVE_SECONDS; + return UDAT_REL_UNIT_SECOND; } else if (unit_string == "week") { - return UDAT_RELATIVE_WEEKS; + return UDAT_REL_UNIT_WEEK; + } else if (unit_string == "quarter") { + return UDAT_REL_UNIT_QUARTER; } else if (unit_string == "year") { - return UDAT_RELATIVE_YEARS; + return UDAT_REL_UNIT_YEAR; } // A default - return UDAT_RELATIVE_DAYS; + return UDAT_REL_UNIT_DAY; } const string TestRelativeDateTimeFmt(json_object *json_in) { @@ -89,53 +95,28 @@ const string TestRelativeDateTimeFmt(json_object *json_in) { string style_string = "long"; // Default string numbering_system_string = ""; // Default + string numeric_option = ""; if (options_obj) { json_object *style_obj = json_object_object_get(options_obj, "style"); if (style_obj) { style_string = json_object_get_string(style_obj); } - json_object *ns_obj = json_object_object_get(options_obj, "numberingSystem"); + json_object *ns_obj = json_object_object_get( + options_obj, "numberingSystem"); if (ns_obj) { numbering_system_string = json_object_get_string(ns_obj); } + json_object *numeric_obj = json_object_object_get(options_obj, "numeric"); + if (numeric_obj) { + numeric_option = json_object_get_string(numeric_obj); + } } UDateRelativeDateTimeFormatterStyle rdtf_style = StringToStyleEnum(style_string); - UDateRelativeUnit rel_unit; - if (unit_string != "quarter") { - rel_unit = StringToRelativeUnitEnum(unit_string); - } else { - // This is not supported. - json_object_object_add( - return_json, - "error", - json_object_new_string("unsupported unit")); - json_object_object_add( - return_json, - "error_type", - json_object_new_string("unsupported")); - json_object_object_add( - return_json, - "unsupported", - json_object_new_string("Bad relative date time unit")); - - json_object *unit_name_obj = - json_object_new_string(unit_string.c_str()); - - // Include details about the failure - json_object *detail_obj = json_object_new_object(); - json_object_object_add(detail_obj, "unsupported_unit", - unit_name_obj); - json_object_object_add( - return_json, - "error_detail", - detail_obj); - - // This can't be processed so return now. - return json_object_to_json_string(return_json); - } + URelativeDateTimeUnit rel_unit; + rel_unit = StringToRelativeUnitEnum(unit_string); // Add variants to the locale. string locale_selection_string = locale_string; @@ -150,58 +131,32 @@ const string TestRelativeDateTimeFmt(json_object *json_in) { RelativeDateTimeFormatter rdtf(display_locale, nf, rdtf_style, cap_context, status); - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("Error creating RelativeDateTimeFormatter")); - json_object_object_add( - return_json, - "error_detail", - json_object_new_string("no detail available")); + if (check_icu_error(status, return_json, "Constructor")) { return json_object_to_json_string(return_json); } - UDateDirection direction = UDAT_DIRECTION_NEXT; - if (quantity < 0.0) { - direction = UDAT_DIRECTION_LAST; - } else if (quantity > 0.0) { - direction = UDAT_DIRECTION_NEXT; - } - // The output of the formatting UnicodeString formatted_result; - rdtf.format(fabs(quantity), direction, rel_unit, formatted_result, status); + if (numeric_option == "auto") { + rdtf.format(quantity, rel_unit, formatted_result, status); + } else { + // Default is "always" + rdtf.formatNumeric(quantity, rel_unit, formatted_result, status); + } - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("Error calling rdtf.format")); + if (check_icu_error(status, return_json, "In format or formatNumeric")) { return json_object_to_json_string(return_json); } - // Get the resulting value as a string - char test_result_string[1000] = ""; - formatted_result.extract( - test_result_string, 1000, nullptr, status); // ignore return value - - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("Failed extracting test result")); - json_object_object_add( - return_json, - "error_detail", - json_object_new_string("no detail available")); - } else { - // Good calls all around. Send the result! - json_object_object_add(return_json, - "result", - json_object_new_string(test_result_string)); - } + // Get the resulting value as a string for output + string test_result_string; + formatted_result.toUTF8String(test_result_string); + + // Good calls all around. Send the result! + json_object_object_add(return_json, + "result", + json_object_new_string(test_result_string.c_str())); return json_object_to_json_string(return_json); } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateFormatNumeric.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateFormatNumeric.java new file mode 100644 index 00000000..79096f00 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateFormatNumeric.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.relativedatetimeformat; + +public enum RelativeDateFormatNumeric { + ALWAYS, + AUTO; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateFormatNumeric DEFAULT = ALWAYS; + + public static org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateFormatNumeric getFromString(String s) { + try { + return org.unicode.conformance.testtype.relativedatetimeformat.RelativeDateFormatNumeric.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java index 5f9328bb..2c31bae0 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatInputJson.java @@ -12,6 +12,8 @@ public class RelativeDateTimeFormatInputJson implements ITestTypeInputJson { public String numberingSystem; + public RelativeDateFormatNumeric numeric;// always (default) or auto + public String count; public RelativeDateTimeFormatUnits unit; diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java index 553ce97d..06273850 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/relativedatetimeformat/RelativeDateTimeFormatTester.java @@ -37,9 +37,13 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { } } - result.style = RelativeDateTimeFormatStyle.getFromString( - "" + inputOptions.get("style") - ); + if (inputOptions != null) { + result.style = RelativeDateTimeFormatStyle.getFromString( + "" + inputOptions.get("style")); + + result.numeric = RelativeDateFormatNumeric.getFromString( + "" + inputOptions.get("numeric")); + } String unitInput = (String) inputMapData.get("unit", "0"); result.unit = RelativeDateTimeFormatUnits.getFromString( @@ -136,6 +140,12 @@ public String getRelativeDateTimeFormatResultString(RelativeDateTimeFormatInputJ RelativeDateTimeFormatter rdtf = RelativeDateTimeFormatter.getInstance(locale, nf, style, dc); - return rdtf.format(input.quantity, unit); + String result; + if (input.numeric == RelativeDateFormatNumeric.ALWAYS) { + result = rdtf.formatNumeric(input.quantity, unit); + } else { + result = rdtf.format(input.quantity, unit); + } + return result; } } diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java index b03b4c93..a886a833 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/relativedatetimeformat/icu74/RelativeDateTimeFormatTest.java @@ -69,6 +69,29 @@ public void testEn100SAgo() { assertEquals("100s ago", output.result); } + @Test + public void testNumericAutoTomorrow() { + String testInput = + "\t{\"unit\":\"day\",\"count\":\"1\",\"locale\":\"en-US\",\"options\":{\"style\":\"narrow\", \"numeric\":\"auto\"},\"hexhash\":\"a57aac792\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("tomorrow", output.result); + } + + @Test + public void testNumericAlwaysInOneDay() { + String testInput = + "\t{\"unit\":\"day\",\"count\":\"1\",\"locale\":\"en-US\",\"options\":{\"style\":\"long\", \"numeric\":\"always\"},\"hexhash\":\"a57aac792\",\"label\":\"0\"}"; + + RelativeDateTimeFormatOutputJson output = + (RelativeDateTimeFormatOutputJson) RelativeDateTimeFormatTester.INSTANCE.getStructuredOutputFromInputStr( + testInput); + + assertEquals("in 1 day", output.result); + } @Ignore // This doesn't yet handle non-ASCII numbering systems // https://github.com/unicode-org/conformance/issues/261 diff --git a/testgen/generators/rdt_fmt_gen.js b/testgen/generators/rdt_fmt_gen.js index 5dd9af28..3d319445 100644 --- a/testgen/generators/rdt_fmt_gen.js +++ b/testgen/generators/rdt_fmt_gen.js @@ -6,6 +6,7 @@ 4. numeric 5. unit, e.g., 'day' 6. value: in the range of min to max + 7. numeric: 'always' and 'auto' unless the resutls are equal */ // Set up Node version to generate data specific to ICU/CLDR version @@ -46,6 +47,64 @@ const numeric = ['auto', 'always']; const counts = [-100, -4, -2, -1, 0, 1, 1.3, 2, 3, 4, 10]; +function sample_tests(all_tests, run_limit) { + // Gets a sampling of the data based on total and the expected number. + + if (run_limit < 0 || all_tests.length <= run_limit) { + return all_tests; + } + + let size_all = all_tests.length; + let increment = Math.floor(size_all / run_limit); + let samples = []; + for (let index = 0; index < size_all; index += increment) { + samples.push(all_tests[index]); + } + return samples; +} + +// Create the test and verify JSON data for this case. +function save_test(unit, count, locale, all_options, result, label_num, + test_cases, verify_cases) { + const label_string = String(label_num); + // Without label + let test_case = { + 'unit': unit, + 'count': String(count), + }; + + if (locale != '') { + test_case["locale"] = locale; + } + + if (all_options != null) { + test_case["options"] = {...all_options}; + } + + if (debug) { + console.log("TEST CASE :", test_case); + } + + gen_hash.generate_hash_for_test(test_case); + test_case['label'] = label_string; + + test_cases.push(test_case); + + // Generate what we get. + try { + verify_cases.push({'label': label_string, + 'verify': result}); + if (debug) { + console.log(' expected = ', result); + } + } catch (error) { + console.log('!!! error ', error, ' in label ', label_num); + } + +} + + + function generateAll() { let test_obj = { @@ -68,6 +127,8 @@ function generateAll() { } let verify_cases = []; + // How many are different between numeric auto vs. always + let diff_count = 0; let label_num = 0; const expected_count = locales.length * @@ -95,12 +156,27 @@ function generateAll() { all_options['numberingSystem'] = number_system; } - let formatter; + // Create to sets of options + let all_options_numeric_always = {...all_options, 'numeric': 'always'}; + let all_options_numeric_auto = {...all_options, 'numeric': 'auto'}; + + let formatter_numeric_always; try { - formatter = new Intl.RelativeTimeFormat(locale, all_options); + formatter_numeric_always = + new Intl.RelativeTimeFormat(locale, all_options_numeric_always); } catch (error) { console.log(error, ' with locale ', - locale, ' and options: ', all_options); + locale, ' and options: ', all_options_numeric_always); + continue; + } + + let formatter_numeric_auto; + try { + formatter_numeric_auto = + new Intl.RelativeTimeFormat(locale, all_options_numeric_auto); + } catch (error) { + console.log(error, ' with locale ', + locale, ' and options: ', all_options_numeric_auto); continue; } @@ -111,49 +187,33 @@ function generateAll() { for (const unit of units) { for (const count of counts) { + let result_always; + let result_auto; + try { - result = formatter.format(count, unit); + result_always = formatter_numeric_always.format(count, unit); } catch (error) { console.log('FORMATTER CREATION FAILS! ', error); } - const label_string = String(label_num); - - // Without label - let test_case = { - 'unit': unit, - 'count': String(count), - }; - - if (locale != '') { - test_case["locale"] = locale; - } - - if (all_options != null) { - test_case["options"] = {...all_options}; - } - - if (debug) { - console.log("TEST CASE :", test_case); + try { + result_auto = formatter_numeric_auto.format(count, unit); + } catch (error) { + console.log('FORMATTER CREATION FAILS! ', error); } - gen_hash.generate_hash_for_test(test_case); - test_case['label'] = label_string; + // Always save the "auto" form. + save_test(unit, count, locale, all_options_numeric_auto, result_auto, label_num, test_cases, verify_cases); + label_num ++; - test_cases.push(test_case); + if (result_always != result_auto) { + // Since results are different, save the "always" form, too. + diff_count += 1; + // console.log(' DIFFERENT RESULTS: %s vs %s', result_always, result_auto); - // Generate what we get. - try { - verify_cases.push({'label': label_string, - 'verify': result}); - if (debug) { - console.log(' expected = ', result); - } - } catch (error) { - console.log('!!! error ', error, ' in label ', label_num, - ' for date = ', d); + save_test(unit, count, locale, all_options_numeric_always, result_always, label_num, test_cases, verify_cases); + label_num ++; } - label_num ++; } } } @@ -163,16 +223,17 @@ function generateAll() { console.log('Number of relative date/time tests generated for ', process.versions.icu, ': ', label_num); + console.log(' %d tests are different between numeric auto and always', diff_count); - test_obj['tests'] = test_cases; + test_obj['tests'] = sample_tests(test_cases, run_limit); try { - fs.writeFileSync('rdt_fmt_test.json', JSON.stringify(test_obj, null)); + fs.writeFileSync('rdt_fmt_test.json', JSON.stringify(test_obj, null, 2)); // file written successfully } catch (err) { console.error(err); } - verify_obj['verifications'] = verify_cases; + verify_obj['verifications'] = sample_tests(verify_cases, run_limit); try { fs.writeFileSync('rdt_fmt_verify.json', JSON.stringify(verify_obj, null, 2)); // file written successfully @@ -182,4 +243,12 @@ function generateAll() { } /* Call the generator */ -generateAll(); +let run_limit = -1; +if (process.argv.length >= 5) { + if (process.argv[3] == '-run_limit') { + run_limit = Number(process.argv[4]); + } +} + +/* Call the generator */ +generateAll(run_limit); From 1eea44cf32924ba400b06db2872646bd4e980368 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 19 Aug 2024 16:51:32 -0700 Subject: [PATCH 16/26] Clean up .cpp files, revising error reporting, adding util.h (#282) * Revising error reporting, adding util.h * These now fail in exectuation. * Working OK now * Lint fixes * Remove unneeded code in coll. Minor fix in dateteime * Update conversions from UnicodeString to string in results * Update .gitignore --- .gitignore | 3 + executors/cpp/coll.cpp | 151 ++++++++----------------- executors/cpp/datetime_fmt.cpp | 49 +++----- executors/cpp/langnames.cpp | 22 ++-- executors/cpp/likely_subtags.cpp | 2 + executors/cpp/list_fmt.cpp | 42 +++---- executors/cpp/message_fmt2.cpp | 13 +-- executors/cpp/number_fmt.cpp | 15 ++- executors/cpp/plural_rules.cpp | 46 +++----- executors/cpp/relativedatetime_fmt.cpp | 14 ++- executors/cpp/util.cpp | 3 + executors/cpp/util.h | 14 +++ 12 files changed, 142 insertions(+), 232 deletions(-) create mode 100644 executors/cpp/util.h diff --git a/.gitignore b/.gitignore index 9c8b9621..f3a9415b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ logrotate.state # Maven dependency-reduced-pom.xml + +# Dart +executors/dart/.dart_tool/ \ No newline at end of file diff --git a/executors/cpp/coll.cpp b/executors/cpp/coll.cpp index f9f59e54..e240bed1 100644 --- a/executors/cpp/coll.cpp +++ b/executors/cpp/coll.cpp @@ -29,6 +29,8 @@ #include #include +#include "./util.h" + using std::cout; using std::endl; using std::string; @@ -40,6 +42,8 @@ using icu::RuleBasedCollator; const char error_message[] = "error"; +bool debug = false; + /** * TestCollator -- process JSON inputs, run comparator, return result */ @@ -124,7 +128,6 @@ const string TestCollator(json_object *json_in) { json_object *return_json = json_object_new_object(); json_object_object_add(return_json, "label", label_obj); - bool no_error = true; int uni_result; // Create a C++ collator and try it. @@ -132,35 +135,21 @@ const string TestCollator(json_object *json_in) { RuleBasedCollator *rb_coll = nullptr; if (rules_string != "") { - char uni_rules_out[1000] = ""; - uni_rules.extract(uni_rules_out, 1000, nullptr, status); // ignore length + string uni_rules_string; + // TODO: Check if this is needed. + uni_rules.toUTF8String(uni_rules_string); // Make sure normalization is consistent rb_coll = new RuleBasedCollator(uni_rules, UCOL_ON, status); - if (U_FAILURE(status)) { - test_result = error_message; - // TODO: report the error in creating the instance - cout << "# Error in making RuleBasedCollator: " << - label_string << " : " << test_result << endl; - - json_object_object_add( - return_json, - "error", json_object_new_string("create rule based collator")); - no_error = false; + if (check_icu_error(status, return_json, "create RuleBasedCollator")) { + return json_object_to_json_string(return_json); } uni_result = rb_coll->compare(us1, us2, status); - if (U_FAILURE(status)) { - test_result = error_message; - - json_object_object_add( - return_json, - "error", json_object_new_string("error in rb_coll->compare")); - no_error = false; - cout << "# Error in rb_coll->compare: " << - label_string << " : " << - test_result << endl; + if (check_icu_error(status, return_json, "rb_coll->compare")) { + return json_object_to_json_string(return_json); } + // Don't need this anymore. delete rb_coll; } else { @@ -171,29 +160,16 @@ const string TestCollator(json_object *json_in) { uni_coll = Collator::createInstance(Locale(locale_string), status); } - if (U_FAILURE(status)) { - test_result = error_message; - json_object_object_add( - return_json, - "error", json_object_new_string("error creating collator instance")); - no_error = false; - cout << "# Error in createInstance: " << - label_string << " : " << - test_result << endl; + if (check_icu_error( + status, return_json, "create collator instance")) { + return json_object_to_json_string(return_json); } // Make sure normalization is consistent uni_coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); - if (U_FAILURE(status)) { - test_result = error_message; - json_object_object_add( - return_json, - "error", - json_object_new_string("error setting normalization to UCOL_ON")); - no_error = false; - cout << "# Error in setAttribute: " << - label_string << " : " << - test_result << endl; + if (check_icu_error( + status, return_json, "error setting normalization to UCOL_ON")) { + return json_object_to_json_string(return_json); } if (strength_obj) { @@ -204,89 +180,58 @@ const string TestCollator(json_object *json_in) { const bool ignore_punctuation_bool = json_object_get_boolean(ignore_obj); if (ignore_punctuation_bool) { uni_coll->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); - if (U_FAILURE(status)) { - test_result = error_message; - json_object_object_add( - return_json, - "error", json_object_new_string("error setAttribute")); - no_error = false; - cout << "# Error in setAttribute: " << - label_string << " : " << - test_result << endl; + if (check_icu_error( + status, return_json, + "set UCOL_ALTERNATE_HANDLING to UCOL_SHIFTED")) { + return json_object_to_json_string(return_json); } } } // Just to check the result. uni_coll->getAttribute(UCOL_ALTERNATE_HANDLING, status); // ignore return + if (check_icu_error( + status, return_json, + "getet UCOL_ALTERNATE_HANDLING")) { + return json_object_to_json_string(return_json); + } // Perform the string comparison uni_result = uni_coll->compare(us1, us2, status); - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", json_object_new_string("error in uni_coll_compare")); - no_error = false; - cout << "## Error in uni_coll->compare: " << - label_string << " : " << - error_message << endl; + if (check_icu_error( status, return_json, "uni_coll_compare")) { + return json_object_to_json_string(return_json); } + if (uni_coll) { uni_coll->getAttribute(UCOL_ALTERNATE_HANDLING, status); // ignore result } delete uni_coll; + if (check_icu_error( status, return_json, "uni_coll->getATTRIBUTE")) { + return json_object_to_json_string(return_json); + } } - if (no_error) { - if (uni_result == UCOL_GREATER) { - coll_result = false; - + coll_result = (uni_result != UCOL_GREATER); + if (!coll_result) { + // Test did not succeed! + if (debug) { cout << "# UNI_RESULT: " << label_string << " " << uni_result << " s1: " << string1 << " s2: " << string2 << endl; - - // Check unescaped versions. - char char_out1[1000] = ""; - char char_out2[1000] = ""; - us1.extract(char_out1, 1000, nullptr, status); // ignore result - if (U_FAILURE(status)) { - test_result = error_message; - json_object_object_add( - return_json, - "error", json_object_new_string("error extracting us1")); - cout << "# Error in us1.extract: " << - label_string << " : " << - test_result << endl; - } - - us2.extract(char_out2, 1000, nullptr, status); // ignore result - if (U_FAILURE(status)) { - test_result = error_message; - // TODO: report the error in creating the instance - test_result = error_message; - json_object_object_add( - return_json, - "error", json_object_new_string("error extracting us2")); - cout << "# Error in us2.extract: " << - label_string << " : " << - test_result << endl; - } - - // Include data compared in the failing test - json_object_object_add( - return_json, "s1", json_object_new_string(string1.c_str())); - json_object_object_add( - return_json, "s2", json_object_new_string(string2.c_str())); - - // Record the actual returned value - json_object_object_add( - return_json, "compare", json_object_new_int64(uni_result)); - } else { - coll_result = true; } + // Include data compared in the failing test json_object_object_add( - return_json, "result", json_object_new_boolean(coll_result)); + return_json, "s1", json_object_new_string(string1.c_str())); + json_object_object_add( + return_json, "s2", json_object_new_string(string2.c_str())); + + // Record the actual returned value + json_object_object_add( + return_json, "compare", json_object_new_int64(uni_result)); } + json_object_object_add( + return_json, "result", json_object_new_boolean(coll_result)); + return json_object_to_json_string(return_json); } diff --git a/executors/cpp/datetime_fmt.cpp b/executors/cpp/datetime_fmt.cpp index eb133a4e..4cab9ab9 100644 --- a/executors/cpp/datetime_fmt.cpp +++ b/executors/cpp/datetime_fmt.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include "unicode/utypes.h" @@ -21,6 +20,8 @@ #include "unicode/uclean.h" +#include "./util.h" + using icu::Calendar; using icu::DateFormat; using icu::Locale; @@ -161,11 +162,7 @@ const string TestDatetimeFmt(json_object *json_in) { display_locale, status); } - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("Error in createInstanceForSkeleton")); + if (check_icu_error(status, return_json, "createInstanceForSkeleton")) { return json_object_to_json_string(return_json); } } else { @@ -205,7 +202,7 @@ const string TestDatetimeFmt(json_object *json_in) { // SimpleDateFormat can't parse options or timezone offset // First, remove options starting with "[" - std:size_t pos = input_date_string.find("["); + std::size_t pos = input_date_string.find("["); if (pos >= 0) { input_date_string = input_date_string.substr(0, pos); } @@ -238,19 +235,10 @@ const string TestDatetimeFmt(json_object *json_in) { } // Get date from the parser if possible. - test_date_time = iso_date_fmt.parse(date_ustring, status); - - if (U_FAILURE(status)) { - string error_message = "# iso_date_fmt parse failure: " + - input_date_string + " " + - u_errorName(status); - - json_object_object_add( - return_json, - "error", - json_object_new_string(error_message.c_str())); - + if (check_icu_error(status, + return_json, + "# iso_date_fmt parse failure" + input_date_string)) { return json_object_to_json_string(return_json); } } else if (input_millis) { @@ -265,27 +253,18 @@ const string TestDatetimeFmt(json_object *json_in) { return json_object_to_json_string(return_json); } - // The output of the formatting + // The output of the formatting step UnicodeString formatted_result; - df->format(test_date_time, formatted_result); // Get the resulting value as a string - char test_result_string[1000] = ""; - formatted_result.extract( - test_result_string, 1000, nullptr, status); // ignore return value + string result_string; + formatted_result.toUTF8String(result_string); - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("Failed extracting test result")); - } else { - // Good calls all around. Send the result! - json_object_object_add(return_json, - "result", - json_object_new_string(test_result_string)); - } + // Good calls all around. Send the result! + json_object_object_add(return_json, + "result", + json_object_new_string(result_string.c_str())); return json_object_to_json_string(return_json); } diff --git a/executors/cpp/langnames.cpp b/executors/cpp/langnames.cpp index 38cdff6c..4d9add5c 100644 --- a/executors/cpp/langnames.cpp +++ b/executors/cpp/langnames.cpp @@ -17,6 +17,8 @@ #include #include +#include "./util.h" + using std::cout; using std::endl; using std::string; @@ -48,24 +50,16 @@ const string TestLangNames (json_object *json_in) { UnicodeString testLang; testLocale.getDisplayName(displayLocale, testLang); - // The following gives only the language name, without region information - /// testLocale.getDisplayLanguage(displayLocale, testLang); json_object *return_json = json_object_new_object(); json_object_object_add(return_json, "label", label_obj); - char test_result_string[1000] = ""; - - testLang.extract(test_result_string, 1000, nullptr, status); // ignore return - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", json_object_new_string("langnames extract error")); - } else { - json_object_object_add(return_json, - "result", - json_object_new_string(test_result_string)); - } + string result_string; + testLang.toUTF8String(result_string); + + json_object_object_add(return_json, + "result", + json_object_new_string(result_string.c_str())); string return_string = json_object_to_json_string(return_json); return return_string; diff --git a/executors/cpp/likely_subtags.cpp b/executors/cpp/likely_subtags.cpp index 85db2fac..5cda131e 100644 --- a/executors/cpp/likely_subtags.cpp +++ b/executors/cpp/likely_subtags.cpp @@ -17,6 +17,8 @@ #include #include +#include "./util.h" + using std::string; using icu::Locale; diff --git a/executors/cpp/list_fmt.cpp b/executors/cpp/list_fmt.cpp index ece56fbe..99913f41 100644 --- a/executors/cpp/list_fmt.cpp +++ b/executors/cpp/list_fmt.cpp @@ -3,11 +3,11 @@ */ #include +#include + #include #include -#include #include -#include #include #include @@ -18,12 +18,17 @@ #include #include +#include "./util.h" + using icu::ListFormatter; using icu::Locale; using icu::UnicodeString; +using std::cout; +using std::endl; using std::string; +/* Main test function */ const string TestListFmt (json_object* json_in) { UErrorCode status = U_ZERO_ERROR; @@ -58,6 +63,7 @@ const string TestListFmt (json_object* json_in) { } u_strings_size = u_strings.size(); } else { + // TODO: use error return function json_object_object_add( return_json, "error", @@ -96,10 +102,9 @@ const string TestListFmt (json_object* json_in) { format_type, format_width, status); - if (U_FAILURE(status)) { - json_object_object_add(return_json, - "error", - json_object_new_string("construct list formatter")); + if (check_icu_error(status, + return_json, "construct list formatter")) { + return json_object_to_json_string(return_json); } UnicodeString *u_array = &u_strings[0]; @@ -109,28 +114,15 @@ const string TestListFmt (json_object* json_in) { u_result_string, status); - char test_result_string[1000] = ""; - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("calling list format")); - } else { - u_result_string.extract( - test_result_string, 1000, nullptr, status); // result ignored + if (check_icu_error(status, return_json, "calling format")) { + return json_object_to_json_string(return_json); } - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("list format result extract error")); - } else { - // It all seems to work! - json_object_object_add(return_json, + string result_string; + u_result_string.toUTF8String(result_string); + json_object_object_add(return_json, "result", - json_object_new_string(test_result_string)); - } + json_object_new_string(result_string.c_str())); // The JSON output. return json_object_to_json_string(return_json); diff --git a/executors/cpp/message_fmt2.cpp b/executors/cpp/message_fmt2.cpp index bbff8288..e02d0bc7 100644 --- a/executors/cpp/message_fmt2.cpp +++ b/executors/cpp/message_fmt2.cpp @@ -25,6 +25,8 @@ #include #include +#include "./util.h" + using icu::Locale; using icu::message2::MessageFormatter; using icu::message2::MessageArguments; @@ -34,14 +36,6 @@ using icu::UnicodeString; using std::string; -/* - * Check for ICU errors and add to output if needed. - */ - -extern const bool check_icu_error(UErrorCode error_code, - json_object *return_json, - string message_to_add_if_error); - /* Based on this test file: * https://github.com/unicode-org/icu/blob/main/icu4c/source/test/intltest/messageformat2test.cpp */ @@ -170,9 +164,6 @@ const string TestMessageFormat2(json_object *json_in) { return json_object_to_json_string(return_json); } - int32_t chars_out; // Extracted characters from Unicode string - char test_result[1000] = ""; - // Get the resulting value and return JSON result. string result_string; result_ustring.toUTF8String(result_string); diff --git a/executors/cpp/number_fmt.cpp b/executors/cpp/number_fmt.cpp index 6b1b4cb7..f5dc12e0 100644 --- a/executors/cpp/number_fmt.cpp +++ b/executors/cpp/number_fmt.cpp @@ -33,6 +33,8 @@ #include #include +#include "./util.h" + using std::cout; using std::endl; using std::string; @@ -426,7 +428,6 @@ const string TestNumfmt(json_object *json_in) { int32_t chars_out; // Results of extracting characters from Unicode string bool no_error = true; - char test_result[1000] = ""; LocalizedNumberFormatter nf; if (notation_string == "scientific") { @@ -498,7 +499,8 @@ const string TestNumfmt(json_object *json_in) { } // Get the resulting value as a string - number_result.extract(test_result, 1000, nullptr, status); // ignore result + string test_result; + number_result.toUTF8String(test_result); if (U_FAILURE(status)) { // Report a failure @@ -512,16 +514,19 @@ const string TestNumfmt(json_object *json_in) { // It worked! json_object_object_add(return_json, "result", - json_object_new_string(test_result)); + json_object_new_string(test_result.c_str())); } } // To see what was actually used. UnicodeString u_skeleton_out = nf.toSkeleton(status); - u_skeleton_out.extract(test_result, 1000, nullptr, status); // result ignored + + string skeleton_string; + u_skeleton_out.toUTF8String(skeleton_string); + json_object_object_add(return_json, "actual_skeleton", - json_object_new_string(test_result)); + json_object_new_string(skeleton_string.c_str())); string return_string = json_object_to_json_string(return_json); return return_string; diff --git a/executors/cpp/plural_rules.cpp b/executors/cpp/plural_rules.cpp index 33cb5829..31a6cfac 100644 --- a/executors/cpp/plural_rules.cpp +++ b/executors/cpp/plural_rules.cpp @@ -14,6 +14,8 @@ #include #include +#include "./util.h" + using icu::Locale; using icu::PluralRules; using icu::UnicodeString; @@ -93,16 +95,11 @@ const string TestPluralRules (json_object* json_in) { return json_object_to_json_string(return_json); } - PluralRules* prules = icu::PluralRules::forLocale( - display_locale, - plural_type, - status); + PluralRules* prules = + icu::PluralRules::forLocale(display_locale, plural_type, status); - if (U_FAILURE(status)) { - json_object_object_add(return_json, - "error", - json_object_new_string("construct plural rules")); - return json_object_to_json_string(return_json); + if (check_icu_error(status, return_json, "contruct plural rules")) { + return json_object_to_json_string(return_json); } // TODO: distinguish between ints, doubles, and compact values @@ -126,31 +123,14 @@ const string TestPluralRules (json_object* json_in) { return json_object_to_json_string(return_json); } - char test_result_string[1000] = ""; - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("calling plural rules select")); - return json_object_to_json_string(return_json); - } else { - u_result.extract( - test_result_string, 1000, nullptr, status); // ignore result - } + string result_string; + u_result.toUTF8String(result_string); - if (U_FAILURE(status)) { - json_object_object_add( - return_json, - "error", - json_object_new_string("plural rules result extract error")); - return json_object_to_json_string(return_json); - } else { - // It all seems to work! - json_object_object_add( - return_json, - "result", - json_object_new_string(test_result_string)); - } + // It all seems to work! + json_object_object_add( + return_json, + "result", + json_object_new_string(result_string.c_str())); // The JSON output. return json_object_to_json_string(return_json); diff --git a/executors/cpp/relativedatetime_fmt.cpp b/executors/cpp/relativedatetime_fmt.cpp index 7110c403..df20ca0a 100644 --- a/executors/cpp/relativedatetime_fmt.cpp +++ b/executors/cpp/relativedatetime_fmt.cpp @@ -18,6 +18,8 @@ #include #include +#include "./util.h" + using icu::Locale; using icu::NumberFormat; using icu::RelativeDateTimeFormatter; @@ -101,8 +103,8 @@ const string TestRelativeDateTimeFmt(json_object *json_in) { if (style_obj) { style_string = json_object_get_string(style_obj); } - json_object *ns_obj = json_object_object_get( - options_obj, "numberingSystem"); + json_object *ns_obj = + json_object_object_get(options_obj, "numberingSystem"); if (ns_obj) { numbering_system_string = json_object_get_string(ns_obj); } @@ -149,14 +151,14 @@ const string TestRelativeDateTimeFmt(json_object *json_in) { return json_object_to_json_string(return_json); } - // Get the resulting value as a string for output - string test_result_string; - formatted_result.toUTF8String(test_result_string); + // Get the resulting value as a string + string test_result; + formatted_result.toUTF8String(test_result); // Good calls all around. Send the result! json_object_object_add(return_json, "result", - json_object_new_string(test_result_string.c_str())); + json_object_new_string(test_result.c_str())); return json_object_to_json_string(return_json); } diff --git a/executors/cpp/util.cpp b/executors/cpp/util.cpp index 7a66e52a..05523403 100644 --- a/executors/cpp/util.cpp +++ b/executors/cpp/util.cpp @@ -2,6 +2,7 @@ * Common functions for dealing with JSON data in conformance testing */ + #include #include @@ -9,6 +10,8 @@ #include #include +#include "./util.h" + using std::string; /* Checks if the result is an error. If not, return false. diff --git a/executors/cpp/util.h b/executors/cpp/util.h new file mode 100644 index 00000000..0e488041 --- /dev/null +++ b/executors/cpp/util.h @@ -0,0 +1,14 @@ +/* + * Check for ICU errors and add to output if needed. + */ + +#include + +#include + +using std::string; + +extern const bool check_icu_error(UErrorCode error_code, + json_object *return_json, + string message_to_add_if_error); + From eb016078d1270193c621b7893e18df201b607bc2 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 19 Aug 2024 17:35:38 -0700 Subject: [PATCH 17/26] Remove "Node.js 18 sample tests", issue #250 (#284) --- .github/workflows/run-nodejs.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/run-nodejs.yml diff --git a/.github/workflows/run-nodejs.yml b/.github/workflows/run-nodejs.yml deleted file mode 100644 index db5619ab..00000000 --- a/.github/workflows/run-nodejs.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Run Node JS tests - -on: - push: - branches: [ main ] - pull_request: - branches: '*' - -jobs: - nodejs_18: - name: Run Node.js 18 sample tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 18.7.0 - uses: actions/setup-node@v3 - with: - node-version: 18.7.0 - - name: test sourcing nvm.sh - run: source "$HOME/.nvm/nvm.sh" - shell: bash - - name: test nvm command - shell: bash -l -eo pipefail {0} - run: nvm ls - - name: "Run Node.js collator sample" - shell: bash -l -eo pipefail {0} - run: | - source "$HOME/.nvm/nvm.sh" - cd testdriver - bash runAll_node_local.sh - cd ../verifier - bash verifyNode_local.sh From 806f49ea3f2f4a0aa23746ce775ac8d9e5dc25d6 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Tue, 20 Aug 2024 15:08:19 -0700 Subject: [PATCH 18/26] Rust rdtf numeric - supports auto and always options (#285) * Basic lint applied * Remove unneeded include * ICU4X: Add Numeric options for RDTF --- .../rust/1.3/src/relativedatetime_fmt.rs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/executors/rust/1.3/src/relativedatetime_fmt.rs b/executors/rust/1.3/src/relativedatetime_fmt.rs index 77dc37fa..d609e908 100644 --- a/executors/rust/1.3/src/relativedatetime_fmt.rs +++ b/executors/rust/1.3/src/relativedatetime_fmt.rs @@ -4,6 +4,7 @@ use fixed_decimal::FixedDecimal; use icu::locid::Locale; use icu_provider::DataLocale; +use icu::relativetime::options::Numeric; use icu::relativetime::{RelativeTimeError, RelativeTimeFormatter, RelativeTimeFormatterOptions}; use serde::{Deserialize, Serialize}; @@ -14,6 +15,7 @@ use serde_json::{json, Value}; struct RelativeDateTimeFormatterOptions { style: Option, numbering_system: Option, + numeric: Option, } fn get_formatter_from_unit_style( @@ -158,27 +160,21 @@ pub fn run_relativedatetimeformat_test(json_obj: &Value) -> Result formatter, From e35ad94246aed62ead3cf3fea8a36f3536b589e8 Mon Sep 17 00:00:00 2001 From: Elango Cheran Date: Tue, 20 Aug 2024 16:34:25 -0700 Subject: [PATCH 19/26] Add generated CLDR test data for locale display names for ICU v73-75 (#286) * Add generated CLDR test data for locale display names for ICU v73-75 * Improve docs about test generation, esp for locale display names --- testgen/README.md | 45 +- testgen/icu73/localeDisplayName.txt | 3020 ++++++++++++++++++++++++++ testgen/icu74/localeDisplayName.txt | 3072 +++++++++++++++++++++++++++ testgen/icu75/localeDisplayName.txt | 3071 ++++++++++++++++++++++++++ 4 files changed, 9207 insertions(+), 1 deletion(-) create mode 100644 testgen/icu73/localeDisplayName.txt create mode 100644 testgen/icu74/localeDisplayName.txt create mode 100644 testgen/icu75/localeDisplayName.txt diff --git a/testgen/README.md b/testgen/README.md index a7abf336..b197d0c6 100644 --- a/testgen/README.md +++ b/testgen/README.md @@ -1,4 +1,14 @@ -# testgen +# testgen - Test Data Generators + +Test data generation is about converting test data from its original form into JSON conforming to a schema that we design for that functionality component. + +The process of test data generation (for a particular component of functionality) entails: + +1. Finding the original source test data +2. Creating a JSON schema that is appropriate for the particular functionality component +3. Creating code to convert the original format to the new JSON format to be used by DDT + +## Usage Generate all test data: ```sh @@ -14,3 +24,36 @@ Show all options: ```sh python testdata_gen.py --help ``` + +## Prerequisites + +For some components, obtaining the original source test data requires manual work. +The following document some of those manual steps required: + +### Locale Display Names (aka lang_names) + +The code to generate locale display names test data was +[merged into CLDR after CLDR v45](https://github.com/unicode-org/cldr/pull/3728). + +In order to retroactively apply the test generator code to older versions of CLDR, +the following steps can be employed for a specific version of CLDR: + +1. checkout snapshot of old CLDR version + ``` + git co release-43 -b release-43-ddt-datagen + ``` +2. pull backwards the current desired version of the test data generator + ``` + git checkout main -- tools/cldr-code/src/main/java/org/unicode/cldr/tool/GenerateLocaleIDTestData.java + ``` +3. compile and run the generator from the right spot + ``` + pushd tools/cldr-code + mvn compile exec:java -DCLDR_DIR=/usr/local/google/home/elango/oss/cldr/mine/src -Dexec.mainClass=org.unicode.cldr.tool.GenerateLocaleIDTestData + popd + ``` +4. copy the generated test data file to the Conformance repo + ``` + cp ./common/testData/localeIdentifiers/localeDisplayName.txt ~/oss/conformance/testgen/icu73 + ``` + diff --git a/testgen/icu73/localeDisplayName.txt b/testgen/icu73/localeDisplayName.txt new file mode 100644 index 00000000..a46053e4 --- /dev/null +++ b/testgen/icu73/localeDisplayName.txt @@ -0,0 +1,3020 @@ +# Test data for locale display name generation +# Copyright © 1991-2024 Unicode, Inc. +# For terms of use, see http://www.unicode.org/copyright.html +# SPDX-License-Identifier: Unicode-DFS-2016 +# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/) +# Format: +# @locale= +# @languageDisplay=[standard|dialect] +# standard - always display additional subtags like region in parentheses +# dialect - form compounds like "Flemish" for nl_BE +# ; + +@locale=en +@languageDisplay=standard + + +# Simple cases: Language, script, region, variants + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + +#Note that the order of the variants is alphabetized before generating names + +en-Latn-GB-scouse-fonipa; English (Latin, United Kingdom, IPA Phonetics, Scouse) + +# Add extensions, and verify their order + +en-u-nu-deva-t-de; English (Transform: German, Devanagari Digits) +en-u-nu-thai-ca-islamic-civil; English (Islamic Calendar [tabular, civil epoch], Thai Digits) +hi-u-nu-latn-t-en-h0-hybrid; Hindi (Hybrid: English, Western Digits) + +# Test ordering of extensions (include well-formed but invalid cases) + +fr-z-zz-zzz-v-vv-vvv-u-uu-uuu-t-ru-Cyrl-s-ss-sss-a-aa-aaa-x-u-x; French (Transform: Russian [Cyrillic], uu: uuu, a: aa-aaa, s: ss-sss, v: vv-vvv, x: u-x, z: zz-zzz) + +# Comprehensive list (mostly comprehensive: currencies, subdivisions, timezones have abbreviated lists) + +en-u-ca-buddhist; English (Buddhist Calendar) +en-u-ca-chinese; English (Chinese Calendar) +en-u-ca-coptic; English (Coptic Calendar) +en-u-ca-dangi; English (Dangi Calendar) +en-u-ca-ethioaa; English (Ethiopic Amete Alem Calendar) +en-u-ca-ethiopic; English (Ethiopic Calendar) +en-u-ca-gregory; English (Gregorian Calendar) +en-u-ca-hebrew; English (Hebrew Calendar) +en-u-ca-indian; English (Indian National Calendar) +en-u-ca-islamic; English (Islamic Calendar) +en-u-ca-islamic-civil; English (Islamic Calendar [tabular, civil epoch]) +en-u-ca-islamic-rgsa; English (Islamic Calendar [Saudi Arabia, sighting]) +en-u-ca-islamic-tbla; English (Islamic Calendar [tabular, astronomical epoch]) +en-u-ca-islamic-umalqura; English (Islamic Calendar [Umm al-Qura]) +en-u-ca-iso8601; English (ISO-8601 Calendar) +en-u-ca-japanese; English (Japanese Calendar) +en-u-ca-persian; English (Persian Calendar) +en-u-ca-roc; English (Minguo Calendar) +en-u-cf-account; English (Accounting Currency Format) +en-u-cf-standard; English (Standard Currency Format) +en-u-co-big5han; English (Traditional Chinese Sort Order - Big5) +en-u-co-compat; English (Previous Sort Order, for compatibility) +en-u-co-dict; English (Dictionary Sort Order) +en-u-co-ducet; English (Default Unicode Sort Order) +en-u-co-emoji; English (Emoji Sort Order) +en-u-co-eor; English (European Ordering Rules) +en-u-co-gb2312; English (Simplified Chinese Sort Order - GB2312) +en-u-co-phonebk; English (Phonebook Sort Order) +en-u-co-phonetic; English (Phonetic Sort Order) +en-u-co-pinyin; English (Pinyin Sort Order) +en-u-co-reformed; English (Reformed Sort Order) +en-u-co-search; English (General-Purpose Search) +en-u-co-searchjl; English (Search By Hangul Initial Consonant) +en-u-co-standard; English (Standard Sort Order) +en-u-co-stroke; English (Stroke Sort Order) +en-u-co-trad; English (Traditional Sort Order) +en-u-co-unihan; English (Radical-Stroke Sort Order) +en-u-co-zhuyin; English (Zhuyin Sort Order) +en-u-cu-eur; English (Currency: €) +en-u-cu-jpy; English (Currency: ¥) +en-u-cu-usd; English (Currency: $) +en-u-cu-chf; English (Currency: CHF) +en-t-d0-accents; English (To Accented Characters From ASCII Sequence) +en-t-d0-ascii; English (To ASCII) +en-t-d0-casefold; English (To Casefolded) +en-t-d0-charname; English (To Unicode Character Names) +en-t-d0-digit; English (To Digit Form Of Accent) +en-t-d0-fcc; English (To Unicode FCC) +en-t-d0-fcd; English (To Unicode FCD) +en-t-d0-fwidth; English (To Fullwidth) +en-t-d0-hex; English (To Hexadecimal Codes) +en-t-d0-hwidth; English (To Halfwidth) +en-t-d0-lower; English (To Lowercase) +en-t-d0-morse; English (To Morse Code) +en-t-d0-nfc; English (To Unicode NFC) +en-t-d0-nfd; English (To Unicode NFD) +en-t-d0-nfkc; English (To Unicode NFKC) +en-t-d0-nfkd; English (To Unicode NFKD) +en-t-d0-npinyin; English (To Pinyin With Numeric Tones) +en-t-d0-null; English (No Change) +en-t-d0-publish; English (To Publishing Characters From ASCII) +en-t-d0-remove; English (To Empty String) +en-t-d0-title; English (To Titlecase) +en-t-d0-upper; English (To Uppercase) +en-t-d0-zawgyi; English (To Zawgyi Myanmar Encoding) +en-u-dx-thai; English (Dictionary Break Exclusions: thai) +en-u-em-default; English (Use Default Presentation For Emoji Characters) +en-u-em-emoji; English (Prefer Emoji Presentation For Emoji Characters) +en-u-em-text; English (Prefer Text Presentation For Emoji Characters) +en-u-fw-fri; English (First Day of Week Is Friday) +en-u-fw-mon; English (First Day of Week Is Monday) +en-u-fw-sat; English (First Day of Week Is Saturday) +en-u-fw-sun; English (First Day of Week Is Sunday) +en-u-fw-thu; English (First Day of Week Is Thursday) +en-u-fw-tue; English (First Day of Week Is Tuesday) +en-u-fw-wed; English (First Day of Week Is Wednesday) +en-t-h0-hybrid; English +en-u-hc-h11; English (12 Hour System [0–11]) +en-u-hc-h12; English (12 Hour System [1–12]) +en-u-hc-h23; English (24 Hour System [0–23]) +en-u-hc-h24; English (24 Hour System [1–24]) +en-t-i0-handwrit; English (Handwriting Input Method) +en-t-i0-pinyin; English (Pinyin Input Method) +en-t-i0-und; English (Unspecified Input Method) +en-t-i0-wubi; English (Wubi Input Method) +en-t-k0-101key; English (101-Key Keyboard) +en-t-k0-102key; English (102-Key Keyboard) +en-t-k0-600dpi; English (600 dpi Keyboard) +en-t-k0-768dpi; English (768 dpi Keyboard) +en-t-k0-android; English (Android Keyboard) +en-t-k0-azerty; English (AZERTY-Based Keyboard) +en-t-k0-chromeos; English (ChromeOS Keyboard) +en-t-k0-colemak; English (Colemak Keyboard) +en-t-k0-dvorak; English (Dvorak Keyboard) +en-t-k0-dvorakl; English (Dvorak Left-Handed Keyboard) +en-t-k0-dvorakr; English (Dvorak Right-Handed Keyboard) +en-t-k0-el220; English (Greek 220 Keyboard) +en-t-k0-el319; English (Greek 319 Keyboard) +en-t-k0-extended; English (Keyboard With Many Extra Characters) +en-t-k0-googlevk; English (Google Virtual Keyboard) +en-t-k0-isiri; English (Persian ISIRI Keyboard) +en-t-k0-legacy; English (Legacy Keyboard) +en-t-k0-lt1205; English (Lithuanian LST 1205 Keyboard) +en-t-k0-lt1582; English (Lithuanian LST 1582 Keyboard) +en-t-k0-nutaaq; English (Inuktitut Nutaaq Keyboard) +en-t-k0-osx; English (macOS Keyboard) +en-t-k0-patta; English (Thai Pattachote Keyboard) +en-t-k0-qwerty; English (QWERTY-Based Keyboard) +en-t-k0-qwertz; English (QWERTZ-Based Keyboard) +en-t-k0-ta99; English (Tamil 99 Keyboard) +en-t-k0-und; English (Unspecified Keyboard) +en-t-k0-var; English (Keyboard Variant) +en-t-k0-viqr; English (Vietnamese VIQR Keyboard) +en-t-k0-windows; English (Windows Keyboard) +en-u-ka-noignore; English (Sort Symbols) +en-u-ka-shifted; English (Sort Ignoring Symbols) +en-u-kb-false; English (Sort Accents Normally) +en-u-kb-true; English (Sort Accents Reversed) +en-u-kc-false; English (Sort Case Insensitive) +en-u-kc-true; English (Sort Case Sensitive) +en-u-kf-false; English (Sort Normal Case Order) +en-u-kf-lower; English (Sort Lowercase First) +en-u-kf-upper; English (Sort Uppercase First) +en-u-kk-false; English (Sort Without Normalization) +en-u-kk-true; English (Sort Unicode Normalized) +en-u-kn-false; English (Sort Digits Individually) +en-u-kn-true; English (Sort Digits Numerically) +en-u-kr-arab; English (Script/Block Reordering: Arabic) +en-u-kr-digit-deva-latn; English (Script/Block Reordering: Digits, Devanagari, Latin) +en-u-kr-currency; English (Currency) +en-u-kr-digit; English (Digits) +en-u-kr-punct; English (Punctuation) +en-u-kr-space; English (Whitespace) +en-u-kr-symbol; English (Symbol) +en-u-ks-identic; English (Sort All) +en-u-ks-level1; English (Sort Base Letters Only) +en-u-ks-level2; English (Sort Accents) +en-u-ks-level3; English (Sort Accents/Case/Width) +en-u-ks-level4; English (Sort Accents/Case/Width/Kana) +en-u-kv-currency; English (Ignore Symbols affects spaces, punctuation, all symbols) +en-u-kv-punct; English (Ignore Symbols affects spaces and punctuation only) +en-u-kv-space; English (Ignore Symbols affects spaces only) +en-u-kv-symbol; English (Ignore Symbols affects spaces, punctuation, non-currency symbols) +en-u-lb-loose; English (Loose Line Break Style) +en-u-lb-normal; English (Normal Line Break Style) +en-u-lb-strict; English (Strict Line Break Style) +en-u-lw-breakall; English (Allow Line Breaks In All Words) +en-u-lw-keepall; English (Prevent Line Breaks In All Words) +en-u-lw-normal; English (Normal Line Breaks For Words) +en-u-lw-phrase; English (Prevent Line Breaks In Phrases) +en-t-m0-aethiopi; English (Encylopedia Aethiopica Transliteration) +en-t-m0-alaloc; English (US ALA-LOC Transliteration) +en-t-m0-betamets; English (Beta Maṣāḥǝft Transliteration) +en-t-m0-bgn; English (US BGN Transliteration) +en-t-m0-buckwalt; English (Buckwalter Arabic Transliteration) +en-t-m0-c11; English (Hex transform using C11 syntax) +en-t-m0-css; English (Hex transform using CSS syntax) +en-t-m0-din; English (German DIN Transliteration) +en-t-m0-es3842; English (Ethiopian Standards Agency ES 3842:2014 Ethiopic-Latin Transliteration) +en-t-m0-ewts; English (Extended Wylie Transliteration Scheme) +en-t-m0-gost; English (CIS GOST Transliteration) +en-t-m0-gurage; English (Gurage Legacy to Modern Transliteration) +en-t-m0-gutgarts; English (Yaros Gutgarts Ethiopic-Cyrillic Transliteration) +en-t-m0-iast; English (International Alphabet of Sanskrit Transliteration) +en-t-m0-iesjes; English (IES/JES Amharic Transliteration) +en-t-m0-iso; English (ISO Transliteration) +en-t-m0-java; English (Hex transform using Java syntax) +en-t-m0-lambdin; English (Thomas Oden Lambdin Ethiopic-Latin Transliteration) +en-t-m0-mcst; English (Korean MCST Transliteration) +en-t-m0-mns; English (Mongolian National Standard Transliteration) +en-t-m0-percent; English (Hex transform using percent syntax) +en-t-m0-perl; English (Hex transform using Perl syntax) +en-t-m0-plain; English (Hex transform with no surrounding syntax) +en-t-m0-prprname; English (Personal name transliteration variant) +en-t-m0-satts; English (Standard Arabic Technical Transliteration) +en-t-m0-sera; English (System for Ethiopic Representation in ASCII) +en-t-m0-tekieali; English (Tekie Alibekit Blin-Latin Transliteration) +en-t-m0-ungegn; English (UN GEGN Transliteration) +en-t-m0-unicode; English (Hex transform using Unicode syntax) +en-t-m0-xaleget; English (Eritrean Ministry of Education Blin-Latin Transliteration) +en-t-m0-xml; English (Hex transform using XML syntax) +en-t-m0-xml10; English (Hex transform using XML decimal syntax) +en-u-ms-metric; English (Metric System) +en-u-ms-uksystem; English (Imperial Measurement System) +en-u-ms-ussystem; English (US Measurement System) +en-u-mu-celsius; English (Celsius) +en-u-mu-fahrenhe; English (Fahrenheit) +en-u-mu-kelvin; English (Kelvin) +en-u-nu-adlm; English (Adlam Digits) +en-u-nu-ahom; English (Ahom Digits) +en-u-nu-arab; English (Arabic-Indic Digits) +en-u-nu-arabext; English (Extended Arabic-Indic Digits) +en-u-nu-armn; English (Armenian Numerals) +en-u-nu-armnlow; English (Armenian Lowercase Numerals) +en-u-nu-bali; English (Balinese Digits) +en-u-nu-beng; English (Bangla Digits) +en-u-nu-bhks; English (Bhaiksuki Digits) +en-u-nu-brah; English (Brahmi Digits) +en-u-nu-cakm; English (Chakma Digits) +en-u-nu-cham; English (Cham Digits) +en-u-nu-cyrl; English (Cyrillic Numerals) +en-u-nu-deva; English (Devanagari Digits) +en-u-nu-diak; English (Dives Akuru Digits) +en-u-nu-ethi; English (Ethiopic Numerals) +en-u-nu-finance; English (Financial Numerals) +en-u-nu-fullwide; English (Full-Width Digits) +en-u-nu-geor; English (Georgian Numerals) +en-u-nu-gong; English (Gunjala Gondi digits) +en-u-nu-gonm; English (Masaram Gondi digits) +en-u-nu-grek; English (Greek Numerals) +en-u-nu-greklow; English (Greek Lowercase Numerals) +en-u-nu-gujr; English (Gujarati Digits) +en-u-nu-guru; English (Gurmukhi Digits) +en-u-nu-hanidays; English (Chinese Calendar Day-of-Month Numerals) +en-u-nu-hanidec; English (Chinese Decimal Numerals) +en-u-nu-hans; English (Simplified Chinese Numerals) +en-u-nu-hansfin; English (Simplified Chinese Financial Numerals) +en-u-nu-hant; English (Traditional Chinese Numerals) +en-u-nu-hantfin; English (Traditional Chinese Financial Numerals) +en-u-nu-hebr; English (Hebrew Numerals) +en-u-nu-hmng; English (Pahawh Hmong Digits) +en-u-nu-hmnp; English (Nyiakeng Puachue Hmong Digits) +en-u-nu-java; English (Javanese Digits) +en-u-nu-jpan; English (Japanese Numerals) +en-u-nu-jpanfin; English (Japanese Financial Numerals) +en-u-nu-jpanyear; English (Japanese Calendar Gannen Year Numerals) +en-u-nu-kali; English (Kayah Li Digits) +en-u-nu-kawi; English (Kawi Digits) +en-u-nu-khmr; English (Khmer Digits) +en-u-nu-knda; English (Kannada Digits) +en-u-nu-lana; English (Tai Tham Hora Digits) +en-u-nu-lanatham; English (Tai Tham Tham Digits) +en-u-nu-laoo; English (Lao Digits) +en-u-nu-latn; English (Western Digits) +en-u-nu-lepc; English (Lepcha Digits) +en-u-nu-limb; English (Limbu Digits) +en-u-nu-mathbold; English (Mathematical Bold Digits) +en-u-nu-mathdbl; English (Mathematical Double-Struck Digits) +en-u-nu-mathmono; English (Mathematical Monospace Digits) +en-u-nu-mathsanb; English (Mathematical Sans-Serif Bold Digits) +en-u-nu-mathsans; English (Mathematical Sans-Serif Digits) +en-u-nu-mlym; English (Malayalam Digits) +en-u-nu-modi; English (Modi Digits) +en-u-nu-mong; English (Mongolian Digits) +en-u-nu-mroo; English (Mro Digits) +en-u-nu-mtei; English (Meetei Mayek Digits) +en-u-nu-mymr; English (Myanmar Digits) +en-u-nu-mymrshan; English (Myanmar Shan Digits) +en-u-nu-mymrtlng; English (Myanmar Tai Laing Digits) +en-u-nu-nagm; English (Nag Mundari Digits) +en-u-nu-native; English (Native Digits) +en-u-nu-newa; English (Newa Digits) +en-u-nu-nkoo; English (N’Ko Digits) +en-u-nu-olck; English (Ol Chiki Digits) +en-u-nu-orya; English (Odia Digits) +en-u-nu-osma; English (Osmanya Digits) +en-u-nu-rohg; English (Hanifi Rohingya digits) +en-u-nu-roman; English (Roman Numerals) +en-u-nu-romanlow; English (Roman Lowercase Numerals) +en-u-nu-saur; English (Saurashtra Digits) +en-u-nu-segment; English (Segmented Digits) +en-u-nu-shrd; English (Sharada Digits) +en-u-nu-sind; English (Khudawadi Digits) +en-u-nu-sinh; English (Sinhala Lith Digits) +en-u-nu-sora; English (Sora Sompeng Digits) +en-u-nu-sund; English (Sundanese Digits) +en-u-nu-takr; English (Takri Digits) +en-u-nu-talu; English (New Tai Lue Digits) +en-u-nu-taml; English (Traditional Tamil Numerals) +en-u-nu-tamldec; English (Tamil Digits) +en-u-nu-telu; English (Telugu Digits) +en-u-nu-thai; English (Thai Digits) +en-u-nu-tibt; English (Tibetan Digits) +en-u-nu-tirh; English (Tirhuta Digits) +en-u-nu-tnsa; English (Tangsa Digits) +en-u-nu-traditio; English (Traditional Numerals) +en-u-nu-vaii; English (Vai Digits) +en-u-nu-wara; English (Warang Citi Digits) +en-u-nu-wcho; English (Wancho Digits) +en-u-rg-gbsct; English (Region For Supplemental Data: Scotland) +en-u-rg-gbeng; English (Region For Supplemental Data: England) +en-t-s0-accents; English (From Accented Characters To ASCII Sequence) +en-t-s0-ascii; English (From ASCII) +en-t-s0-hex; English (From Hexadecimal Codes) +en-t-s0-morse; English (From Morse Code) +en-t-s0-npinyin; English (From Pinyin With Numeric Tones) +en-t-s0-publish; English (From Publishing Punctuation To ASCII) +en-t-s0-zawgyi; English (From Zawgyi Myanmar Encoding) +en-u-sd-gbsct; English (Region Subdivision: Scotland) +en-u-sd-gbwls; English (Region Subdivision: Wales) +en-u-ss-none; English (Sentence Breaks Without Abbreviation Handling) +en-u-ss-standard; English (Suppress Sentence Breaks After Standard Abbreviations) +en-t-t0-und; English (Unspecified Machine Translation) +en-u-tz-uslax; English (Time Zone: Los Angeles Time) +en-u-tz-gblon; English (Time Zone: United Kingdom Time) +en-u-tz-chzrh; English (Time Zone: Switzerland Time) +en-u-va-posix; English (POSIX Compliant Locale) +en-t-x0-foobar2; English (Private-Use Transform: foobar2) + + +@locale=af +@languageDisplay=standard + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latyn, België) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=af +@languageDisplay=dialect + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latyn) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=am +@languageDisplay=standard + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓንሽኛ +es-419; ስፓንሽኛ (ላቲን አሜሪካ) +es-Cyrl-MX; ስፓንሽኛ (ሲይሪልክ፣ሜክሲኮ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ደች (ቤልጄም) +nl-Latn-BE; ደች (ላቲን፣ቤልጄም) +zh-Hans-fonipa; ቻይንኛ (ቀለል ያለ፣FONIPA) + + +@locale=am +@languageDisplay=dialect + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓንሽኛ +es-419; የላቲን አሜሪካ ስፓኒሽ +es-Cyrl-MX; የሜክሲኮ ስፓንሽኛ (ሲይሪልክ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ፍሌሚሽ +nl-Latn-BE; ፍሌሚሽ (ላቲን) +zh-Hans-fonipa; ቀለል ያለ ቻይንኛ (FONIPA) + + +@locale=ar +@languageDisplay=standard + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية (أمريكا اللاتينية) +es-Cyrl-MX; الإسبانية (السيريلية، المكسيك) +hi-Latn; الهندية (اللاتينية) +nl-BE; الهولندية (بلجيكا) +nl-Latn-BE; الهولندية (اللاتينية، بلجيكا) +zh-Hans-fonipa; الصينية (المبسطة، FONIPA) + + +@locale=ar +@languageDisplay=dialect + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية أمريكا اللاتينية +es-Cyrl-MX; الإسبانية المكسيكية (السيريلية) +hi-Latn; الهندية (اللاتينية) +nl-BE; الفلمنكية +nl-Latn-BE; الفلمنكية (اللاتينية) +zh-Hans-fonipa; الصينية المبسطة (FONIPA) + + +@locale=as +@languageDisplay=standard + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; স্পেনিচ (লেটিন আমেৰিকা) +es-Cyrl-MX; স্পেনিচ (চিৰিলিক, মেক্সিকো) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ডাচ (বেলজিয়াম) +nl-Latn-BE; ডাচ (লেটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সৰলীকৃত, FONIPA) + + +@locale=as +@languageDisplay=dialect + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; লেটিন আমেৰিকান স্পেনিচ +es-Cyrl-MX; মেক্সিকান স্পেনিচ (চিৰিলিক) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ফ্লেমিচ +nl-Latn-BE; ফ্লেমিচ (লেটিন) +zh-Hans-fonipa; সৰলীকৃত চীনা (FONIPA) + + +@locale=az +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=az_Latn +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az_Latn +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=be +@languageDisplay=standard + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; іспанская (Лацінская Амерыка) +es-Cyrl-MX; іспанская (кірыліца, Мексіка) +hi-Latn; хіндзі (лацініца) +nl-BE; нідэрландская (Бельгія) +nl-Latn-BE; нідэрландская (лацініца, Бельгія) +zh-Hans-fonipa; кітайская (спрошчанае кітайскае, FONIPA) + + +@locale=be +@languageDisplay=dialect + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; лацінаамерыканская іспанская +es-Cyrl-MX; мексіканская іспанская (кірыліца) +hi-Latn; хіндзі (лацініца) +nl-BE; фламандская +nl-Latn-BE; фламандская (лацініца) +zh-Hans-fonipa; кітайская [спрошчаныя іерогліфы] (FONIPA) + + +@locale=bg +@languageDisplay=standard + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; нидерландски (Белгия) +nl-Latn-BE; нидерландски (латиница, Белгия) +zh-Hans-fonipa; китайски (опростена, Международна фонетична азбука) + + +@locale=bg +@languageDisplay=dialect + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламандски +nl-Latn-BE; фламандски (латиница) +zh-Hans-fonipa; китайски [опростен] (Международна фонетична азбука) + + +@locale=bn +@languageDisplay=standard + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ওলন্দাজ (বেলজিয়াম) +nl-Latn-BE; ওলন্দাজ (ল্যাটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bn +@languageDisplay=dialect + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ফ্লেমিশ +nl-Latn-BE; ফ্লেমিশ (ল্যাটিন) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bs +@languageDisplay=standard + +en-MM; engleski (Mjanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; holandski (Belgija) +nl-Latn-BE; holandski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs +@languageDisplay=dialect + +en-MM; engleski (Mjanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=standard + +en-MM; engleski (Mjanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; holandski (Belgija) +nl-Latn-BE; holandski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=dialect + +en-MM; engleski (Mjanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=ca +@languageDisplay=standard + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol (Amèrica Llatina) +es-Cyrl-MX; espanyol (ciríl·lic, Mèxic) +hi-Latn; hindi (llatí) +nl-BE; neerlandès (Bèlgica) +nl-Latn-BE; neerlandès (llatí, Bèlgica) +zh-Hans-fonipa; xinès (simplificat, alfabet fonètic internacional) + + +@locale=ca +@languageDisplay=dialect + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol hispanoamericà +es-Cyrl-MX; espanyol de Mèxic (ciríl·lic) +hi-Latn; hindi (llatí) +nl-BE; flamenc +nl-Latn-BE; flamenc (llatí) +zh-Hans-fonipa; xinès simplificat (alfabet fonètic internacional) + + +@locale=cs +@languageDisplay=standard + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština (Latinská Amerika) +es-Cyrl-MX; španělština (cyrilice, Mexiko) +hi-Latn; hindština (latinka) +nl-BE; nizozemština (Belgie) +nl-Latn-BE; nizozemština (latinka, Belgie) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=cs +@languageDisplay=dialect + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština [Latinská Amerika] +es-Cyrl-MX; španělština [Mexiko] (cyrilice) +hi-Latn; hindština [latinka] +nl-BE; vlámština +nl-Latn-BE; vlámština (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=cy +@languageDisplay=standard + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg (America Ladin) +es-Cyrl-MX; Sbaeneg (Cyrilig, Mecsico) +hi-Latn; Hindi (Lladin) +nl-BE; Iseldireg (Gwlad Belg) +nl-Latn-BE; Iseldireg (Lladin, Gwlad Belg) +zh-Hans-fonipa; Tsieinëeg (Symledig, Seineg IPA) + + +@locale=cy +@languageDisplay=dialect + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg America Ladin +es-Cyrl-MX; Sbaeneg Mecsico (Cyrilig) +hi-Latn; Hindi [Lladin] +nl-BE; Fflemeg +nl-Latn-BE; Fflemeg (Lladin) +zh-Hans-fonipa; Tsieinëeg Symledig (Seineg IPA) + + +@locale=da +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latinamerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgien) +nl-Latn-BE; nederlandsk (latinsk, Belgien) +zh-Hans-fonipa; kinesisk (forenklet, det internationale fonetiske alfabet) + + +@locale=da +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; latinamerikansk spansk +es-Cyrl-MX; mexicansk spansk (kyrillisk) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internationale fonetiske alfabet) + + +@locale=de +@languageDisplay=standard + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Niederländisch (Belgien) +nl-Latn-BE; Niederländisch (Lateinisch, Belgien) +zh-Hans-fonipa; Chinesisch (Vereinfacht, IPA Phonetisch) + + +@locale=de +@languageDisplay=dialect + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Flämisch +nl-Latn-BE; Flämisch (Lateinisch) +zh-Hans-fonipa; Chinesisch [vereinfacht] (IPA Phonetisch) + + +@locale=el +@languageDisplay=standard + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά (Λατινική Αμερική) +es-Cyrl-MX; Ισπανικά (Κυριλλικό, Μεξικό) +hi-Latn; Χίντι (Λατινικό) +nl-BE; Ολλανδικά (Βέλγιο) +nl-Latn-BE; Ολλανδικά (Λατινικό, Βέλγιο) +zh-Hans-fonipa; Κινεζικά (Απλοποιημένο, Διεθνής φωνητική αλφάβητος) + + +@locale=el +@languageDisplay=dialect + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά Λατινικής Αμερικής +es-Cyrl-MX; Ισπανικά Μεξικού (Κυριλλικό) +hi-Latn; Χίντι [Λατινικό] +nl-BE; Φλαμανδικά +nl-Latn-BE; Φλαμανδικά (Λατινικό) +zh-Hans-fonipa; Απλοποιημένα Κινεζικά (Διεθνής φωνητική αλφάβητος) + + +@locale=en +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=en +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=es +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (Latinoamérica) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélgica) +nl-Latn-BE; neerlandés (latino, Bélgica) +zh-Hans-fonipa; chino (simplificado, Alfabeto fonético internacional IPA) + + +@locale=es +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español latinoamericano +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi (latino) +nl-BE; flamenco +nl-Latn-BE; flamenco (latino) +zh-Hans-fonipa; chino simplificado (Alfabeto fonético internacional IPA) + + +@locale=et +@languageDisplay=standard + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; hispaania (Ladina-Ameerika) +es-Cyrl-MX; hispaania (kirillitsa, Mehhiko) +hi-Latn; hindi (ladina) +nl-BE; hollandi (Belgia) +nl-Latn-BE; hollandi (ladina, Belgia) +zh-Hans-fonipa; hiina (lihtsustatud, IPA foneetika) + + +@locale=et +@languageDisplay=dialect + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; Ladina-Ameerika hispaania +es-Cyrl-MX; Mehhiko hispaania (kirillitsa) +hi-Latn; hindi (ladina) +nl-BE; flaami +nl-Latn-BE; flaami (ladina) +zh-Hans-fonipa; lihtsustatud hiina (IPA foneetika) + + +@locale=eu +@languageDisplay=standard + +en-MM; ingelesa (Myanmar [Birmania]) +es; espainiera +es-419; espainiera (Latinoamerika) +es-Cyrl-MX; espainiera (zirilikoa, Mexiko) +hi-Latn; hindia (latinoa) +nl-BE; nederlandera (Belgika) +nl-Latn-BE; nederlandera (latinoa, Belgika) +zh-Hans-fonipa; txinera (sinplifikatua, IPA ahoskera) + + +@locale=eu +@languageDisplay=dialect + +en-MM; ingelesa (Myanmar [Birmania]) +es; espainiera +es-419; Latinoamerikako espainiera +es-Cyrl-MX; Mexikoko espainiera (zirilikoa) +hi-Latn; hindia (latinoa) +nl-BE; flandriera +nl-Latn-BE; flandriera (latinoa) +zh-Hans-fonipa; txinera sinplifikatua (IPA ahoskera) + + +@locale=fa +@languageDisplay=standard + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی (امریکای لاتین) +es-Cyrl-MX; اسپانیایی (سیریلی، مکزیک) +hi-Latn; هندی (لاتین) +nl-BE; هلندی (بلژیک) +nl-Latn-BE; هلندی (لاتین، بلژیک) +zh-Hans-fonipa; چینی (ساده‌شده، فونتیک IPA) + + +@locale=fa +@languageDisplay=dialect + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی امریکای لاتین +es-Cyrl-MX; اسپانیایی مکزیک (سیریلی) +hi-Latn; هندی (لاتین) +nl-BE; فلمنگی +nl-Latn-BE; فلمنگی (لاتین) +zh-Hans-fonipa; چینی ساده‌شده (فونتیک IPA) + + +@locale=fi +@languageDisplay=standard + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; espanja (Latinalainen Amerikka) +es-Cyrl-MX; espanja (kyrillinen, Meksiko) +hi-Latn; hindi (latinalainen) +nl-BE; hollanti (Belgia) +nl-Latn-BE; hollanti (latinalainen, Belgia) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fi +@languageDisplay=dialect + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; amerikanespanja +es-Cyrl-MX; meksikonespanja (kyrillinen) +hi-Latn; hindi (latinalainen) +nl-BE; flaami +nl-Latn-BE; flaami (latinalainen) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fil +@languageDisplay=standard + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Pinasimple, FONIPA) + + +@locale=fil +@languageDisplay=dialect + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Latin American na Espanyol +es-Cyrl-MX; Mexican na Espanyol (Cyrillic) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Pinasimpleng Chinese (FONIPA) + + +@locale=fr +@languageDisplay=standard + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol (Amérique latine) +es-Cyrl-MX; espagnol (cyrillique, Mexique) +hi-Latn; hindi (latin) +nl-BE; néerlandais (Belgique) +nl-Latn-BE; néerlandais (latin, Belgique) +zh-Hans-fonipa; chinois (simplifié, alphabet phonétique international) + + +@locale=fr +@languageDisplay=dialect + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol d’Amérique latine +es-Cyrl-MX; espagnol du Mexique (cyrillique) +hi-Latn; hindi (latin) +nl-BE; flamand +nl-Latn-BE; flamand (latin) +zh-Hans-fonipa; chinois simplifié (alphabet phonétique international) + + +@locale=ga +@languageDisplay=standard + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis (Meiriceá Laidineach) +es-Cyrl-MX; Spáinnis (Coireallach, Meicsiceo) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Ollainnis (an Bheilg) +nl-Latn-BE; Ollainnis (Laidineach, an Bheilg) +zh-Hans-fonipa; Sínis (Simplithe, Fogharscríobh IPA) + + +@locale=ga +@languageDisplay=dialect + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis Mheiriceá Laidinigh +es-Cyrl-MX; Spáinnis Mheicsiceach (Coireallach) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Pléimeannais +nl-Latn-BE; Pléimeannais (Laidineach) +zh-Hans-fonipa; Sínis Shimplithe (Fogharscríobh IPA) + + +@locale=gd +@languageDisplay=standard + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis (Aimeireaga Laidinneach) +es-Cyrl-MX; Spàinntis (Cirilis, Meagsago) +hi-Latn; Hindis (Laideann) +nl-BE; Duitsis (A’ Bheilg) +nl-Latn-BE; Duitsis (Laideann, A’ Bheilg) +zh-Hans-fonipa; Sìnis (Simplichte, Comharran fuaim-eòlais an IPA) + + +@locale=gd +@languageDisplay=dialect + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis na h-Aimeireaga Laidinneach +es-Cyrl-MX; Spàinntis Mheagsagach (Cirilis) +hi-Latn; Hindis [Laideann] +nl-BE; Flànrais +nl-Latn-BE; Flànrais (Laideann) +zh-Hans-fonipa; Sìnis Shimplichte (Comharran fuaim-eòlais an IPA) + + +@locale=gl +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (América Latina) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélxica) +nl-Latn-BE; neerlandés (latino, Bélxica) +zh-Hans-fonipa; chinés (simplificado, FONIPA) + + +@locale=gl +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español de América +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi [alfabeto latino] +nl-BE; flamengo +nl-Latn-BE; flamengo (latino) +zh-Hans-fonipa; chinés simplificado (FONIPA) + + +@locale=gu +@languageDisplay=standard + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; સ્પેનિશ (લેટિન અમેરિકા) +es-Cyrl-MX; સ્પેનિશ (સિરિલિક, મેક્સિકો) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ડચ (બેલ્જીયમ) +nl-Latn-BE; ડચ (લેટિન, બેલ્જીયમ) +zh-Hans-fonipa; ચાઇનીઝ (સરળીકૃત, FONIPA) + + +@locale=gu +@languageDisplay=dialect + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; લેટિન અમેરિકન સ્પેનિશ +es-Cyrl-MX; મેક્સિકન સ્પેનિશ (સિરિલિક) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ફ્લેમિશ +nl-Latn-BE; ફ્લેમિશ (લેટિન) +zh-Hans-fonipa; સરળીકૃત ચાઇનીઝ (FONIPA) + + +@locale=ha +@languageDisplay=standard + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyanci (Latin Amurka) +es-Cyrl-MX; Sifaniyanci (Cyrillic, Mesiko) +hi-Latn; Harshen Hindi (Latin) +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Harshen Sinanci (Sauƙaƙaƙƙen, FONIPA) + + +@locale=ha +@languageDisplay=dialect + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyancin Latin Amirka +es-Cyrl-MX; Sifaniyanci Mesiko (Cyrillic) +hi-Latn; Hindi [Latinanci] +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Sauƙaƙaƙƙen Sinanci (FONIPA) + + +@locale=he +@languageDisplay=standard + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית (בלגיה) +nl-Latn-BE; הולנדית (לטיני, בלגיה) +zh-Hans-fonipa; סינית (פשוט, אלפבית פונטי בינלאומי) + + +@locale=he +@languageDisplay=dialect + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית [פלמית] +nl-Latn-BE; הולנדית [פלמית] (לטיני) +zh-Hans-fonipa; סינית פשוטה (אלפבית פונטי בינלאומי) + + +@locale=hi +@languageDisplay=standard + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; स्पेनिश (लैटिन अमेरिका) +es-Cyrl-MX; स्पेनिश (सिरिलिक, मैक्सिको) +hi-Latn; हिन्दी (लैटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लैटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=hi +@languageDisplay=dialect + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; लैटिन अमेरिकी स्पेनिश +es-Cyrl-MX; मैक्सिकन स्पेनिश (सिरिलिक) +hi-Latn; हिन्दी [लैटिन] +nl-BE; फ़्लेमिश +nl-Latn-BE; फ़्लेमिश (लैटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=hi_Latn +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=hi_Latn +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=hr +@languageDisplay=standard + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; španjolski (Latinska Amerika) +es-Cyrl-MX; španjolski (ćirilica, Meksiko) +hi-Latn; hindski (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno pismo, IPA fonetika) + + +@locale=hr +@languageDisplay=dialect + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; latinoamerički španjolski +es-Cyrl-MX; meksički španjolski (ćirilica) +hi-Latn; hindski (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=hu +@languageDisplay=standard + +en-MM; angol (Mianmar) +es; spanyol +es-419; spanyol (Latin-Amerika) +es-Cyrl-MX; spanyol (Cirill, Mexikó) +hi-Latn; hindi (Latin) +nl-BE; holland (Belgium) +nl-Latn-BE; holland (Latin, Belgium) +zh-Hans-fonipa; kínai (Egyszerűsített, IPA fonetika) + + +@locale=hu +@languageDisplay=dialect + +en-MM; angol (Mianmar) +es; spanyol +es-419; latin-amerikai spanyol +es-Cyrl-MX; spanyol [mexikói] (Cirill) +hi-Latn; hindi (Latin) +nl-BE; flamand +nl-Latn-BE; flamand (Latin) +zh-Hans-fonipa; egyszerűsített kínai (IPA fonetika) + + +@locale=hy +@languageDisplay=standard + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; իսպաներեն (Լատինական Ամերիկա) +es-Cyrl-MX; իսպաներեն (կյուրեղագիր, Մեքսիկա) +hi-Latn; հինդի (լատինական) +nl-BE; հոլանդերեն (Բելգիա) +nl-Latn-BE; հոլանդերեն (լատինական, Բելգիա) +zh-Hans-fonipa; չինարեն (պարզեցված, FONIPA) + + +@locale=hy +@languageDisplay=dialect + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; լատինամերիկյան իսպաներեն +es-Cyrl-MX; մեքսիկական իսպաներեն (կյուրեղագիր) +hi-Latn; հինդի [լատինական] +nl-BE; ֆլամանդերեն +nl-Latn-BE; ֆլամանդերեն (լատինական) +zh-Hans-fonipa; պարզեցված չինարեն (FONIPA) + + +@locale=id +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=id +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=ig +@languageDisplay=standard + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi (Latin America) +es-Cyrl-MX; Spanishi (Mkpụrụ Okwu Cyrillic, Mexico) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị (Belgium) +nl-Latn-BE; Dọchị (Latin, Belgium) +zh-Hans-fonipa; Chainisi (Nke dị mfe, FONIPA) + + +@locale=ig +@languageDisplay=dialect + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi ndị Latin America +es-Cyrl-MX; Spanishi ndị Mexico (Mkpụrụ Okwu Cyrillic) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị [Belgium] +nl-Latn-BE; Dọchị [Belgium] (Latin) +zh-Hans-fonipa; Asụsụ Chinese dị mfe (FONIPA) + + +@locale=is +@languageDisplay=standard + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; spænska (Rómanska Ameríka) +es-Cyrl-MX; spænska (kyrillískt, Mexíkó) +hi-Latn; hindí (latneskt) +nl-BE; hollenska (Belgía) +nl-Latn-BE; hollenska (latneskt, Belgía) +zh-Hans-fonipa; kínverska (einfaldað, FONIPA) + + +@locale=is +@languageDisplay=dialect + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; rómönsk-amerísk spænska +es-Cyrl-MX; mexíkósk spænska (kyrillískt) +hi-Latn; hindí (latneskt) +nl-BE; flæmska +nl-Latn-BE; flæmska (latneskt) +zh-Hans-fonipa; kínverska [einfölduð] (FONIPA) + + +@locale=it +@languageDisplay=standard + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo (America Latina) +es-Cyrl-MX; spagnolo (cirillico, Messico) +hi-Latn; hindi (latino) +nl-BE; olandese (Belgio) +nl-Latn-BE; olandese (latino, Belgio) +zh-Hans-fonipa; cinese (semplificato, alfabeto fonetico internazionale IPA) + + +@locale=it +@languageDisplay=dialect + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo latinoamericano +es-Cyrl-MX; spagnolo messicano (cirillico) +hi-Latn; hindi (latino) +nl-BE; fiammingo +nl-Latn-BE; fiammingo (latino) +zh-Hans-fonipa; cinese semplificato (alfabeto fonetico internazionale IPA) + + +@locale=ja +@languageDisplay=standard + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 (ラテン文字) +nl-BE; オランダ語 (ベルギー) +nl-Latn-BE; オランダ語 (ラテン文字、ベルギー) +zh-Hans-fonipa; 中国語 (簡体字、国際音声記号) + + +@locale=ja +@languageDisplay=dialect + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 [ラテン文字] +nl-BE; フラマン語 +nl-Latn-BE; フラマン語 (ラテン文字) +zh-Hans-fonipa; 簡体中国語 (国際音声記号) + + +@locale=jv +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amérika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Mèksiko) +hi-Latn; India (Latin) +nl-BE; Walanda (Bèlgi) +nl-Latn-BE; Walanda (Latin, Bèlgi) +zh-Hans-fonipa; Tyonghwa (Prasaja, FONIPA) + + +@locale=jv +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol [Amerika Latin] +es-Cyrl-MX; Spanyol [Meksiko] (Sirilik) +hi-Latn; India (Latin) +nl-BE; Flemis +nl-Latn-BE; Flemis (Latin) +zh-Hans-fonipa; Tyonghwa [Ringkes] (FONIPA) + + +@locale=ka +@languageDisplay=standard + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ესპანური (ლათინური ამერიკა) +es-Cyrl-MX; ესპანური (კირილიცა, მექსიკა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ნიდერლანდური (ბელგია) +nl-Latn-BE; ნიდერლანდური (ლათინური, ბელგია) +zh-Hans-fonipa; ჩინური (გამარტივებული, FONIPA) + + +@locale=ka +@languageDisplay=dialect + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ლათინურ ამერიკული ესპანური +es-Cyrl-MX; მექსიკური ესპანური (კირილიცა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ფლამანდიური +nl-Latn-BE; ფლამანდიური (ლათინური) +zh-Hans-fonipa; გამარტივებული ჩინური (FONIPA) + + +@locale=kk +@languageDisplay=standard + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; хинди тілі (латын жазуы) +nl-BE; нидерланд тілі (Бельгия) +nl-Latn-BE; нидерланд тілі (латын жазуы, Бельгия) +zh-Hans-fonipa; қытай тілі (жеңілдетілген жазу, Халықаралық фонетикалық әліпби) + + +@locale=kk +@languageDisplay=dialect + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; Хинди [латын жазуы] +nl-BE; фламанд тілі +nl-Latn-BE; фламанд тілі (латын жазуы) +zh-Hans-fonipa; жеңілдетілген қытай тілі (Халықаралық фонетикалық әліпби) + + +@locale=km +@languageDisplay=standard + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ហូឡង់ (បែលហ្ស៊ិក) +nl-Latn-BE; ហូឡង់ (ឡាតាំង, បែលហ្ស៊ិក) +zh-Hans-fonipa; ចិន (អក្សរ​ចិន​កាត់, FONIPA) + + +@locale=km +@languageDisplay=dialect + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ផ្លាមីស +nl-Latn-BE; ផ្លាមីស (ឡាតាំង) +zh-Hans-fonipa; ចិន​អក្សរ​កាត់ (FONIPA) + + +@locale=kn +@languageDisplay=standard + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಸ್ಪ್ಯಾನಿಷ್ (ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕಾ) +es-Cyrl-MX; ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್, ಮೆಕ್ಸಿಕೊ) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಡಚ್ (ಬೆಲ್ಜಿಯಮ್) +nl-Latn-BE; ಡಚ್ (ಲ್ಯಾಟಿನ್, ಬೆಲ್ಜಿಯಮ್) +zh-Hans-fonipa; ಚೈನೀಸ್ (ಸರಳೀಕೃತ, FONIPA) + + +@locale=kn +@languageDisplay=dialect + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ +es-Cyrl-MX; ಮೆಕ್ಸಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಫ್ಲೆಮಿಷ್ +nl-Latn-BE; ಫ್ಲೆಮಿಷ್ (ಲ್ಯಾಟಿನ್) +zh-Hans-fonipa; ಸರಳೀಕೃತ ಚೈನೀಸ್ (FONIPA) + + +@locale=ko +@languageDisplay=standard + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 네덜란드어(벨기에) +nl-Latn-BE; 네덜란드어(로마자, 벨기에) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=ko +@languageDisplay=dialect + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 플라망어 +nl-Latn-BE; 플라망어(로마자) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=kok +@languageDisplay=standard + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; स्पॅनीश (लॅटीन अमेरिका) +es-Cyrl-MX; स्पॅनीश (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटीन, बेल्जियम) +zh-Hans-fonipa; चिनी (सोंपी, FONIPA) + + +@locale=kok +@languageDisplay=dialect + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; लातीं अमेरिकन स्पॅनीश +es-Cyrl-MX; मॅक्सिकन स्पॅनीश (सिरिलिक) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटीन) +zh-Hans-fonipa; सोंपी चिनी (FONIPA) + + +@locale=ky +@languageDisplay=standard + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; голландча (Бельгия) +nl-Latn-BE; голландча (Латын, Бельгия) +zh-Hans-fonipa; кытайча (Жөнөкөйлөштүрүлгөн, FONIPA) + + +@locale=ky +@languageDisplay=dialect + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; фламандча +nl-Latn-BE; фламандча (Латын) +zh-Hans-fonipa; кытайча [жөнөкөйлөштүрүлгөн] (FONIPA) + + +@locale=lo +@languageDisplay=standard + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ສະແປນນິຊ (ລາຕິນ ອາເມລິກາ) +es-Cyrl-MX; ສະແປນນິຊ (ຊີຣິວລິກ, ເມັກຊິໂກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ດັຊ (ເບວຢຽມ) +nl-Latn-BE; ດັຊ (ລາຕິນ, ເບວຢຽມ) +zh-Hans-fonipa; ຈີນ (ແບບຮຽບງ່າຍ, ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lo +@languageDisplay=dialect + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ລາຕິນ ອາເມຣິກັນ ສະແປນນິຊ +es-Cyrl-MX; ເມັກຊິກັນ ສະແປນນິຊ (ຊີຣິວລິກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ຟລີມິຊ +nl-Latn-BE; ຟລີມິຊ (ລາຕິນ) +zh-Hans-fonipa; ຈີນແບບຮຽບງ່າຍ (ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lt +@languageDisplay=standard + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; ispanų (Lotynų Amerika) +es-Cyrl-MX; ispanų (kirilica, Meksika) +hi-Latn; hindi (lotynų) +nl-BE; olandų (Belgija) +nl-Latn-BE; olandų (lotynų, Belgija) +zh-Hans-fonipa; kinų (supaprastinti, Tarptautinės abėcėlės fonetika) + + +@locale=lt +@languageDisplay=dialect + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; Lotynų Amerikos ispanų +es-Cyrl-MX; Meksikos ispanų (kirilica) +hi-Latn; hindi (lotynų) +nl-BE; flamandų +nl-Latn-BE; flamandų (lotynų) +zh-Hans-fonipa; supaprastintoji kinų (Tarptautinės abėcėlės fonetika) + + +@locale=lv +@languageDisplay=standard + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi (latīņu) +nl-BE; holandiešu (Beļģija) +nl-Latn-BE; holandiešu (latīņu, Beļģija) +zh-Hans-fonipa; ķīniešu (vienkāršotā, Starptautiskais fonētiskais alfabēts) + + +@locale=lv +@languageDisplay=dialect + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi [latīņu] +nl-BE; flāmu +nl-Latn-BE; flāmu (latīņu) +zh-Hans-fonipa; ķīniešu vienkāršotā (Starptautiskais fonētiskais alfabēts) + + +@locale=mk +@languageDisplay=standard + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (кирилско писмо, Мексико) +hi-Latn; хинди (латинично писмо) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латинично писмо, Белгија) +zh-Hans-fonipa; кинески (поедноставено, FONIPA) + + +@locale=mk +@languageDisplay=dialect + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; латиноамерикански шпански +es-Cyrl-MX; мексикански шпански (кирилско писмо) +hi-Latn; хинди (латинично писмо) +nl-BE; фламански +nl-Latn-BE; фламански (латинично писмо) +zh-Hans-fonipa; поедноставен кинески (FONIPA) + + +@locale=ml +@languageDisplay=standard + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; സ്‌പാനിഷ് (ലാറ്റിനമേരിക്ക) +es-Cyrl-MX; സ്‌പാനിഷ് (സിറിലിക്, മെക്സിക്കോ) +hi-Latn; ഹിന്ദി (ലാറ്റിൻ) +nl-BE; ഡച്ച് (ബെൽജിയം) +nl-Latn-BE; ഡച്ച് (ലാറ്റിൻ, ബെൽജിയം) +zh-Hans-fonipa; ചൈനീസ് (ലളിതവൽക്കരിച്ചത്, ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=ml +@languageDisplay=dialect + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; ലാറ്റിൻ അമേരിക്കൻ സ്‌പാനിഷ് +es-Cyrl-MX; മെക്സിക്കൻ സ്പാനിഷ് (സിറിലിക്) +hi-Latn; ഹിന്ദി [ലാറ്റിൻ] +nl-BE; ഫ്ലമിഷ് +nl-Latn-BE; ഫ്ലമിഷ് (ലാറ്റിൻ) +zh-Hans-fonipa; ലളിതമാക്കിയ ചൈനീസ് (ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=mn +@languageDisplay=standard + +en-MM; англи (Мьянмар) +es; испани +es-419; испани (Латин Америк) +es-Cyrl-MX; испани (кирилл, Мексик) +hi-Latn; хинди (латин) +nl-BE; нидерланд (Бельги) +nl-Latn-BE; нидерланд (латин, Бельги) +zh-Hans-fonipa; хятад (хялбаршуулсан, FONIPA) + + +@locale=mn +@languageDisplay=dialect + +en-MM; англи (Мьянмар) +es; испани +es-419; испани хэл [Латин Америк] +es-Cyrl-MX; испани хэл [Мексик] (кирилл) +hi-Latn; хинди (латин) +nl-BE; фламанд +nl-Latn-BE; фламанд (латин) +zh-Hans-fonipa; хялбаршуулсан хятад (FONIPA) + + +@locale=mr +@languageDisplay=standard + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; स्पॅनिश (लॅटिन अमेरिका) +es-Cyrl-MX; स्पॅनिश (सीरिलिक, मेक्सिको) +hi-Latn; हिंदी (लॅटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=mr +@languageDisplay=dialect + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; लॅटिन अमेरिकन स्पॅनिश +es-Cyrl-MX; मेक्सिकन स्पॅनिश (सीरिलिक) +hi-Latn; हिंदी (लॅटिन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=ms +@languageDisplay=standard + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol (Amerika Latin) +es-Cyrl-MX; Sepanyol (Cyril, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgium) +nl-Latn-BE; Belanda (Latin, Belgium) +zh-Hans-fonipa; Cina (Ringkas, Fonetik IPA) + + +@locale=ms +@languageDisplay=dialect + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol Amerika Latin +es-Cyrl-MX; Sepanyol Mexico (Cyril) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Cina Ringkas (Fonetik IPA) + + +@locale=my +@languageDisplay=standard + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် (စစ်ရိလစ်/ မက်ကဆီကို) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဒတ်ခ်ျ (ဘယ်လ်ဂျီယမ်) +nl-Latn-BE; ဒတ်ခ်ျ (လက်တင်/ ဘယ်လ်ဂျီယမ်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=my +@languageDisplay=dialect + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် [မက္ကဆီကို] (စစ်ရိလစ်) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဖလီမစ်ရှ် +nl-Latn-BE; ဖလီမစ်ရှ် (လက်တင်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=nb +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=nb +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=ne +@languageDisplay=standard + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; स्पेनी (ल्याटिन अमेरिका) +es-Cyrl-MX; स्पेनी (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (ल्याटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (ल्याटिन, बेल्जियम) +zh-Hans-fonipa; चिनियाँ (सरलिकृत चिनियाँ, FONIPA) + + +@locale=ne +@languageDisplay=dialect + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; ल्याटिन अमेरिकी स्पेनी +es-Cyrl-MX; मेक्सिकन स्पेनी (सिरिलिक) +hi-Latn; हिन्दी [ल्याटिन] +nl-BE; फ्लेमिस +nl-Latn-BE; फ्लेमिस (ल्याटिन) +zh-Hans-fonipa; सरलिकृत चिनियाँ (FONIPA) + + +@locale=nl +@languageDisplay=standard + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latijns, België) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nl +@languageDisplay=dialect + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latijns) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nn +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenkla, det internasjonale fonetiske alfabetet [IPA]) + + +@locale=nn +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenkla kinesisk (det internasjonale fonetiske alfabetet [IPA]) + + +@locale=no +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=no +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=or +@languageDisplay=standard + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ସ୍ପେନିୟ (ଲାଟିନ୍‌ ଆମେରିକା) +es-Cyrl-MX; ସ୍ପେନିୟ (ସିରିଲିକ୍, ମେକ୍ସିକୋ) +hi-Latn; ହିନ୍ଦୀ (ଲାଟିନ୍) +nl-BE; ଡଚ୍ (ବେଲଜିୟମ୍) +nl-Latn-BE; ଡଚ୍ (ଲାଟିନ୍, ବେଲଜିୟମ୍) +zh-Hans-fonipa; ଚାଇନିଜ୍‌ (ସରଳୀକୃତ, FONIPA) + + +@locale=or +@languageDisplay=dialect + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ଲାଟିନ୍‌ ଆମେରିକୀୟ ସ୍ପାନିସ୍‌ +es-Cyrl-MX; ମେକ୍ସିକାନ ସ୍ପାନିସ୍‌ (ସିରିଲିକ୍) +hi-Latn; ହିନ୍ଦୀ [ଲାଟିନ୍] +nl-BE; ଫ୍ଲେମିଶ୍ +nl-Latn-BE; ଫ୍ଲେମିଶ୍ (ଲାଟିନ୍) +zh-Hans-fonipa; ସରଳୀକୃତ ଚାଇନିଜ୍‌ (FONIPA) + + +@locale=pa +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ [ਸਰਲ] (FONIPA) + + +@locale=pa_Guru +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa_Guru +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ [ਸਰਲ] (FONIPA) + + +@locale=pcm +@languageDisplay=standard + +en-MM; Ínglish (Miánma [Bọ́ma]) +es; Spánish Lángwej +es-419; Spánish Lángwej (Látín Amẹ́ríka) +es-Cyrl-MX; Spánish Lángwej (Sírílik, Mẹ́ksíko) +hi-Latn; Híndi Lángwej (Látin) +nl-BE; Dọch Lángwej (Bẹ́ljọm) +nl-Latn-BE; Dọch Lángwej (Látin, Bẹ́ljọm) +zh-Hans-fonipa; Mandarín Chainíz Lángwej (Ízí Chainíz Lángwej, FONIPA) + + +@locale=pcm +@languageDisplay=dialect + +en-MM; Ínglish (Miánma [Bọ́ma]) +es; Spánish Lángwej +es-419; Látín Amẹ́ríka Spánish +es-Cyrl-MX; Mẹ́ksiko Spánish (Sírílik) +hi-Latn; Híndi [Látin] +nl-BE; Flẹ́mish Lángwej +nl-Latn-BE; Flẹ́mish Lángwej (Látin) +zh-Hans-fonipa; Mandarín Chainíz Lángwej (Ízí Chainíz Lángwej, FONIPA) + + +@locale=pl +@languageDisplay=standard + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; hiszpański (Ameryka Łacińska) +es-Cyrl-MX; hiszpański (cyrylica, Meksyk) +hi-Latn; hindi (łacińskie) +nl-BE; niderlandzki (Belgia) +nl-Latn-BE; niderlandzki (łacińskie, Belgia) +zh-Hans-fonipa; chiński (uproszczone, fonetyczny międzynarodowy) + + +@locale=pl +@languageDisplay=dialect + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; amerykański hiszpański +es-Cyrl-MX; meksykański hiszpański (cyrylica) +hi-Latn; hindi [alfabet łaciński] +nl-BE; flamandzki +nl-Latn-BE; flamandzki (łacińskie) +zh-Hans-fonipa; chiński uproszczony (fonetyczny międzynarodowy) + + +@locale=ps +@languageDisplay=standard + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاتیني امریکا) +es-Cyrl-MX; هسپانوي (سیریلیک, میکسیکو) +hi-Latn; هندي (لاتين/لاتيني) +nl-BE; هالېنډي (بیلجیم) +nl-Latn-BE; هالېنډي (لاتين/لاتيني, بیلجیم) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=ps +@languageDisplay=dialect + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; لاتيني امريکايي هسپانوي +es-Cyrl-MX; ميکسيکي هسپانوي (سیریلیک) +hi-Latn; هندي [لاتيني] +nl-BE; فلېمېشي +nl-Latn-BE; فلېمېشي (لاتين/لاتيني) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=pt +@languageDisplay=standard + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; holandês (Bélgica) +nl-Latn-BE; holandês (latim, Bélgica) +zh-Hans-fonipa; chinês (simplificado, fonética do Alfabeto Fonético Internacional) + + +@locale=pt +@languageDisplay=dialect + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; flamengo +nl-Latn-BE; flamengo (latim) +zh-Hans-fonipa; chinês simplificado (fonética do Alfabeto Fonético Internacional) + + +@locale=ro +@languageDisplay=standard + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; neerlandeză (Belgia) +nl-Latn-BE; neerlandeză (latină, Belgia) +zh-Hans-fonipa; chineză (simplificată, alfabet fonetic internațional) + + +@locale=ro +@languageDisplay=dialect + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; flamandă +nl-Latn-BE; flamandă (latină) +zh-Hans-fonipa; chineză simplificată (alfabet fonetic internațional) + + +@locale=root +@languageDisplay=standard + +en-MM; en (MM) +es; es +es-419; es (419) +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=root +@languageDisplay=dialect + +en-MM; en (MM) +es; es +es-419; es_419 +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=ru +@languageDisplay=standard + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; испанский (Латинская Америка) +es-Cyrl-MX; испанский (кириллица, Мексика) +hi-Latn; хинди (латиница) +nl-BE; нидерландский (Бельгия) +nl-Latn-BE; нидерландский (латиница, Бельгия) +zh-Hans-fonipa; китайский (упрощенная, Международный фонетический алфавит) + + +@locale=ru +@languageDisplay=dialect + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; латиноамериканский испанский +es-Cyrl-MX; мексиканский испанский (кириллица) +hi-Latn; хинди (латиница) +nl-BE; фламандский +nl-Latn-BE; фламандский (латиница) +zh-Hans-fonipa; китайский, упрощенное письмо (Международный фонетический алфавит) + + +@locale=sd +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=si +@languageDisplay=standard + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ස්පාඤ්ඤ (ලතින් ඇමෙරිකාව) +es-Cyrl-MX; ස්පාඤ්ඤ (සිරිලික්, මෙක්සිකෝව) +hi-Latn; හින්දි (ලතින්) +nl-BE; ලන්දේසි (බෙල්ජියම) +nl-Latn-BE; ලන්දේසි (ලතින්, බෙල්ජියම) +zh-Hans-fonipa; චීන (සුළුකළ, FONIPA) + + +@locale=si +@languageDisplay=dialect + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ලතින් ඇමරිකානු ස්පාඤ්ඤ +es-Cyrl-MX; මෙක්සිකානු ස්පාඤ්ඤ (සිරිලික්) +hi-Latn; හින්දි (ලතින්) +nl-BE; ෆ්ලෙමිශ් +nl-Latn-BE; ෆ්ලෙමිශ් (ලතින්) +zh-Hans-fonipa; සරල චීන (FONIPA) + + +@locale=sk +@languageDisplay=standard + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina (Latinská Amerika) +es-Cyrl-MX; španielčina (cyrilika, Mexiko) +hi-Latn; hindčina (latinka) +nl-BE; holandčina (Belgicko) +nl-Latn-BE; holandčina (latinka, Belgicko) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=sk +@languageDisplay=dialect + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina [latinskoamerická] +es-Cyrl-MX; španielčina [mexická] (cyrilika) +hi-Latn; hindčina (latinka) +nl-BE; flámčina +nl-Latn-BE; flámčina (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=sl +@languageDisplay=standard + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; španščina (Latinska Amerika) +es-Cyrl-MX; španščina (cirilica, Mehika) +hi-Latn; hindijščina (latinica) +nl-BE; nizozemščina (Belgija) +nl-Latn-BE; nizozemščina (latinica, Belgija) +zh-Hans-fonipa; kitajščina (poenostavljena pisava, mednarodna fonetična pisava IPA) + + +@locale=sl +@languageDisplay=dialect + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; latinskoameriška španščina +es-Cyrl-MX; mehiška španščina (cirilica) +hi-Latn; hindijščina (latinica) +nl-BE; flamščina +nl-Latn-BE; flamščina (latinica) +zh-Hans-fonipa; poenostavljena kitajščina (mednarodna fonetična pisava IPA) + + +@locale=so +@languageDisplay=standard + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanish (Laatiin Ameerika) +es-Cyrl-MX; Isbaanish (Siriylik, Meksiko) +hi-Latn; Hindi (Laatiin) +nl-BE; Holandays (Biljam) +nl-Latn-BE; Holandays (Laatiin, Biljam) +zh-Hans-fonipa; Shiinaha Mandarin (La fududeeyay, FONIPA) + + +@locale=so +@languageDisplay=dialect + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanishka Laatiin Ameerika +es-Cyrl-MX; Isbaanishka Mexico (Siriylik) +hi-Latn; Hindi [Latin] +nl-BE; Af faleemi +nl-Latn-BE; Af faleemi (Laatiin) +zh-Hans-fonipa; Shiinaha Rasmiga ah (FONIPA) + + +@locale=sq +@languageDisplay=standard + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjisht (Amerika Latine) +es-Cyrl-MX; spanjisht (cirilik, Meksikë) +hi-Latn; indisht (latin) +nl-BE; holandisht (Belgjikë) +nl-Latn-BE; holandisht (latin, Belgjikë) +zh-Hans-fonipa; kinezisht (i thjeshtuar, FONIPA) + + +@locale=sq +@languageDisplay=dialect + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjishte amerikano-latine +es-Cyrl-MX; spanjishte meksikane (cirilik) +hi-Latn; indisht (latin) +nl-BE; flamandisht +nl-Latn-BE; flamandisht (latin) +zh-Hans-fonipa; kinezishte e thjeshtuar (FONIPA) + + +@locale=sr +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Latn +@languageDisplay=standard + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; holandski (Belgija) +nl-Latn-BE; holandski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno kinesko pismo, IPA fonetika) + + +@locale=sr_Latn +@languageDisplay=dialect + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; pojednostavljeni kineski (IPA fonetika) + + +@locale=sv +@languageDisplay=standard + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; spanska (Latinamerika) +es-Cyrl-MX; spanska (kyrilliska, Mexiko) +hi-Latn; hindi (latinska) +nl-BE; nederländska (Belgien) +nl-Latn-BE; nederländska (latinska, Belgien) +zh-Hans-fonipa; kinesiska (förenklad, internationell fonetisk notation - IPA) + + +@locale=sv +@languageDisplay=dialect + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; latinamerikansk spanska +es-Cyrl-MX; mexikansk spanska (kyrilliska) +hi-Latn; hindi [latinsk] +nl-BE; flamländska +nl-Latn-BE; flamländska (latinska) +zh-Hans-fonipa; förenklad kinesiska (internationell fonetisk notation - IPA) + + +@locale=sw +@languageDisplay=standard + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania (Amerika ya Kilatini) +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiholanzi (Ubelgiji) +nl-Latn-BE; Kiholanzi (Kilatini, Ubelgiji) +zh-Hans-fonipa; Kichina (Rahisi, FONIPA) + + +@locale=sw +@languageDisplay=dialect + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania [Amerika ya Latini] +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiflemi +nl-Latn-BE; Kiflemi (Kilatini) +zh-Hans-fonipa; Kichina [Kilichorahisishwa] (FONIPA) + + +@locale=ta +@languageDisplay=standard + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; ஸ்பானிஷ் (லத்தீன் அமெரிக்கா) +es-Cyrl-MX; ஸ்பானிஷ் (சிரிலிக், மெக்சிகோ) +hi-Latn; இந்தி (லத்தின்) +nl-BE; டச்சு (பெல்ஜியம்) +nl-Latn-BE; டச்சு (லத்தின், பெல்ஜியம்) +zh-Hans-fonipa; சீனம் (எளிதாக்கப்பட்டது, FONIPA) + + +@locale=ta +@languageDisplay=dialect + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; லத்தின் அமெரிக்க ஸ்பானிஷ் +es-Cyrl-MX; மெக்ஸிகன் ஸ்பானிஷ் (சிரிலிக்) +hi-Latn; இந்தி (லத்தின்) +nl-BE; ஃப்லெமிஷ் +nl-Latn-BE; ஃப்லெமிஷ் (லத்தின்) +zh-Hans-fonipa; எளிதாக்கப்பட்ட சீனம் (FONIPA) + + +@locale=te +@languageDisplay=standard + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; స్పానిష్ (లాటిన్ అమెరికా) +es-Cyrl-MX; స్పానిష్ (సిరిలిక్, మెక్సికో) +hi-Latn; హిందీ (లాటిన్) +nl-BE; డచ్ (బెల్జియం) +nl-Latn-BE; డచ్ (లాటిన్, బెల్జియం) +zh-Hans-fonipa; చైనీస్ (సరళీకృతం, FONIPA) + + +@locale=te +@languageDisplay=dialect + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; లాటిన్ అమెరికన్ స్పానిష్ +es-Cyrl-MX; మెక్సికన్ స్పానిష్ (సిరిలిక్) +hi-Latn; హిందీ [లాటిన్] +nl-BE; ఫ్లెమిష్ +nl-Latn-BE; ఫ్లెమిష్ (లాటిన్) +zh-Hans-fonipa; సరళీకృత చైనీస్ (FONIPA) + + +@locale=th +@languageDisplay=standard + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน (ละตินอเมริกา) +es-Cyrl-MX; สเปน (ซีริลลิก, เม็กซิโก) +hi-Latn; ฮินดี (ละติน) +nl-BE; ดัตช์ (เบลเยียม) +nl-Latn-BE; ดัตช์ (ละติน, เบลเยียม) +zh-Hans-fonipa; จีน (ตัวย่อ, สัทอักษรสากล) + + +@locale=th +@languageDisplay=dialect + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน - ละตินอเมริกา +es-Cyrl-MX; สเปน - เม็กซิโก (ซีริลลิก) +hi-Latn; ฮินดี (ละติน) +nl-BE; เฟลมิช +nl-Latn-BE; เฟลมิช (ละติน) +zh-Hans-fonipa; จีนตัวย่อ (สัทอักษรสากล) + + +@locale=tk +@languageDisplay=standard + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; niderland dili (Belgiýa) +nl-Latn-BE; niderland dili (Latyn elipbiýi, Belgiýa) +zh-Hans-fonipa; hytaý dili (Ýönekeýleşdirilen, FONIPA) + + +@locale=tk +@languageDisplay=dialect + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; flamand dili +nl-Latn-BE; flamand dili (Latyn elipbiýi) +zh-Hans-fonipa; ýönekeýleşdirilen hytaý dili (FONIPA) + + +@locale=tr +@languageDisplay=standard + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; İspanyolca (Latin Amerika) +es-Cyrl-MX; İspanyolca (Kiril, Meksika) +hi-Latn; Hintçe (Latin) +nl-BE; Felemenkçe (Belçika) +nl-Latn-BE; Felemenkçe (Latin, Belçika) +zh-Hans-fonipa; Çince (Basitleştirilmiş, IPA Ses Bilimi) + + +@locale=tr +@languageDisplay=dialect + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; Latin Amerika İspanyolcası +es-Cyrl-MX; Meksika İspanyolcası (Kiril) +hi-Latn; Hintçe (Latin) +nl-BE; Flamanca +nl-Latn-BE; Flamanca (Latin) +zh-Hans-fonipa; Basitleştirilmiş Çince (IPA Ses Bilimi) + + +@locale=uk +@languageDisplay=standard + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; іспанська (Латинська Америка) +es-Cyrl-MX; іспанська (кирилиця, Мексика) +hi-Latn; гінді (латиниця) +nl-BE; нідерландська (Бельгія) +nl-Latn-BE; нідерландська (латиниця, Бельгія) +zh-Hans-fonipa; китайська (спрощена, Міжнародний фонетичний алфавіт) + + +@locale=uk +@languageDisplay=dialect + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; латиноамериканська іспанська +es-Cyrl-MX; мексиканська іспанська (кирилиця) +hi-Latn; гінді (латиниця) +nl-BE; фламандська +nl-Latn-BE; фламандська (латиниця) +zh-Hans-fonipa; китайська [спрощене письмо] (Міжнародний фонетичний алфавіт) + + +@locale=ur +@languageDisplay=standard + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; ہسپانوی (لاطینی امریکہ) +es-Cyrl-MX; ہسپانوی (سیریلک،میکسیکو) +hi-Latn; ہندی (لاطینی) +nl-BE; ڈچ (بیلجیم) +nl-Latn-BE; ڈچ (لاطینی،بیلجیم) +zh-Hans-fonipa; چینی (آسان،FONIPA) + + +@locale=ur +@languageDisplay=dialect + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; لاطینی امریکی ہسپانوی +es-Cyrl-MX; میکسیکن ہسپانوی (سیریلک) +hi-Latn; ہندی [لاطینی] +nl-BE; فلیمِش +nl-Latn-BE; فلیمِش (لاطینی) +zh-Hans-fonipa; چینی [آسان کردہ] (FONIPA) + + +@locale=uz +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind [lotin] +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy [soddalashgan] (FONIPA) + + +@locale=uz_Latn +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz_Latn +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind [lotin] +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy [soddalashgan] (FONIPA) + + +@locale=vi +@languageDisplay=standard + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha (Châu Mỹ La-tinh) +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Hà Lan (Bỉ) +nl-Latn-BE; Tiếng Hà Lan (Chữ La tinh, Bỉ) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=vi +@languageDisplay=dialect + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha [Mỹ La tinh] +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Flemish +nl-Latn-BE; Tiếng Flemish (Chữ La tinh) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=yo +@languageDisplay=standard + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì (Látín Amẹ́ríkà) +es-Cyrl-MX; Èdè Sípáníìṣì (èdè ilẹ̀ Rọ́ṣíà, Mesiko) +hi-Latn; Èdè Híńdì (Èdè Látìn) +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Edè Ṣáínà (tí wọ́n mú rọrùn., FONIPA) + + +@locale=yo +@languageDisplay=dialect + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì [orílẹ̀-èdè Látìn-Amẹ́ríkà] +es-Cyrl-MX; Èdè Sípáníìṣì [orílẹ̀-èdè Mẹ́síkò] (èdè ilẹ̀ Rọ́ṣíà) +hi-Latn; Èdè Híndì [Látìnì] +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Ẹdè Ṣáínà Onírọ̀rùn (FONIPA) + + +@locale=yue +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=standard + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷兰文 (比利时) +nl-Latn-BE; 荷兰文 (拉丁文,比利时) +zh-Hans-fonipa; 中文 (简体,IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=dialect + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛兰芒文 +nl-Latn-BE; 佛兰芒文 (拉丁文) +zh-Hans-fonipa; 简体中文 (IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=zh +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hans +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh_Hans +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hant +@languageDisplay=standard + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地文(拉丁文) +nl-BE; 荷蘭文(比利時) +nl-Latn-BE; 荷蘭文(拉丁文,比利時) +zh-Hans-fonipa; 中文(簡體,IPA 拼音) + + +@locale=zh_Hant +@languageDisplay=dialect + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地語[拉丁文] +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文(拉丁文) +zh-Hans-fonipa; 簡體中文(IPA 拼音) + + +@locale=zu +@languageDisplay=standard + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Spanish (i-Latin America) +es-Cyrl-MX; isi-Spanish (isi-Cyrillic, i-Mexico) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Dutch (i-Belgium) +nl-Latn-BE; isi-Dutch (isi-Latin, i-Belgium) +zh-Hans-fonipa; isi-Chinese (enziwe lula, Ifonotiki ye-IPA) + + +@locale=zu +@languageDisplay=dialect + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Latin American Spanish +es-Cyrl-MX; isi-Mexican Spanish (isi-Cyrillic) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Flemish +nl-Latn-BE; isi-Flemish (isi-Latin) +zh-Hans-fonipa; isi-Chinese [esenziwe-lula] (Ifonotiki ye-IPA) + diff --git a/testgen/icu74/localeDisplayName.txt b/testgen/icu74/localeDisplayName.txt new file mode 100644 index 00000000..83b844e4 --- /dev/null +++ b/testgen/icu74/localeDisplayName.txt @@ -0,0 +1,3072 @@ +# Test data for locale display name generation +# Copyright © 1991-2024 Unicode, Inc. +# For terms of use, see http://www.unicode.org/copyright.html +# SPDX-License-Identifier: Unicode-3.0 +# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/) +# Format: +# @locale= +# @languageDisplay=[standard|dialect] +# standard - always display additional subtags like region in parentheses +# dialect - form compounds like "Flemish" for nl_BE +# ; + +@locale=en +@languageDisplay=standard + + +# Simple cases: Language, script, region, variants + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + +#Note that the order of the variants is alphabetized before generating names + +en-Latn-GB-scouse-fonipa; English (Latin, United Kingdom, IPA Phonetics, Scouse) + +# Add extensions, and verify their order + +en-u-nu-deva-t-de; English (Transform: German, Devanagari Digits) +en-u-nu-thai-ca-islamic-civil; English (Hijri Calendar [tabular, civil epoch], Thai Digits) +hi-u-nu-latn-t-en-h0-hybrid; Hindi (Hybrid: English, Western Digits) + +# Test ordering of extensions (include well-formed but invalid cases) + +fr-z-zz-zzz-v-vv-vvv-u-uu-uuu-t-ru-Cyrl-s-ss-sss-a-aa-aaa-x-u-x; French (Transform: Russian [Cyrillic], uu: uuu, a: aa-aaa, s: ss-sss, v: vv-vvv, x: u-x, z: zz-zzz) + +# Comprehensive list (mostly comprehensive: currencies, subdivisions, timezones have abbreviated lists) + +en-u-ca-buddhist; English (Buddhist Calendar) +en-u-ca-chinese; English (Chinese Calendar) +en-u-ca-coptic; English (Coptic Calendar) +en-u-ca-dangi; English (Dangi Calendar) +en-u-ca-ethioaa; English (Ethiopic Amete Alem Calendar) +en-u-ca-ethiopic; English (Ethiopic Calendar) +en-u-ca-gregory; English (Gregorian Calendar) +en-u-ca-hebrew; English (Hebrew Calendar) +en-u-ca-indian; English (Indian National Calendar) +en-u-ca-islamic; English (Hijri Calendar) +en-u-ca-islamic-civil; English (Hijri Calendar [tabular, civil epoch]) +en-u-ca-islamic-rgsa; English (Hijri Calendar [Saudi Arabia, sighting]) +en-u-ca-islamic-tbla; English (Hijri Calendar [tabular, astronomical epoch]) +en-u-ca-islamic-umalqura; English (Hijri Calendar [Umm al-Qura]) +en-u-ca-iso8601; English (ISO-8601 Calendar) +en-u-ca-japanese; English (Japanese Calendar) +en-u-ca-persian; English (Persian Calendar) +en-u-ca-roc; English (Minguo Calendar) +en-u-cf-account; English (Accounting Currency Format) +en-u-cf-standard; English (Standard Currency Format) +en-u-co-big5han; English (Traditional Chinese Sort Order - Big5) +en-u-co-compat; English (Previous Sort Order, for compatibility) +en-u-co-dict; English (Dictionary Sort Order) +en-u-co-ducet; English (Default Unicode Sort Order) +en-u-co-emoji; English (Emoji Sort Order) +en-u-co-eor; English (European Ordering Rules) +en-u-co-gb2312; English (Simplified Chinese Sort Order - GB2312) +en-u-co-phonebk; English (Phonebook Sort Order) +en-u-co-phonetic; English (Phonetic Sort Order) +en-u-co-pinyin; English (Pinyin Sort Order) +en-u-co-reformed; English (Reformed Sort Order) +en-u-co-search; English (General-Purpose Search) +en-u-co-searchjl; English (Search By Hangul Initial Consonant) +en-u-co-standard; English (Standard Sort Order) +en-u-co-stroke; English (Stroke Sort Order) +en-u-co-trad; English (Traditional Sort Order) +en-u-co-unihan; English (Radical-Stroke Sort Order) +en-u-co-zhuyin; English (Zhuyin Sort Order) +en-u-cu-eur; English (Currency: €) +en-u-cu-jpy; English (Currency: ¥) +en-u-cu-usd; English (Currency: $) +en-u-cu-chf; English (Currency: CHF) +en-t-d0-accents; English (To Accented Characters From ASCII Sequence) +en-t-d0-ascii; English (To ASCII) +en-t-d0-casefold; English (To Casefolded) +en-t-d0-charname; English (To Unicode Character Names) +en-t-d0-digit; English (To Digit Form Of Accent) +en-t-d0-fcc; English (To Unicode FCC) +en-t-d0-fcd; English (To Unicode FCD) +en-t-d0-fwidth; English (To Fullwidth) +en-t-d0-hex; English (To Hexadecimal Codes) +en-t-d0-hwidth; English (To Halfwidth) +en-t-d0-lower; English (To Lowercase) +en-t-d0-morse; English (To Morse Code) +en-t-d0-nfc; English (To Unicode NFC) +en-t-d0-nfd; English (To Unicode NFD) +en-t-d0-nfkc; English (To Unicode NFKC) +en-t-d0-nfkd; English (To Unicode NFKD) +en-t-d0-npinyin; English (To Pinyin With Numeric Tones) +en-t-d0-null; English (No Change) +en-t-d0-publish; English (To Publishing Characters From ASCII) +en-t-d0-remove; English (To Empty String) +en-t-d0-title; English (To Titlecase) +en-t-d0-upper; English (To Uppercase) +en-t-d0-zawgyi; English (To Zawgyi Myanmar Encoding) +en-u-dx-thai; English (Dictionary Break Exclusions: thai) +en-u-em-default; English (Use Default Presentation For Emoji Characters) +en-u-em-emoji; English (Prefer Emoji Presentation For Emoji Characters) +en-u-em-text; English (Prefer Text Presentation For Emoji Characters) +en-u-fw-fri; English (First Day of Week Is Friday) +en-u-fw-mon; English (First Day of Week Is Monday) +en-u-fw-sat; English (First Day of Week Is Saturday) +en-u-fw-sun; English (First Day of Week Is Sunday) +en-u-fw-thu; English (First Day of Week Is Thursday) +en-u-fw-tue; English (First Day of Week Is Tuesday) +en-u-fw-wed; English (First Day of Week Is Wednesday) +en-t-h0-hybrid; English +en-u-hc-h11; English (12 Hour System [0–11]) +en-u-hc-h12; English (12 Hour System [1–12]) +en-u-hc-h23; English (24 Hour System [0–23]) +en-u-hc-h24; English (24 Hour System [1–24]) +en-t-i0-handwrit; English (Handwriting Input Method) +en-t-i0-pinyin; English (Pinyin Input Method) +en-t-i0-und; English (Unspecified Input Method) +en-t-i0-wubi; English (Wubi Input Method) +en-t-k0-101key; English (101-Key Keyboard) +en-t-k0-102key; English (102-Key Keyboard) +en-t-k0-600dpi; English (600 dpi Keyboard) +en-t-k0-768dpi; English (768 dpi Keyboard) +en-t-k0-android; English (Android Keyboard) +en-t-k0-azerty; English (AZERTY-Based Keyboard) +en-t-k0-chromeos; English (ChromeOS Keyboard) +en-t-k0-colemak; English (Colemak Keyboard) +en-t-k0-dvorak; English (Dvorak Keyboard) +en-t-k0-dvorakl; English (Dvorak Left-Handed Keyboard) +en-t-k0-dvorakr; English (Dvorak Right-Handed Keyboard) +en-t-k0-el220; English (Greek 220 Keyboard) +en-t-k0-el319; English (Greek 319 Keyboard) +en-t-k0-extended; English (Keyboard With Many Extra Characters) +en-t-k0-googlevk; English (Google Virtual Keyboard) +en-t-k0-isiri; English (Persian ISIRI Keyboard) +en-t-k0-legacy; English (Legacy Keyboard) +en-t-k0-lt1205; English (Lithuanian LST 1205 Keyboard) +en-t-k0-lt1582; English (Lithuanian LST 1582 Keyboard) +en-t-k0-nutaaq; English (Inuktitut Nutaaq Keyboard) +en-t-k0-osx; English (macOS Keyboard) +en-t-k0-patta; English (Thai Pattachote Keyboard) +en-t-k0-qwerty; English (QWERTY-Based Keyboard) +en-t-k0-qwertz; English (QWERTZ-Based Keyboard) +en-t-k0-ta99; English (Tamil 99 Keyboard) +en-t-k0-und; English (Unspecified Keyboard) +en-t-k0-var; English (Keyboard Variant) +en-t-k0-viqr; English (Vietnamese VIQR Keyboard) +en-t-k0-windows; English (Windows Keyboard) +en-u-ka-noignore; English (Sort Symbols) +en-u-ka-shifted; English (Sort Ignoring Symbols) +en-u-kb-false; English (Sort Accents Normally) +en-u-kb-true; English (Sort Accents Reversed) +en-u-kc-false; English (Sort Case Insensitive) +en-u-kc-true; English (Sort Case Sensitive) +en-u-kf-false; English (Sort Normal Case Order) +en-u-kf-lower; English (Sort Lowercase First) +en-u-kf-upper; English (Sort Uppercase First) +en-u-kk-false; English (Sort Without Normalization) +en-u-kk-true; English (Sort Unicode Normalized) +en-u-kn-false; English (Sort Digits Individually) +en-u-kn-true; English (Sort Digits Numerically) +en-u-kr-arab; English (Script/Block Reordering: Arabic) +en-u-kr-digit-deva-latn; English (Script/Block Reordering: Digits, Devanagari, Latin) +en-u-kr-currency; English (Currency) +en-u-kr-digit; English (Digits) +en-u-kr-punct; English (Punctuation) +en-u-kr-space; English (Whitespace) +en-u-kr-symbol; English (Symbol) +en-u-ks-identic; English (Sort All) +en-u-ks-level1; English (Sort Base Letters Only) +en-u-ks-level2; English (Sort Accents) +en-u-ks-level3; English (Sort Accents/Case/Width) +en-u-ks-level4; English (Sort Accents/Case/Width/Kana) +en-u-kv-currency; English (Ignore Symbols affects spaces, punctuation, all symbols) +en-u-kv-punct; English (Ignore Symbols affects spaces and punctuation only) +en-u-kv-space; English (Ignore Symbols affects spaces only) +en-u-kv-symbol; English (Ignore Symbols affects spaces, punctuation, non-currency symbols) +en-u-lb-loose; English (Loose Line Break Style) +en-u-lb-normal; English (Normal Line Break Style) +en-u-lb-strict; English (Strict Line Break Style) +en-u-lw-breakall; English (Allow Line Breaks In All Words) +en-u-lw-keepall; English (Prevent Line Breaks In All Words) +en-u-lw-normal; English (Normal Line Breaks For Words) +en-u-lw-phrase; English (Prevent Line Breaks In Phrases) +en-t-m0-aethiopi; English (Encylopedia Aethiopica Transliteration) +en-t-m0-alaloc; English (US ALA-LOC Transliteration) +en-t-m0-betamets; English (Beta Maṣāḥǝft Transliteration) +en-t-m0-bgn; English (US BGN Transliteration) +en-t-m0-buckwalt; English (Buckwalter Arabic Transliteration) +en-t-m0-c11; English (Hex transform using C11 syntax) +en-t-m0-css; English (Hex transform using CSS syntax) +en-t-m0-din; English (German DIN Transliteration) +en-t-m0-es3842; English (Ethiopian Standards Agency ES 3842:2014 Ethiopic-Latin Transliteration) +en-t-m0-ewts; English (Extended Wylie Transliteration Scheme) +en-t-m0-gost; English (CIS GOST Transliteration) +en-t-m0-gurage; English (Gurage Legacy to Modern Transliteration) +en-t-m0-gutgarts; English (Yaros Gutgarts Ethiopic-Cyrillic Transliteration) +en-t-m0-iast; English (International Alphabet of Sanskrit Transliteration) +en-t-m0-iesjes; English (IES/JES Amharic Transliteration) +en-t-m0-iso; English (ISO Transliteration) +en-t-m0-java; English (Hex transform using Java syntax) +en-t-m0-lambdin; English (Thomas Oden Lambdin Ethiopic-Latin Transliteration) +en-t-m0-mcst; English (Korean MCST Transliteration) +en-t-m0-mns; English (Mongolian National Standard Transliteration) +en-t-m0-percent; English (Hex transform using percent syntax) +en-t-m0-perl; English (Hex transform using Perl syntax) +en-t-m0-plain; English (Hex transform with no surrounding syntax) +en-t-m0-prprname; English (Personal name transliteration variant) +en-t-m0-satts; English (Standard Arabic Technical Transliteration) +en-t-m0-sera; English (System for Ethiopic Representation in ASCII) +en-t-m0-tekieali; English (Tekie Alibekit Blin-Latin Transliteration) +en-t-m0-ungegn; English (UN GEGN Transliteration) +en-t-m0-unicode; English (Hex transform using Unicode syntax) +en-t-m0-xaleget; English (Eritrean Ministry of Education Blin-Latin Transliteration) +en-t-m0-xml; English (Hex transform using XML syntax) +en-t-m0-xml10; English (Hex transform using XML decimal syntax) +en-u-ms-metric; English (Metric System) +en-u-ms-uksystem; English (Imperial Measurement System) +en-u-ms-ussystem; English (US Measurement System) +en-u-mu-celsius; English (Celsius) +en-u-mu-fahrenhe; English (Fahrenheit) +en-u-mu-kelvin; English (Kelvin) +en-u-nu-adlm; English (Adlam Digits) +en-u-nu-ahom; English (Ahom Digits) +en-u-nu-arab; English (Arabic-Indic Digits) +en-u-nu-arabext; English (Extended Arabic-Indic Digits) +en-u-nu-armn; English (Armenian Numerals) +en-u-nu-armnlow; English (Armenian Lowercase Numerals) +en-u-nu-bali; English (Balinese Digits) +en-u-nu-beng; English (Bangla Digits) +en-u-nu-bhks; English (Bhaiksuki Digits) +en-u-nu-brah; English (Brahmi Digits) +en-u-nu-cakm; English (Chakma Digits) +en-u-nu-cham; English (Cham Digits) +en-u-nu-cyrl; English (Cyrillic Numerals) +en-u-nu-deva; English (Devanagari Digits) +en-u-nu-diak; English (Dives Akuru Digits) +en-u-nu-ethi; English (Ethiopic Numerals) +en-u-nu-finance; English (Financial Numerals) +en-u-nu-fullwide; English (Full-Width Digits) +en-u-nu-geor; English (Georgian Numerals) +en-u-nu-gong; English (Gunjala Gondi digits) +en-u-nu-gonm; English (Masaram Gondi digits) +en-u-nu-grek; English (Greek Numerals) +en-u-nu-greklow; English (Greek Lowercase Numerals) +en-u-nu-gujr; English (Gujarati Digits) +en-u-nu-guru; English (Gurmukhi Digits) +en-u-nu-hanidays; English (Chinese Calendar Day-of-Month Numerals) +en-u-nu-hanidec; English (Chinese Decimal Numerals) +en-u-nu-hans; English (Simplified Chinese Numerals) +en-u-nu-hansfin; English (Simplified Chinese Financial Numerals) +en-u-nu-hant; English (Traditional Chinese Numerals) +en-u-nu-hantfin; English (Traditional Chinese Financial Numerals) +en-u-nu-hebr; English (Hebrew Numerals) +en-u-nu-hmng; English (Pahawh Hmong Digits) +en-u-nu-hmnp; English (Nyiakeng Puachue Hmong Digits) +en-u-nu-java; English (Javanese Digits) +en-u-nu-jpan; English (Japanese Numerals) +en-u-nu-jpanfin; English (Japanese Financial Numerals) +en-u-nu-jpanyear; English (Japanese Calendar Gannen Year Numerals) +en-u-nu-kali; English (Kayah Li Digits) +en-u-nu-kawi; English (Kawi Digits) +en-u-nu-khmr; English (Khmer Digits) +en-u-nu-knda; English (Kannada Digits) +en-u-nu-lana; English (Tai Tham Hora Digits) +en-u-nu-lanatham; English (Tai Tham Tham Digits) +en-u-nu-laoo; English (Lao Digits) +en-u-nu-latn; English (Western Digits) +en-u-nu-lepc; English (Lepcha Digits) +en-u-nu-limb; English (Limbu Digits) +en-u-nu-mathbold; English (Mathematical Bold Digits) +en-u-nu-mathdbl; English (Mathematical Double-Struck Digits) +en-u-nu-mathmono; English (Mathematical Monospace Digits) +en-u-nu-mathsanb; English (Mathematical Sans-Serif Bold Digits) +en-u-nu-mathsans; English (Mathematical Sans-Serif Digits) +en-u-nu-mlym; English (Malayalam Digits) +en-u-nu-modi; English (Modi Digits) +en-u-nu-mong; English (Mongolian Digits) +en-u-nu-mroo; English (Mro Digits) +en-u-nu-mtei; English (Meetei Mayek Digits) +en-u-nu-mymr; English (Myanmar Digits) +en-u-nu-mymrshan; English (Myanmar Shan Digits) +en-u-nu-mymrtlng; English (Myanmar Tai Laing Digits) +en-u-nu-nagm; English (Nag Mundari Digits) +en-u-nu-native; English (Native Digits) +en-u-nu-newa; English (Newa Digits) +en-u-nu-nkoo; English (N’Ko Digits) +en-u-nu-olck; English (Ol Chiki Digits) +en-u-nu-orya; English (Odia Digits) +en-u-nu-osma; English (Osmanya Digits) +en-u-nu-rohg; English (Hanifi Rohingya digits) +en-u-nu-roman; English (Roman Numerals) +en-u-nu-romanlow; English (Roman Lowercase Numerals) +en-u-nu-saur; English (Saurashtra Digits) +en-u-nu-segment; English (Segmented Digits) +en-u-nu-shrd; English (Sharada Digits) +en-u-nu-sind; English (Khudawadi Digits) +en-u-nu-sinh; English (Sinhala Lith Digits) +en-u-nu-sora; English (Sora Sompeng Digits) +en-u-nu-sund; English (Sundanese Digits) +en-u-nu-takr; English (Takri Digits) +en-u-nu-talu; English (New Tai Lue Digits) +en-u-nu-taml; English (Traditional Tamil Numerals) +en-u-nu-tamldec; English (Tamil Digits) +en-u-nu-telu; English (Telugu Digits) +en-u-nu-thai; English (Thai Digits) +en-u-nu-tibt; English (Tibetan Digits) +en-u-nu-tirh; English (Tirhuta Digits) +en-u-nu-tnsa; English (Tangsa Digits) +en-u-nu-traditio; English (Traditional Numerals) +en-u-nu-vaii; English (Vai Digits) +en-u-nu-wara; English (Warang Citi Digits) +en-u-nu-wcho; English (Wancho Digits) +en-u-rg-gbsct; English (Region For Supplemental Data: Scotland) +en-u-rg-gbeng; English (Region For Supplemental Data: England) +en-t-s0-accents; English (From Accented Characters To ASCII Sequence) +en-t-s0-ascii; English (From ASCII) +en-t-s0-hex; English (From Hexadecimal Codes) +en-t-s0-morse; English (From Morse Code) +en-t-s0-npinyin; English (From Pinyin With Numeric Tones) +en-t-s0-publish; English (From Publishing Punctuation To ASCII) +en-t-s0-zawgyi; English (From Zawgyi Myanmar Encoding) +en-u-sd-gbsct; English (Region Subdivision: Scotland) +en-u-sd-gbwls; English (Region Subdivision: Wales) +en-u-ss-none; English (Sentence Breaks Without Abbreviation Handling) +en-u-ss-standard; English (Suppress Sentence Breaks After Standard Abbreviations) +en-t-t0-und; English (Unspecified Machine Translation) +en-u-tz-uslax; English (Time Zone: Los Angeles Time) +en-u-tz-gblon; English (Time Zone: United Kingdom Time) +en-u-tz-chzrh; English (Time Zone: Switzerland Time) +en-u-va-posix; English (POSIX Compliant Locale) +en-t-x0-foobar2; English (Private-Use Transform: foobar2) + + +@locale=af +@languageDisplay=standard + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latyn, België) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=af +@languageDisplay=dialect + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latyn) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=am +@languageDisplay=standard + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓኒሽ +es-419; ስፓኒሽ (ላቲን አሜሪካ) +es-Cyrl-MX; ስፓኒሽ (ሲይሪልክ፣ሜክሲኮ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ደች (ቤልጄም) +nl-Latn-BE; ደች (ላቲን፣ቤልጄም) +zh-Hans-fonipa; ቻይንኛ (ቀለል ያለ፣FONIPA) + + +@locale=am +@languageDisplay=dialect + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓኒሽ +es-419; የላቲን አሜሪካ ስፓኒሽ +es-Cyrl-MX; የሜክሲኮ ስፓኒሽ (ሲይሪልክ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ፍሌሚሽ +nl-Latn-BE; ፍሌሚሽ (ላቲን) +zh-Hans-fonipa; ቀለል ያለ ቻይንኛ (FONIPA) + + +@locale=ar +@languageDisplay=standard + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية (أمريكا اللاتينية) +es-Cyrl-MX; الإسبانية (السيريلية، المكسيك) +hi-Latn; الهندية (اللاتينية) +nl-BE; الهولندية (بلجيكا) +nl-Latn-BE; الهولندية (اللاتينية، بلجيكا) +zh-Hans-fonipa; الصينية (المبسطة، FONIPA) + + +@locale=ar +@languageDisplay=dialect + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية أمريكا اللاتينية +es-Cyrl-MX; الإسبانية المكسيكية (السيريلية) +hi-Latn; الهندية (اللاتينية) +nl-BE; الفلمنكية +nl-Latn-BE; الفلمنكية (اللاتينية) +zh-Hans-fonipa; الصينية المبسطة (FONIPA) + + +@locale=as +@languageDisplay=standard + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; স্পেনিচ (লেটিন আমেৰিকা) +es-Cyrl-MX; স্পেনিচ (চিৰিলিক, মেক্সিকো) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ডাচ (বেলজিয়াম) +nl-Latn-BE; ডাচ (লেটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সৰলীকৃত, FONIPA) + + +@locale=as +@languageDisplay=dialect + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; লেটিন আমেৰিকান স্পেনিচ +es-Cyrl-MX; মেক্সিকান স্পেনিচ (চিৰিলিক) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ফ্লেমিচ +nl-Latn-BE; ফ্লেমিচ (লেটিন) +zh-Hans-fonipa; সৰলীকৃত চীনা (FONIPA) + + +@locale=az +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=az_Latn +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az_Latn +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=be +@languageDisplay=standard + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; іспанская (Лацінская Амерыка) +es-Cyrl-MX; іспанская (кірыліца, Мексіка) +hi-Latn; хіндзі (лацініца) +nl-BE; нідэрландская (Бельгія) +nl-Latn-BE; нідэрландская (лацініца, Бельгія) +zh-Hans-fonipa; кітайская (спрошчанае кітайскае, FONIPA) + + +@locale=be +@languageDisplay=dialect + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; лацінаамерыканская іспанская +es-Cyrl-MX; мексіканская іспанская (кірыліца) +hi-Latn; хіндзі (лацініца) +nl-BE; фламандская +nl-Latn-BE; фламандская (лацініца) +zh-Hans-fonipa; кітайская [спрошчаныя іерогліфы] (FONIPA) + + +@locale=bg +@languageDisplay=standard + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; нидерландски (Белгия) +nl-Latn-BE; нидерландски (латиница, Белгия) +zh-Hans-fonipa; китайски (опростена, Международна фонетична азбука) + + +@locale=bg +@languageDisplay=dialect + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламандски +nl-Latn-BE; фламандски (латиница) +zh-Hans-fonipa; китайски [опростен] (Международна фонетична азбука) + + +@locale=bn +@languageDisplay=standard + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ওলন্দাজ (বেলজিয়াম) +nl-Latn-BE; ওলন্দাজ (ল্যাটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bn +@languageDisplay=dialect + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ফ্লেমিশ +nl-Latn-BE; ফ্লেমিশ (ল্যাটিন) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bs +@languageDisplay=standard + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs +@languageDisplay=dialect + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=standard + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=dialect + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=ca +@languageDisplay=standard + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol (Amèrica Llatina) +es-Cyrl-MX; espanyol (ciríl·lic, Mèxic) +hi-Latn; hindi (llatí) +nl-BE; neerlandès (Bèlgica) +nl-Latn-BE; neerlandès (llatí, Bèlgica) +zh-Hans-fonipa; xinès (simplificat, alfabet fonètic internacional) + + +@locale=ca +@languageDisplay=dialect + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol llatinoamericà +es-Cyrl-MX; espanyol de Mèxic (ciríl·lic) +hi-Latn; hindi (llatí) +nl-BE; flamenc +nl-Latn-BE; flamenc (llatí) +zh-Hans-fonipa; xinès simplificat (alfabet fonètic internacional) + + +@locale=chr +@languageDisplay=standard + +en-MM; ᎩᎵᏏ (ᎹᏯᎹᎵ [ᏇᎵᎹ]) +es; ᏍᏆᏂ +es-419; ᏍᏆᏂ (ᎳᏘᏂ ᎠᎹᏰᏟ) +es-Cyrl-MX; ᏍᏆᏂ (ᏲᏂᎢ ᏗᎪᏪᎵ, ᎠᏂᏍᏆᏂ) +hi-Latn; ᎯᏂᏗ (ᎳᏘᏂ) +nl-BE; ᏛᏥ (ᏇᎵᏥᎥᎻ) +nl-Latn-BE; ᏛᏥ (ᎳᏘᏂ, ᏇᎵᏥᎥᎻ) +zh-Hans-fonipa; ᏓᎶᏂᎨ (ᎠᎯᏗᎨ, FONIPA) + + +@locale=chr +@languageDisplay=dialect + +en-MM; ᎩᎵᏏ (ᎹᏯᎹᎵ [ᏇᎵᎹ]) +es; ᏍᏆᏂ +es-419; ᏔᏘᏂ ᎠᎹᏰᏟ ᏍᏆᏂ +es-Cyrl-MX; ᏍᏆᏂᏱ ᏍᏆᏂ (ᏲᏂᎢ ᏗᎪᏪᎵ) +hi-Latn; ᎯᏂᏗ (ᎳᏘᏂ) +nl-BE; ᏊᎵᏥᎥᎻ ᏛᏥ +nl-Latn-BE; ᏊᎵᏥᎥᎻ ᏛᏥ (ᎳᏘᏂ) +zh-Hans-fonipa; ᎠᎯᏗᎨ ᏓᎶᏂᎨ (FONIPA) + + +@locale=cs +@languageDisplay=standard + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština (Latinská Amerika) +es-Cyrl-MX; španělština (cyrilice, Mexiko) +hi-Latn; hindština (latinka) +nl-BE; nizozemština (Belgie) +nl-Latn-BE; nizozemština (latinka, Belgie) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=cs +@languageDisplay=dialect + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština (Latinská Amerika) +es-Cyrl-MX; španělština (cyrilice, Mexiko) +hi-Latn; hindština (latinka) +nl-BE; vlámština +nl-Latn-BE; vlámština (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=cy +@languageDisplay=standard + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg (America Ladin) +es-Cyrl-MX; Sbaeneg (Cyrilig, Mecsico) +hi-Latn; Hindi (Lladin) +nl-BE; Iseldireg (Gwlad Belg) +nl-Latn-BE; Iseldireg (Lladin, Gwlad Belg) +zh-Hans-fonipa; Tsieinëeg (Symledig, Seineg IPA) + + +@locale=cy +@languageDisplay=dialect + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg America Ladin +es-Cyrl-MX; Sbaeneg Mecsico (Cyrilig) +hi-Latn; Hindi (Lladin) +nl-BE; Fflemeg +nl-Latn-BE; Fflemeg (Lladin) +zh-Hans-fonipa; Tsieinëeg Symledig (Seineg IPA) + + +@locale=da +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latinamerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgien) +nl-Latn-BE; nederlandsk (latinsk, Belgien) +zh-Hans-fonipa; kinesisk (forenklet, det internationale fonetiske alfabet) + + +@locale=da +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; latinamerikansk spansk +es-Cyrl-MX; mexicansk spansk (kyrillisk) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internationale fonetiske alfabet) + + +@locale=de +@languageDisplay=standard + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Niederländisch (Belgien) +nl-Latn-BE; Niederländisch (Lateinisch, Belgien) +zh-Hans-fonipa; Chinesisch (Vereinfacht, IPA Phonetisch) + + +@locale=de +@languageDisplay=dialect + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Flämisch +nl-Latn-BE; Flämisch (Lateinisch) +zh-Hans-fonipa; Chinesisch [vereinfacht] (IPA Phonetisch) + + +@locale=dsb +@languageDisplay=standard + +en-MM; engelšćina (Myanmar) +es; špańšćina +es-419; špańšćina (Łatyńska Amerika) +es-Cyrl-MX; špańšćina (kyriliski, Mexiko) +hi-Latn; hindišćina (łatyński) +nl-BE; nižozemšćina (Belgiska) +nl-Latn-BE; nižozemšćina (łatyński, Belgiska) +zh-Hans-fonipa; chinšćina (zjadnorjone, FONIPA) + + +@locale=dsb +@languageDisplay=dialect + +en-MM; engelšćina (Myanmar) +es; špańšćina +es-419; łatyńskoamerikańska špańšćina +es-Cyrl-MX; mexikańska špańšćina (kyriliski) +hi-Latn; hindišćina (łatyński) +nl-BE; flamšćina +nl-Latn-BE; flamšćina (łatyński) +zh-Hans-fonipa; chinšćina [zjadnorjona] (FONIPA) + + +@locale=el +@languageDisplay=standard + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά (Λατινική Αμερική) +es-Cyrl-MX; Ισπανικά (Κυριλλικό, Μεξικό) +hi-Latn; Χίντι (Λατινικό) +nl-BE; Ολλανδικά (Βέλγιο) +nl-Latn-BE; Ολλανδικά (Λατινικό, Βέλγιο) +zh-Hans-fonipa; Κινεζικά (Απλοποιημένο, Διεθνής φωνητική αλφάβητος) + + +@locale=el +@languageDisplay=dialect + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά Λατινικής Αμερικής +es-Cyrl-MX; Ισπανικά Μεξικού (Κυριλλικό) +hi-Latn; Χίντι (Λατινικό) +nl-BE; Φλαμανδικά +nl-Latn-BE; Φλαμανδικά (Λατινικό) +zh-Hans-fonipa; Απλοποιημένα Κινεζικά (Διεθνής φωνητική αλφάβητος) + + +@locale=en +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=en +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=es +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (Latinoamérica) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélgica) +nl-Latn-BE; neerlandés (latino, Bélgica) +zh-Hans-fonipa; chino (simplificado, Alfabeto fonético internacional IPA) + + +@locale=es +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español latinoamericano +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi (latino) +nl-BE; flamenco +nl-Latn-BE; flamenco (latino) +zh-Hans-fonipa; chino simplificado (Alfabeto fonético internacional IPA) + + +@locale=et +@languageDisplay=standard + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; hispaania (Ladina-Ameerika) +es-Cyrl-MX; hispaania (kirillitsa, Mehhiko) +hi-Latn; hindi (ladina) +nl-BE; hollandi (Belgia) +nl-Latn-BE; hollandi (ladina, Belgia) +zh-Hans-fonipa; hiina (lihtsustatud, IPA foneetika) + + +@locale=et +@languageDisplay=dialect + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; Ladina-Ameerika hispaania +es-Cyrl-MX; Mehhiko hispaania (kirillitsa) +hi-Latn; hindi (ladina) +nl-BE; flaami +nl-Latn-BE; flaami (ladina) +zh-Hans-fonipa; lihtsustatud hiina (IPA foneetika) + + +@locale=eu +@languageDisplay=standard + +en-MM; ingelesa (Myanmar [Birmania]) +es; gaztelania +es-419; gaztelania (Latinoamerika) +es-Cyrl-MX; gaztelania (zirilikoa, Mexiko) +hi-Latn; hindia (latinoa) +nl-BE; nederlandera (Belgika) +nl-Latn-BE; nederlandera (latinoa, Belgika) +zh-Hans-fonipa; txinera (sinplifikatua, IPA ahoskera) + + +@locale=eu +@languageDisplay=dialect + +en-MM; ingelesa (Myanmar [Birmania]) +es; gaztelania +es-419; Latinoamerikako gaztelania +es-Cyrl-MX; Mexikoko gaztelania (zirilikoa) +hi-Latn; hindia [latindarra] +nl-BE; flandriera +nl-Latn-BE; flandriera (latinoa) +zh-Hans-fonipa; txinera sinplifikatua (IPA ahoskera) + + +@locale=fa +@languageDisplay=standard + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی (امریکای لاتین) +es-Cyrl-MX; اسپانیایی (سیریلی، مکزیک) +hi-Latn; هندی (لاتین) +nl-BE; هلندی (بلژیک) +nl-Latn-BE; هلندی (لاتین، بلژیک) +zh-Hans-fonipa; چینی (ساده‌شده، فونتیک IPA) + + +@locale=fa +@languageDisplay=dialect + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی امریکای لاتین +es-Cyrl-MX; اسپانیایی مکزیک (سیریلی) +hi-Latn; هندی (لاتین) +nl-BE; فلمنگی +nl-Latn-BE; فلمنگی (لاتین) +zh-Hans-fonipa; چینی ساده‌شده (فونتیک IPA) + + +@locale=fi +@languageDisplay=standard + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; espanja (Latinalainen Amerikka) +es-Cyrl-MX; espanja (kyrillinen, Meksiko) +hi-Latn; hindi (latinalainen) +nl-BE; hollanti (Belgia) +nl-Latn-BE; hollanti (latinalainen, Belgia) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fi +@languageDisplay=dialect + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; amerikanespanja +es-Cyrl-MX; meksikonespanja (kyrillinen) +hi-Latn; hindi (latinalainen) +nl-BE; flaami +nl-Latn-BE; flaami (latinalainen) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fil +@languageDisplay=standard + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Pinasimple, FONIPA) + + +@locale=fil +@languageDisplay=dialect + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Latin American na Espanyol +es-Cyrl-MX; Mexican na Espanyol (Cyrillic) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Pinasimpleng Chinese (FONIPA) + + +@locale=fr +@languageDisplay=standard + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol (Amérique latine) +es-Cyrl-MX; espagnol (cyrillique, Mexique) +hi-Latn; hindi (latin) +nl-BE; néerlandais (Belgique) +nl-Latn-BE; néerlandais (latin, Belgique) +zh-Hans-fonipa; chinois (simplifié, alphabet phonétique international) + + +@locale=fr +@languageDisplay=dialect + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol d’Amérique latine +es-Cyrl-MX; espagnol du Mexique (cyrillique) +hi-Latn; hindi (latin) +nl-BE; flamand +nl-Latn-BE; flamand (latin) +zh-Hans-fonipa; chinois simplifié (alphabet phonétique international) + + +@locale=ga +@languageDisplay=standard + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis (Meiriceá Laidineach) +es-Cyrl-MX; Spáinnis (Coireallach, Meicsiceo) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Ollainnis (an Bheilg) +nl-Latn-BE; Ollainnis (Laidineach, an Bheilg) +zh-Hans-fonipa; Sínis (Simplithe, Fogharscríobh IPA) + + +@locale=ga +@languageDisplay=dialect + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis Mheiriceá Laidinigh +es-Cyrl-MX; Spáinnis Mheicsiceach (Coireallach) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Pléimeannais +nl-Latn-BE; Pléimeannais (Laidineach) +zh-Hans-fonipa; Sínis Shimplithe (Fogharscríobh IPA) + + +@locale=gd +@languageDisplay=standard + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis (Aimeireaga Laidinneach) +es-Cyrl-MX; Spàinntis (Cirilis, Meagsago) +hi-Latn; Hindis (Laideann) +nl-BE; Duitsis (A’ Bheilg) +nl-Latn-BE; Duitsis (Laideann, A’ Bheilg) +zh-Hans-fonipa; Sìnis (Simplichte, Comharran fuaim-eòlais an IPA) + + +@locale=gd +@languageDisplay=dialect + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis na h-Aimeireaga Laidinneach +es-Cyrl-MX; Spàinntis Mheagsagach (Cirilis) +hi-Latn; Hindis (Laideann) +nl-BE; Flànrais +nl-Latn-BE; Flànrais (Laideann) +zh-Hans-fonipa; Sìnis Shimplichte (Comharran fuaim-eòlais an IPA) + + +@locale=gl +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (América Latina) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélxica) +nl-Latn-BE; neerlandés (latino, Bélxica) +zh-Hans-fonipa; chinés (simplificado, FONIPA) + + +@locale=gl +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español de América +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi [alfabeto latino] +nl-BE; flamengo +nl-Latn-BE; flamengo (latino) +zh-Hans-fonipa; chinés simplificado (FONIPA) + + +@locale=gu +@languageDisplay=standard + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; સ્પેનિશ (લેટિન અમેરિકા) +es-Cyrl-MX; સ્પેનિશ (સિરિલિક, મેક્સિકો) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ડચ (બેલ્જીયમ) +nl-Latn-BE; ડચ (લેટિન, બેલ્જીયમ) +zh-Hans-fonipa; ચાઇનીઝ (સરળીકૃત, FONIPA) + + +@locale=gu +@languageDisplay=dialect + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; લેટિન અમેરિકન સ્પેનિશ +es-Cyrl-MX; મેક્સિકન સ્પેનિશ (સિરિલિક) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ફ્લેમિશ +nl-Latn-BE; ફ્લેમિશ (લેટિન) +zh-Hans-fonipa; સરળીકૃત ચાઇનીઝ (FONIPA) + + +@locale=ha +@languageDisplay=standard + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyanci (Latin Amurka) +es-Cyrl-MX; Sifaniyanci (Cyrillic, Mesiko) +hi-Latn; Harshen Hindi (Latin) +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Harshen Sinanci (Sauƙaƙaƙƙen, FONIPA) + + +@locale=ha +@languageDisplay=dialect + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyancin Latin Amirka +es-Cyrl-MX; Sifaniyanci Mesiko (Cyrillic) +hi-Latn; Hindi [Latinanci] +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Sauƙaƙaƙƙen Sinanci (FONIPA) + + +@locale=he +@languageDisplay=standard + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית (בלגיה) +nl-Latn-BE; הולנדית (לטיני, בלגיה) +zh-Hans-fonipa; סינית (פשוט, אלפבית פונטי בינלאומי) + + +@locale=he +@languageDisplay=dialect + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית [פלמית] +nl-Latn-BE; הולנדית [פלמית] (לטיני) +zh-Hans-fonipa; סינית פשוטה (אלפבית פונטי בינלאומי) + + +@locale=hi +@languageDisplay=standard + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; स्पेनिश (लैटिन अमेरिका) +es-Cyrl-MX; स्पेनिश (सिरिलिक, मैक्सिको) +hi-Latn; हिन्दी (लैटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लैटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=hi +@languageDisplay=dialect + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; लैटिन अमेरिकी स्पेनिश +es-Cyrl-MX; मैक्सिकन स्पेनिश (सिरिलिक) +hi-Latn; हिन्दी (लैटिन) +nl-BE; फ़्लेमिश +nl-Latn-BE; फ़्लेमिश (लैटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=hi_Latn +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=hi_Latn +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=hr +@languageDisplay=standard + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; španjolski (Latinska Amerika) +es-Cyrl-MX; španjolski (ćirilica, Meksiko) +hi-Latn; hindski (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno pismo, IPA fonetika) + + +@locale=hr +@languageDisplay=dialect + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; latinoamerički španjolski +es-Cyrl-MX; meksički španjolski (ćirilica) +hi-Latn; hindski (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=hsb +@languageDisplay=standard + +en-MM; jendźelšćina (Myanmar) +es; španišćina +es-419; španišćina (Łaćonska Amerika) +es-Cyrl-MX; španišćina (kyrilisce, Mexiko) +hi-Latn; hindišćina (łaćonsce) +nl-BE; nižozemšćina (Belgiska) +nl-Latn-BE; nižozemšćina (łaćonsce, Belgiska) +zh-Hans-fonipa; chinšćina (zjednorjene, FONIPA) + + +@locale=hsb +@languageDisplay=dialect + +en-MM; jendźelšćina (Myanmar) +es; španišćina +es-419; łaćonskoameriska španišćina +es-Cyrl-MX; mexiska španišćina (kyrilisce) +hi-Latn; hindišćina (łaćonsce) +nl-BE; flamšćina +nl-Latn-BE; flamšćina (łaćonsce) +zh-Hans-fonipa; chinšćina [zjednorjena] (FONIPA) + + +@locale=hu +@languageDisplay=standard + +en-MM; angol (Mianmar) +es; spanyol +es-419; spanyol (Latin-Amerika) +es-Cyrl-MX; spanyol (Cirill, Mexikó) +hi-Latn; hindi (Latin) +nl-BE; holland (Belgium) +nl-Latn-BE; holland (Latin, Belgium) +zh-Hans-fonipa; kínai (Egyszerűsített, IPA fonetika) + + +@locale=hu +@languageDisplay=dialect + +en-MM; angol (Mianmar) +es; spanyol +es-419; latin-amerikai spanyol +es-Cyrl-MX; spanyol [mexikói] (Cirill) +hi-Latn; hindi [latin] +nl-BE; flamand +nl-Latn-BE; flamand (Latin) +zh-Hans-fonipa; egyszerűsített kínai (IPA fonetika) + + +@locale=hy +@languageDisplay=standard + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; իսպաներեն (Լատինական Ամերիկա) +es-Cyrl-MX; իսպաներեն (կյուրեղագիր, Մեքսիկա) +hi-Latn; հինդի (լատինական) +nl-BE; հոլանդերեն (Բելգիա) +nl-Latn-BE; հոլանդերեն (լատինական, Բելգիա) +zh-Hans-fonipa; չինարեն (պարզեցված, FONIPA) + + +@locale=hy +@languageDisplay=dialect + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; լատինամերիկյան իսպաներեն +es-Cyrl-MX; մեքսիկական իսպաներեն (կյուրեղագիր) +hi-Latn; հինդի (լատինական) +nl-BE; ֆլամանդերեն +nl-Latn-BE; ֆլամանդերեն (լատինական) +zh-Hans-fonipa; պարզեցված չինարեն (FONIPA) + + +@locale=id +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=id +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=ig +@languageDisplay=standard + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi (Latin America) +es-Cyrl-MX; Spanishi (Mkpụrụ Okwu Cyrillic, Mexico) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị (Belgium) +nl-Latn-BE; Dọchị (Latin, Belgium) +zh-Hans-fonipa; Chainisi (Nke dị mfe, FONIPA) + + +@locale=ig +@languageDisplay=dialect + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi ndị Latin America +es-Cyrl-MX; Spanishi ndị Mexico (Mkpụrụ Okwu Cyrillic) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị (Belgium) +nl-Latn-BE; Dọchị (Latin, Belgium) +zh-Hans-fonipa; Asụsụ Chinese dị mfe (FONIPA) + + +@locale=is +@languageDisplay=standard + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; spænska (Rómanska Ameríka) +es-Cyrl-MX; spænska (kyrillískt, Mexíkó) +hi-Latn; hindí (latneskt) +nl-BE; hollenska (Belgía) +nl-Latn-BE; hollenska (latneskt, Belgía) +zh-Hans-fonipa; kínverska (einfaldað, FONIPA) + + +@locale=is +@languageDisplay=dialect + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; rómönsk-amerísk spænska +es-Cyrl-MX; mexíkósk spænska (kyrillískt) +hi-Latn; hindí (latneskt) +nl-BE; flæmska +nl-Latn-BE; flæmska (latneskt) +zh-Hans-fonipa; kínverska [einfölduð] (FONIPA) + + +@locale=it +@languageDisplay=standard + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo (America Latina) +es-Cyrl-MX; spagnolo (cirillico, Messico) +hi-Latn; hindi (latino) +nl-BE; olandese (Belgio) +nl-Latn-BE; olandese (latino, Belgio) +zh-Hans-fonipa; cinese (semplificato, alfabeto fonetico internazionale IPA) + + +@locale=it +@languageDisplay=dialect + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo latinoamericano +es-Cyrl-MX; spagnolo messicano (cirillico) +hi-Latn; hindi (latino) +nl-BE; fiammingo +nl-Latn-BE; fiammingo (latino) +zh-Hans-fonipa; cinese semplificato (alfabeto fonetico internazionale IPA) + + +@locale=ja +@languageDisplay=standard + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 (ラテン文字) +nl-BE; オランダ語 (ベルギー) +nl-Latn-BE; オランダ語 (ラテン文字、ベルギー) +zh-Hans-fonipa; 中国語 (簡体字、国際音声記号) + + +@locale=ja +@languageDisplay=dialect + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 (ラテン文字) +nl-BE; フラマン語 +nl-Latn-BE; フラマン語 (ラテン文字) +zh-Hans-fonipa; 簡体中国語 (国際音声記号) + + +@locale=jv +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amérika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Mèksiko) +hi-Latn; India (Latin) +nl-BE; Walanda (Bèlgi) +nl-Latn-BE; Walanda (Latin, Bèlgi) +zh-Hans-fonipa; Tyonghwa (Prasaja, FONIPA) + + +@locale=jv +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol [Amerika Latin] +es-Cyrl-MX; Spanyol [Meksiko] (Sirilik) +hi-Latn; India (Latin) +nl-BE; Flemis +nl-Latn-BE; Flemis (Latin) +zh-Hans-fonipa; Tyonghwa [Ringkes] (FONIPA) + + +@locale=ka +@languageDisplay=standard + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ესპანური (ლათინური ამერიკა) +es-Cyrl-MX; ესპანური (კირილიცა, მექსიკა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ნიდერლანდური (ბელგია) +nl-Latn-BE; ნიდერლანდური (ლათინური, ბელგია) +zh-Hans-fonipa; ჩინური (გამარტივებული, FONIPA) + + +@locale=ka +@languageDisplay=dialect + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ლათინურ ამერიკული ესპანური +es-Cyrl-MX; მექსიკური ესპანური (კირილიცა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ფლამანდიური +nl-Latn-BE; ფლამანდიური (ლათინური) +zh-Hans-fonipa; გამარტივებული ჩინური (FONIPA) + + +@locale=kk +@languageDisplay=standard + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; хинди тілі (латын жазуы) +nl-BE; нидерланд тілі (Бельгия) +nl-Latn-BE; нидерланд тілі (латын жазуы, Бельгия) +zh-Hans-fonipa; қытай тілі (жеңілдетілген жазу, Халықаралық фонетикалық әліпби) + + +@locale=kk +@languageDisplay=dialect + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; хинди тілі (латын жазуы) +nl-BE; фламанд тілі +nl-Latn-BE; фламанд тілі (латын жазуы) +zh-Hans-fonipa; жеңілдетілген қытай тілі (Халықаралық фонетикалық әліпби) + + +@locale=km +@languageDisplay=standard + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ហូឡង់ (បែលហ្ស៊ិក) +nl-Latn-BE; ហូឡង់ (ឡាតាំង, បែលហ្ស៊ិក) +zh-Hans-fonipa; ចិន (អក្សរ​ចិន​កាត់, FONIPA) + + +@locale=km +@languageDisplay=dialect + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ផ្លាមីស +nl-Latn-BE; ផ្លាមីស (ឡាតាំង) +zh-Hans-fonipa; ចិន​អក្សរ​កាត់ (FONIPA) + + +@locale=kn +@languageDisplay=standard + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಸ್ಪ್ಯಾನಿಷ್ (ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕಾ) +es-Cyrl-MX; ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್, ಮೆಕ್ಸಿಕೊ) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಡಚ್ (ಬೆಲ್ಜಿಯಮ್) +nl-Latn-BE; ಡಚ್ (ಲ್ಯಾಟಿನ್, ಬೆಲ್ಜಿಯಮ್) +zh-Hans-fonipa; ಚೈನೀಸ್ (ಸರಳೀಕೃತ, FONIPA) + + +@locale=kn +@languageDisplay=dialect + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ +es-Cyrl-MX; ಮೆಕ್ಸಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಫ್ಲೆಮಿಷ್ +nl-Latn-BE; ಫ್ಲೆಮಿಷ್ (ಲ್ಯಾಟಿನ್) +zh-Hans-fonipa; ಸರಳೀಕೃತ ಚೈನೀಸ್ (FONIPA) + + +@locale=ko +@languageDisplay=standard + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 네덜란드어(벨기에) +nl-Latn-BE; 네덜란드어(로마자, 벨기에) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=ko +@languageDisplay=dialect + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 플라망어 +nl-Latn-BE; 플라망어(로마자) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=kok +@languageDisplay=standard + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; स्पॅनीश (लॅटीन अमेरिका) +es-Cyrl-MX; स्पॅनीश (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटीन, बेल्जियम) +zh-Hans-fonipa; चिनी (सोंपी, FONIPA) + + +@locale=kok +@languageDisplay=dialect + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; लातीं अमेरिकन स्पॅनीश +es-Cyrl-MX; मॅक्सिकन स्पॅनीश (सिरिलिक) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटीन) +zh-Hans-fonipa; सोंपी चिनी (FONIPA) + + +@locale=ky +@languageDisplay=standard + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; голландча (Бельгия) +nl-Latn-BE; голландча (Латын, Бельгия) +zh-Hans-fonipa; кытайча (Жөнөкөйлөштүрүлгөн, FONIPA) + + +@locale=ky +@languageDisplay=dialect + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; фламандча +nl-Latn-BE; фламандча (Латын) +zh-Hans-fonipa; кытайча [жөнөкөйлөштүрүлгөн] (FONIPA) + + +@locale=lo +@languageDisplay=standard + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ສະແປນນິຊ (ລາຕິນ ອາເມລິກາ) +es-Cyrl-MX; ສະແປນນິຊ (ຊີຣິວລິກ, ເມັກຊິໂກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ດັຊ (ເບວຢຽມ) +nl-Latn-BE; ດັຊ (ລາຕິນ, ເບວຢຽມ) +zh-Hans-fonipa; ຈີນ (ແບບຮຽບງ່າຍ, ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lo +@languageDisplay=dialect + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ລາຕິນ ອາເມຣິກັນ ສະແປນນິຊ +es-Cyrl-MX; ເມັກຊິກັນ ສະແປນນິຊ (ຊີຣິວລິກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ຟລີມິຊ +nl-Latn-BE; ຟລີມິຊ (ລາຕິນ) +zh-Hans-fonipa; ຈີນແບບຮຽບງ່າຍ (ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lt +@languageDisplay=standard + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; ispanų (Lotynų Amerika) +es-Cyrl-MX; ispanų (kirilica, Meksika) +hi-Latn; hindi (lotynų) +nl-BE; olandų (Belgija) +nl-Latn-BE; olandų (lotynų, Belgija) +zh-Hans-fonipa; kinų (supaprastinti, Tarptautinės abėcėlės fonetika) + + +@locale=lt +@languageDisplay=dialect + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; Lotynų Amerikos ispanų +es-Cyrl-MX; Meksikos ispanų (kirilica) +hi-Latn; hindi (lotynų) +nl-BE; flamandų +nl-Latn-BE; flamandų (lotynų) +zh-Hans-fonipa; supaprastintoji kinų (Tarptautinės abėcėlės fonetika) + + +@locale=lv +@languageDisplay=standard + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi (latīņu) +nl-BE; holandiešu (Beļģija) +nl-Latn-BE; holandiešu (latīņu, Beļģija) +zh-Hans-fonipa; ķīniešu (vienkāršotā, Starptautiskais fonētiskais alfabēts) + + +@locale=lv +@languageDisplay=dialect + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi (latīņu) +nl-BE; flāmu +nl-Latn-BE; flāmu (latīņu) +zh-Hans-fonipa; ķīniešu vienkāršotā (Starptautiskais fonētiskais alfabēts) + + +@locale=mk +@languageDisplay=standard + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (кирилско писмо, Мексико) +hi-Latn; хинди (латинично писмо) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латинично писмо, Белгија) +zh-Hans-fonipa; кинески (поедноставено, FONIPA) + + +@locale=mk +@languageDisplay=dialect + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; латиноамерикански шпански +es-Cyrl-MX; мексикански шпански (кирилско писмо) +hi-Latn; хинди (латинично писмо) +nl-BE; фламански +nl-Latn-BE; фламански (латинично писмо) +zh-Hans-fonipa; поедноставен кинески (FONIPA) + + +@locale=ml +@languageDisplay=standard + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; സ്‌പാനിഷ് (ലാറ്റിനമേരിക്ക) +es-Cyrl-MX; സ്‌പാനിഷ് (സിറിലിക്, മെക്സിക്കോ) +hi-Latn; ഹിന്ദി (ലാറ്റിൻ) +nl-BE; ഡച്ച് (ബെൽജിയം) +nl-Latn-BE; ഡച്ച് (ലാറ്റിൻ, ബെൽജിയം) +zh-Hans-fonipa; ചൈനീസ് (ലളിതവൽക്കരിച്ചത്, ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=ml +@languageDisplay=dialect + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; ലാറ്റിൻ അമേരിക്കൻ സ്‌പാനിഷ് +es-Cyrl-MX; മെക്സിക്കൻ സ്പാനിഷ് (സിറിലിക്) +hi-Latn; ഹിന്ദി (ലാറ്റിൻ) +nl-BE; ഫ്ലമിഷ് +nl-Latn-BE; ഫ്ലമിഷ് (ലാറ്റിൻ) +zh-Hans-fonipa; ലളിതമാക്കിയ ചൈനീസ് (ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=mn +@languageDisplay=standard + +en-MM; англи (Мьянмар) +es; испани +es-419; испани (Латин Америк) +es-Cyrl-MX; испани (кирилл, Мексик) +hi-Latn; хинди (латин) +nl-BE; нидерланд (Бельги) +nl-Latn-BE; нидерланд (латин, Бельги) +zh-Hans-fonipa; хятад (хялбаршуулсан, FONIPA) + + +@locale=mn +@languageDisplay=dialect + +en-MM; англи (Мьянмар) +es; испани +es-419; испани хэл [Латин Америк] +es-Cyrl-MX; испани хэл [Мексик] (кирилл) +hi-Latn; хинди (латин) +nl-BE; фламанд +nl-Latn-BE; фламанд (латин) +zh-Hans-fonipa; хялбаршуулсан хятад (FONIPA) + + +@locale=mr +@languageDisplay=standard + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; स्पॅनिश (लॅटिन अमेरिका) +es-Cyrl-MX; स्पॅनिश (सीरिलिक, मेक्सिको) +hi-Latn; हिंदी (लॅटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=mr +@languageDisplay=dialect + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; लॅटिन अमेरिकन स्पॅनिश +es-Cyrl-MX; मेक्सिकन स्पॅनिश (सीरिलिक) +hi-Latn; हिंदी (लॅटिन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=ms +@languageDisplay=standard + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol (Amerika Latin) +es-Cyrl-MX; Sepanyol (Cyril, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgium) +nl-Latn-BE; Belanda (Latin, Belgium) +zh-Hans-fonipa; Cina (Ringkas, Fonetik IPA) + + +@locale=ms +@languageDisplay=dialect + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol Amerika Latin +es-Cyrl-MX; Sepanyol Mexico (Cyril) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Cina Ringkas (Fonetik IPA) + + +@locale=my +@languageDisplay=standard + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် (စစ်ရိလစ်/ မက်ကဆီကို) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဒတ်ခ်ျ (ဘယ်လ်ဂျီယမ်) +nl-Latn-BE; ဒတ်ခ်ျ (လက်တင်/ ဘယ်လ်ဂျီယမ်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=my +@languageDisplay=dialect + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် [မက္ကဆီကို] (စစ်ရိလစ်) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဖလီမစ်ရှ် +nl-Latn-BE; ဖလီမစ်ရှ် (လက်တင်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=nb +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=nb +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=ne +@languageDisplay=standard + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; स्पेनी (ल्याटिन अमेरिका) +es-Cyrl-MX; स्पेनी (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (ल्याटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (ल्याटिन, बेल्जियम) +zh-Hans-fonipa; चिनियाँ (सरलिकृत चिनियाँ, FONIPA) + + +@locale=ne +@languageDisplay=dialect + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; ल्याटिन अमेरिकी स्पेनी +es-Cyrl-MX; मेक्सिकन स्पेनी (सिरिलिक) +hi-Latn; हिन्दी (ल्याटिन) +nl-BE; फ्लेमिस +nl-Latn-BE; फ्लेमिस (ल्याटिन) +zh-Hans-fonipa; सरलिकृत चिनियाँ (FONIPA) + + +@locale=nl +@languageDisplay=standard + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latijns, België) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nl +@languageDisplay=dialect + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latijns) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nn +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenkla, det internasjonale fonetiske alfabetet [IPA]) + + +@locale=nn +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenkla kinesisk (det internasjonale fonetiske alfabetet [IPA]) + + +@locale=no +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=no +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=or +@languageDisplay=standard + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ସ୍ପେନିୟ (ଲାଟିନ୍‌ ଆମେରିକା) +es-Cyrl-MX; ସ୍ପେନିୟ (ସିରିଲିକ୍, ମେକ୍ସିକୋ) +hi-Latn; ହିନ୍ଦୀ (ଲାଟିନ୍) +nl-BE; ଡଚ୍ (ବେଲଜିୟମ୍) +nl-Latn-BE; ଡଚ୍ (ଲାଟିନ୍, ବେଲଜିୟମ୍) +zh-Hans-fonipa; ଚାଇନିଜ୍‌ (ସରଳୀକୃତ, FONIPA) + + +@locale=or +@languageDisplay=dialect + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ଲାଟିନ୍‌ ଆମେରିକୀୟ ସ୍ପାନିସ୍‌ +es-Cyrl-MX; ମେକ୍ସିକାନ ସ୍ପାନିସ୍‌ (ସିରିଲିକ୍) +hi-Latn; ହିନ୍ଦୀ (ଲାଟିନ୍) +nl-BE; ଫ୍ଲେମିଶ୍ +nl-Latn-BE; ଫ୍ଲେମିଶ୍ (ଲାଟିନ୍) +zh-Hans-fonipa; ସରଳୀକୃତ ଚାଇନିଜ୍‌ (FONIPA) + + +@locale=pa +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa_Guru +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa_Guru +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pl +@languageDisplay=standard + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; hiszpański (Ameryka Łacińska) +es-Cyrl-MX; hiszpański (cyrylica, Meksyk) +hi-Latn; hindi (łacińskie) +nl-BE; niderlandzki (Belgia) +nl-Latn-BE; niderlandzki (łacińskie, Belgia) +zh-Hans-fonipa; chiński (uproszczone, fonetyczny międzynarodowy) + + +@locale=pl +@languageDisplay=dialect + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; amerykański hiszpański +es-Cyrl-MX; meksykański hiszpański (cyrylica) +hi-Latn; hindi [alfabet łaciński] +nl-BE; flamandzki +nl-Latn-BE; flamandzki (łacińskie) +zh-Hans-fonipa; chiński uproszczony (fonetyczny międzynarodowy) + + +@locale=ps +@languageDisplay=standard + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاتیني امریکا) +es-Cyrl-MX; هسپانوي (سیریلیک, میکسیکو) +hi-Latn; هندي (لاتين/لاتيني) +nl-BE; هالېنډي (بیلجیم) +nl-Latn-BE; هالېنډي (لاتين/لاتيني, بیلجیم) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=ps +@languageDisplay=dialect + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; لاتيني امريکايي هسپانوي +es-Cyrl-MX; ميکسيکي هسپانوي (سیریلیک) +hi-Latn; هندي [لاتيني] +nl-BE; فلېمېشي +nl-Latn-BE; فلېمېشي (لاتين/لاتيني) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=pt +@languageDisplay=standard + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; holandês (Bélgica) +nl-Latn-BE; holandês (latim, Bélgica) +zh-Hans-fonipa; chinês (simplificado, fonética do Alfabeto Fonético Internacional) + + +@locale=pt +@languageDisplay=dialect + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; flamengo +nl-Latn-BE; flamengo (latim) +zh-Hans-fonipa; chinês simplificado (fonética do Alfabeto Fonético Internacional) + + +@locale=ro +@languageDisplay=standard + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; neerlandeză (Belgia) +nl-Latn-BE; neerlandeză (latină, Belgia) +zh-Hans-fonipa; chineză (simplificată, alfabet fonetic internațional) + + +@locale=ro +@languageDisplay=dialect + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; flamandă +nl-Latn-BE; flamandă (latină) +zh-Hans-fonipa; chineză simplificată (alfabet fonetic internațional) + + +@locale=root +@languageDisplay=standard + +en-MM; en (MM) +es; es +es-419; es (419) +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=root +@languageDisplay=dialect + +en-MM; en (MM) +es; es +es-419; es_419 +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=ru +@languageDisplay=standard + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; испанский (Латинская Америка) +es-Cyrl-MX; испанский (кириллица, Мексика) +hi-Latn; хинди (латиница) +nl-BE; нидерландский (Бельгия) +nl-Latn-BE; нидерландский (латиница, Бельгия) +zh-Hans-fonipa; китайский (упрощенная, Международный фонетический алфавит) + + +@locale=ru +@languageDisplay=dialect + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; латиноамериканский испанский +es-Cyrl-MX; мексиканский испанский (кириллица) +hi-Latn; хинди (латиница) +nl-BE; фламандский +nl-Latn-BE; фламандский (латиница) +zh-Hans-fonipa; китайский, упрощенное письмо (Международный фонетический алфавит) + + +@locale=sd +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=si +@languageDisplay=standard + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ස්පාඤ්ඤ (ලතින් ඇමෙරිකාව) +es-Cyrl-MX; ස්පාඤ්ඤ (සිරිලික්, මෙක්සිකෝව) +hi-Latn; හින්දි (ලතින්) +nl-BE; ලන්දේසි (බෙල්ජියම) +nl-Latn-BE; ලන්දේසි (ලතින්, බෙල්ජියම) +zh-Hans-fonipa; චීන (සුළුකළ, FONIPA) + + +@locale=si +@languageDisplay=dialect + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ලතින් ඇමරිකානු ස්පාඤ්ඤ +es-Cyrl-MX; මෙක්සිකානු ස්පාඤ්ඤ (සිරිලික්) +hi-Latn; හින්දි (ලතින්) +nl-BE; ෆ්ලෙමිශ් +nl-Latn-BE; ෆ්ලෙමිශ් (ලතින්) +zh-Hans-fonipa; සරල චීන (FONIPA) + + +@locale=sk +@languageDisplay=standard + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina (Latinská Amerika) +es-Cyrl-MX; španielčina (cyrilika, Mexiko) +hi-Latn; hindčina (latinka) +nl-BE; holandčina (Belgicko) +nl-Latn-BE; holandčina (latinka, Belgicko) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=sk +@languageDisplay=dialect + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina [latinskoamerická] +es-Cyrl-MX; španielčina [mexická] (cyrilika) +hi-Latn; hindčina (latinka) +nl-BE; flámčina +nl-Latn-BE; flámčina (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=sl +@languageDisplay=standard + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; španščina (Latinska Amerika) +es-Cyrl-MX; španščina (cirilica, Mehika) +hi-Latn; hindijščina (latinica) +nl-BE; nizozemščina (Belgija) +nl-Latn-BE; nizozemščina (latinica, Belgija) +zh-Hans-fonipa; kitajščina (poenostavljena pisava, mednarodna fonetična pisava IPA) + + +@locale=sl +@languageDisplay=dialect + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; latinskoameriška španščina +es-Cyrl-MX; mehiška španščina (cirilica) +hi-Latn; hindijščina (latinica) +nl-BE; flamščina +nl-Latn-BE; flamščina (latinica) +zh-Hans-fonipa; poenostavljena kitajščina (mednarodna fonetična pisava IPA) + + +@locale=so +@languageDisplay=standard + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanish (Laatiin Ameerika) +es-Cyrl-MX; Isbaanish (Siriylik, Meksiko) +hi-Latn; Hindi (Laatiin) +nl-BE; Holandays (Biljam) +nl-Latn-BE; Holandays (Laatiin, Biljam) +zh-Hans-fonipa; Shiinaha Mandarin (La fududeeyay, FONIPA) + + +@locale=so +@languageDisplay=dialect + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanishka Laatiin Ameerika +es-Cyrl-MX; Isbaanishka Mexico (Siriylik) +hi-Latn; Hindi [Latin] +nl-BE; Af faleemi +nl-Latn-BE; Af faleemi (Laatiin) +zh-Hans-fonipa; Shiinaha Rasmiga ah (FONIPA) + + +@locale=sq +@languageDisplay=standard + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjisht (Amerika Latine) +es-Cyrl-MX; spanjisht (cirilik, Meksikë) +hi-Latn; indisht (latin) +nl-BE; holandisht (Belgjikë) +nl-Latn-BE; holandisht (latin, Belgjikë) +zh-Hans-fonipa; kinezisht (i thjeshtuar, FONIPA) + + +@locale=sq +@languageDisplay=dialect + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjishte amerikano-latine +es-Cyrl-MX; spanjishte meksikane (cirilik) +hi-Latn; indisht (latin) +nl-BE; flamandisht +nl-Latn-BE; flamandisht (latin) +zh-Hans-fonipa; kinezishte e thjeshtuar (FONIPA) + + +@locale=sr +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Latn +@languageDisplay=standard + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; holandski (Belgija) +nl-Latn-BE; holandski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno kinesko pismo, IPA fonetika) + + +@locale=sr_Latn +@languageDisplay=dialect + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; pojednostavljeni kineski (IPA fonetika) + + +@locale=sv +@languageDisplay=standard + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; spanska (Latinamerika) +es-Cyrl-MX; spanska (kyrilliska, Mexiko) +hi-Latn; hindi (latinska) +nl-BE; nederländska (Belgien) +nl-Latn-BE; nederländska (latinska, Belgien) +zh-Hans-fonipa; kinesiska (förenklad, internationell fonetisk notation - IPA) + + +@locale=sv +@languageDisplay=dialect + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; latinamerikansk spanska +es-Cyrl-MX; mexikansk spanska (kyrilliska) +hi-Latn; hindi [latinsk] +nl-BE; flamländska +nl-Latn-BE; flamländska (latinska) +zh-Hans-fonipa; förenklad kinesiska (internationell fonetisk notation - IPA) + + +@locale=sw +@languageDisplay=standard + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania (Amerika ya Kilatini) +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiholanzi (Ubelgiji) +nl-Latn-BE; Kiholanzi (Kilatini, Ubelgiji) +zh-Hans-fonipa; Kichina (Rahisi, FONIPA) + + +@locale=sw +@languageDisplay=dialect + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania [Amerika ya Latini] +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiflemi +nl-Latn-BE; Kiflemi (Kilatini) +zh-Hans-fonipa; Kichina [Kilichorahisishwa] (FONIPA) + + +@locale=ta +@languageDisplay=standard + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; ஸ்பானிஷ் (லத்தீன் அமெரிக்கா) +es-Cyrl-MX; ஸ்பானிஷ் (சிரிலிக், மெக்சிகோ) +hi-Latn; இந்தி (லத்தின்) +nl-BE; டச்சு (பெல்ஜியம்) +nl-Latn-BE; டச்சு (லத்தின், பெல்ஜியம்) +zh-Hans-fonipa; சீனம் (எளிதாக்கப்பட்டது, FONIPA) + + +@locale=ta +@languageDisplay=dialect + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; லத்தின் அமெரிக்க ஸ்பானிஷ் +es-Cyrl-MX; மெக்ஸிகன் ஸ்பானிஷ் (சிரிலிக்) +hi-Latn; இந்தி (லத்தின்) +nl-BE; ஃப்லெமிஷ் +nl-Latn-BE; ஃப்லெமிஷ் (லத்தின்) +zh-Hans-fonipa; எளிதாக்கப்பட்ட சீனம் (FONIPA) + + +@locale=te +@languageDisplay=standard + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; స్పానిష్ (లాటిన్ అమెరికా) +es-Cyrl-MX; స్పానిష్ (సిరిలిక్, మెక్సికో) +hi-Latn; హిందీ (లాటిన్) +nl-BE; డచ్ (బెల్జియం) +nl-Latn-BE; డచ్ (లాటిన్, బెల్జియం) +zh-Hans-fonipa; చైనీస్ (సరళీకృతం, FONIPA) + + +@locale=te +@languageDisplay=dialect + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; లాటిన్ అమెరికన్ స్పానిష్ +es-Cyrl-MX; మెక్సికన్ స్పానిష్ (సిరిలిక్) +hi-Latn; హిందీ (లాటిన్) +nl-BE; ఫ్లెమిష్ +nl-Latn-BE; ఫ్లెమిష్ (లాటిన్) +zh-Hans-fonipa; సరళీకృత చైనీస్ (FONIPA) + + +@locale=th +@languageDisplay=standard + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน (ละตินอเมริกา) +es-Cyrl-MX; สเปน (ซีริลลิก, เม็กซิโก) +hi-Latn; ฮินดี (ละติน) +nl-BE; ดัตช์ (เบลเยียม) +nl-Latn-BE; ดัตช์ (ละติน, เบลเยียม) +zh-Hans-fonipa; จีน (ตัวย่อ, สัทอักษรสากล) + + +@locale=th +@languageDisplay=dialect + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน - ละตินอเมริกา +es-Cyrl-MX; สเปน - เม็กซิโก (ซีริลลิก) +hi-Latn; ฮินดี (ละติน) +nl-BE; เฟลมิช +nl-Latn-BE; เฟลมิช (ละติน) +zh-Hans-fonipa; จีนตัวย่อ (สัทอักษรสากล) + + +@locale=tk +@languageDisplay=standard + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; niderland dili (Belgiýa) +nl-Latn-BE; niderland dili (Latyn elipbiýi, Belgiýa) +zh-Hans-fonipa; hytaý dili (Ýönekeýleşdirilen, FONIPA) + + +@locale=tk +@languageDisplay=dialect + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; flamand dili +nl-Latn-BE; flamand dili (Latyn elipbiýi) +zh-Hans-fonipa; ýönekeýleşdirilen hytaý dili (FONIPA) + + +@locale=tr +@languageDisplay=standard + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; İspanyolca (Latin Amerika) +es-Cyrl-MX; İspanyolca (Kiril, Meksika) +hi-Latn; Hintçe (Latin) +nl-BE; Felemenkçe (Belçika) +nl-Latn-BE; Felemenkçe (Latin, Belçika) +zh-Hans-fonipa; Çince (Basitleştirilmiş, IPA Ses Bilimi) + + +@locale=tr +@languageDisplay=dialect + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; Latin Amerika İspanyolcası +es-Cyrl-MX; Meksika İspanyolcası (Kiril) +hi-Latn; Hintçe (Latin) +nl-BE; Flamanca +nl-Latn-BE; Flamanca (Latin) +zh-Hans-fonipa; Basitleştirilmiş Çince (IPA Ses Bilimi) + + +@locale=uk +@languageDisplay=standard + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; іспанська (Латинська Америка) +es-Cyrl-MX; іспанська (кирилиця, Мексика) +hi-Latn; гінді (латиниця) +nl-BE; нідерландська (Бельгія) +nl-Latn-BE; нідерландська (латиниця, Бельгія) +zh-Hans-fonipa; китайська (спрощена, Міжнародний фонетичний алфавіт) + + +@locale=uk +@languageDisplay=dialect + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; іспанська (Латинська Америка) +es-Cyrl-MX; іспанська (кирилиця, Мексика) +hi-Latn; гінді (латиниця) +nl-BE; фламандська +nl-Latn-BE; фламандська (латиниця) +zh-Hans-fonipa; китайська [спрощене письмо] (Міжнародний фонетичний алфавіт) + + +@locale=ur +@languageDisplay=standard + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; ہسپانوی (لاطینی امریکہ) +es-Cyrl-MX; ہسپانوی (سیریلک،میکسیکو) +hi-Latn; ہندی (لاطینی) +nl-BE; ڈچ (بیلجیم) +nl-Latn-BE; ڈچ (لاطینی،بیلجیم) +zh-Hans-fonipa; چینی (آسان،FONIPA) + + +@locale=ur +@languageDisplay=dialect + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; لاطینی امریکی ہسپانوی +es-Cyrl-MX; میکسیکن ہسپانوی (سیریلک) +hi-Latn; ہندی (لاطینی) +nl-BE; فلیمِش +nl-Latn-BE; فلیمِش (لاطینی) +zh-Hans-fonipa; چینی [آسان کردہ] (FONIPA) + + +@locale=uz +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind (lotin) +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz_Latn +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz_Latn +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind (lotin) +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=vi +@languageDisplay=standard + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha (Châu Mỹ La-tinh) +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Hà Lan (Bỉ) +nl-Latn-BE; Tiếng Hà Lan (Chữ La tinh, Bỉ) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=vi +@languageDisplay=dialect + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha [Mỹ La tinh] +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Flemish +nl-Latn-BE; Tiếng Flemish (Chữ La tinh) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=yo +@languageDisplay=standard + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì (Látín Amẹ́ríkà) +es-Cyrl-MX; Èdè Sípáníìṣì (èdè ilẹ̀ Rọ́ṣíà, Mesiko) +hi-Latn; Èdè Híńdì (Èdè Látìn) +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Edè Ṣáínà (tí wọ́n mú rọrùn., FONIPA) + + +@locale=yo +@languageDisplay=dialect + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì [orílẹ̀-èdè Látìn-Amẹ́ríkà] +es-Cyrl-MX; Èdè Sípáníìṣì [orílẹ̀-èdè Mẹ́síkò] (èdè ilẹ̀ Rọ́ṣíà) +hi-Latn; Èdè Híndì [Látìnì] +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Ẹdè Ṣáínà Onírọ̀rùn (FONIPA) + + +@locale=yue +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=standard + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷兰文 (比利时) +nl-Latn-BE; 荷兰文 (拉丁文,比利时) +zh-Hans-fonipa; 中文 (简体,IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=dialect + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛兰芒文 +nl-Latn-BE; 佛兰芒文 (拉丁文) +zh-Hans-fonipa; 简体中文 (IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=zh +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hans +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh_Hans +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hant +@languageDisplay=standard + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地文(拉丁文) +nl-BE; 荷蘭文(比利時) +nl-Latn-BE; 荷蘭文(拉丁文,比利時) +zh-Hans-fonipa; 中文(簡體,IPA 拼音) + + +@locale=zh_Hant +@languageDisplay=dialect + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地語[拉丁文] +nl-BE; 法蘭德斯文 +nl-Latn-BE; 法蘭德斯文(拉丁文) +zh-Hans-fonipa; 簡體中文(IPA 拼音) + + +@locale=zu +@languageDisplay=standard + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Spanish (i-Latin America) +es-Cyrl-MX; isi-Spanish (isi-Cyrillic, i-Mexico) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Dutch (i-Belgium) +nl-Latn-BE; isi-Dutch (isi-Latin, i-Belgium) +zh-Hans-fonipa; isi-Chinese (enziwe lula, Ifonotiki ye-IPA) + + +@locale=zu +@languageDisplay=dialect + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Latin American Spanish +es-Cyrl-MX; isi-Mexican Spanish (isi-Cyrillic) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Flemish +nl-Latn-BE; isi-Flemish (isi-Latin) +zh-Hans-fonipa; isi-Chinese [esenziwe-lula] (Ifonotiki ye-IPA) + diff --git a/testgen/icu75/localeDisplayName.txt b/testgen/icu75/localeDisplayName.txt new file mode 100644 index 00000000..20b30cb4 --- /dev/null +++ b/testgen/icu75/localeDisplayName.txt @@ -0,0 +1,3071 @@ +# Test data for locale display name generation +# Copyright © 1991-2024 Unicode, Inc. +# For terms of use, see http://www.unicode.org/copyright.html +# SPDX-License-Identifier: Unicode-3.0 +# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/) +# Format: +# @locale= +# @languageDisplay=[standard|dialect] +# standard - always display additional subtags like region in parentheses +# dialect - form compounds like "Flemish" for nl_BE +# ; + +@locale=en +@languageDisplay=standard + + +# Simple cases: Language, script, region, variants + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + +#Note that the order of the variants is alphabetized before generating names + +en-Latn-GB-scouse-fonipa; English (Latin, United Kingdom, IPA Phonetics, Scouse) + +# Add extensions, and verify their order + +en-u-nu-deva-t-de; English (Transform: German, Devanagari Digits) +en-u-nu-thai-ca-islamic-civil; English (Hijri Calendar [tabular, civil epoch], Thai Digits) +hi-u-nu-latn-t-en-h0-hybrid; Hindi (Hybrid: English, Western Digits) + +# Test ordering of extensions (include well-formed but invalid cases) + +fr-z-zz-zzz-v-vv-vvv-u-uu-uuu-t-ru-Cyrl-s-ss-sss-a-aa-aaa-x-u-x; French (Transform: Russian [Cyrillic], uu: uuu, a: aa-aaa, s: ss-sss, v: vv-vvv, x: u-x, z: zz-zzz) + +# Comprehensive list (mostly comprehensive: currencies, subdivisions, timezones have abbreviated lists) + +en-u-ca-buddhist; English (Buddhist Calendar) +en-u-ca-chinese; English (Chinese Calendar) +en-u-ca-coptic; English (Coptic Calendar) +en-u-ca-dangi; English (Dangi Calendar) +en-u-ca-ethioaa; English (Ethiopic Amete Alem Calendar) +en-u-ca-ethiopic; English (Ethiopic Calendar) +en-u-ca-gregory; English (Gregorian Calendar) +en-u-ca-hebrew; English (Hebrew Calendar) +en-u-ca-indian; English (Indian National Calendar) +en-u-ca-islamic; English (Hijri Calendar) +en-u-ca-islamic-civil; English (Hijri Calendar [tabular, civil epoch]) +en-u-ca-islamic-rgsa; English (Hijri Calendar [Saudi Arabia, sighting]) +en-u-ca-islamic-tbla; English (Hijri Calendar [tabular, astronomical epoch]) +en-u-ca-islamic-umalqura; English (Hijri Calendar [Umm al-Qura]) +en-u-ca-iso8601; English (ISO-8601 Calendar) +en-u-ca-japanese; English (Japanese Calendar) +en-u-ca-persian; English (Persian Calendar) +en-u-ca-roc; English (Minguo Calendar) +en-u-cf-account; English (Accounting Currency Format) +en-u-cf-standard; English (Standard Currency Format) +en-u-co-big5han; English (Traditional Chinese Sort Order - Big5) +en-u-co-compat; English (Previous Sort Order, for compatibility) +en-u-co-dict; English (Dictionary Sort Order) +en-u-co-ducet; English (Default Unicode Sort Order) +en-u-co-emoji; English (Emoji Sort Order) +en-u-co-eor; English (European Ordering Rules) +en-u-co-gb2312; English (Simplified Chinese Sort Order - GB2312) +en-u-co-phonebk; English (Phonebook Sort Order) +en-u-co-phonetic; English (Phonetic Sort Order) +en-u-co-pinyin; English (Pinyin Sort Order) +en-u-co-search; English (General-Purpose Search) +en-u-co-searchjl; English (Search By Hangul Initial Consonant) +en-u-co-standard; English (Standard Sort Order) +en-u-co-stroke; English (Stroke Sort Order) +en-u-co-trad; English (Traditional Sort Order) +en-u-co-unihan; English (Radical-Stroke Sort Order) +en-u-co-zhuyin; English (Zhuyin Sort Order) +en-u-cu-eur; English (Currency: €) +en-u-cu-jpy; English (Currency: ¥) +en-u-cu-usd; English (Currency: $) +en-u-cu-chf; English (Currency: CHF) +en-t-d0-accents; English (To Accented Characters From ASCII Sequence) +en-t-d0-ascii; English (To ASCII) +en-t-d0-casefold; English (To Casefolded) +en-t-d0-charname; English (To Unicode Character Names) +en-t-d0-digit; English (To Digit Form Of Accent) +en-t-d0-fcc; English (To Unicode FCC) +en-t-d0-fcd; English (To Unicode FCD) +en-t-d0-fwidth; English (To Fullwidth) +en-t-d0-hex; English (To Hexadecimal Codes) +en-t-d0-hwidth; English (To Halfwidth) +en-t-d0-lower; English (To Lowercase) +en-t-d0-morse; English (To Morse Code) +en-t-d0-nfc; English (To Unicode NFC) +en-t-d0-nfd; English (To Unicode NFD) +en-t-d0-nfkc; English (To Unicode NFKC) +en-t-d0-nfkd; English (To Unicode NFKD) +en-t-d0-npinyin; English (To Pinyin With Numeric Tones) +en-t-d0-null; English (No Change) +en-t-d0-publish; English (To Publishing Characters From ASCII) +en-t-d0-remove; English (To Empty String) +en-t-d0-title; English (To Titlecase) +en-t-d0-upper; English (To Uppercase) +en-t-d0-zawgyi; English (To Zawgyi Myanmar Encoding) +en-u-dx-thai; English (Dictionary Break Exclusions: thai) +en-u-em-default; English (Use Default Presentation For Emoji Characters) +en-u-em-emoji; English (Prefer Emoji Presentation For Emoji Characters) +en-u-em-text; English (Prefer Text Presentation For Emoji Characters) +en-u-fw-fri; English (First Day of Week Is Friday) +en-u-fw-mon; English (First Day of Week Is Monday) +en-u-fw-sat; English (First Day of Week Is Saturday) +en-u-fw-sun; English (First Day of Week Is Sunday) +en-u-fw-thu; English (First Day of Week Is Thursday) +en-u-fw-tue; English (First Day of Week Is Tuesday) +en-u-fw-wed; English (First Day of Week Is Wednesday) +en-t-h0-hybrid; English +en-u-hc-h11; English (12 Hour System [0–11]) +en-u-hc-h12; English (12 Hour System [1–12]) +en-u-hc-h23; English (24 Hour System [0–23]) +en-u-hc-h24; English (24 Hour System [1–24]) +en-t-i0-handwrit; English (Handwriting Input Method) +en-t-i0-pinyin; English (Pinyin Input Method) +en-t-i0-und; English (Unspecified Input Method) +en-t-i0-wubi; English (Wubi Input Method) +en-t-k0-101key; English (101-Key Keyboard) +en-t-k0-102key; English (102-Key Keyboard) +en-t-k0-600dpi; English (600 dpi Keyboard) +en-t-k0-768dpi; English (768 dpi Keyboard) +en-t-k0-android; English (Android Keyboard) +en-t-k0-azerty; English (AZERTY-Based Keyboard) +en-t-k0-chromeos; English (ChromeOS Keyboard) +en-t-k0-colemak; English (Colemak Keyboard) +en-t-k0-dvorak; English (Dvorak Keyboard) +en-t-k0-dvorakl; English (Dvorak Left-Handed Keyboard) +en-t-k0-dvorakr; English (Dvorak Right-Handed Keyboard) +en-t-k0-el220; English (Greek 220 Keyboard) +en-t-k0-el319; English (Greek 319 Keyboard) +en-t-k0-extended; English (Keyboard With Many Extra Characters) +en-t-k0-googlevk; English (Google Virtual Keyboard) +en-t-k0-isiri; English (Persian ISIRI Keyboard) +en-t-k0-legacy; English (Legacy Keyboard) +en-t-k0-lt1205; English (Lithuanian LST 1205 Keyboard) +en-t-k0-lt1582; English (Lithuanian LST 1582 Keyboard) +en-t-k0-nutaaq; English (Inuktitut Nutaaq Keyboard) +en-t-k0-osx; English (macOS Keyboard) +en-t-k0-patta; English (Thai Pattachote Keyboard) +en-t-k0-qwerty; English (QWERTY-Based Keyboard) +en-t-k0-qwertz; English (QWERTZ-Based Keyboard) +en-t-k0-ta99; English (Tamil 99 Keyboard) +en-t-k0-und; English (Unspecified Keyboard) +en-t-k0-var; English (Keyboard Variant) +en-t-k0-viqr; English (Vietnamese VIQR Keyboard) +en-t-k0-windows; English (Windows Keyboard) +en-u-ka-noignore; English (Sort Symbols) +en-u-ka-shifted; English (Sort Ignoring Symbols) +en-u-kb-false; English (Sort Accents Normally) +en-u-kb-true; English (Sort Accents Reversed) +en-u-kc-false; English (Sort Case Insensitive) +en-u-kc-true; English (Sort Case Sensitive) +en-u-kf-false; English (Sort Normal Case Order) +en-u-kf-lower; English (Sort Lowercase First) +en-u-kf-upper; English (Sort Uppercase First) +en-u-kk-false; English (Sort Without Normalization) +en-u-kk-true; English (Sort Unicode Normalized) +en-u-kn-false; English (Sort Digits Individually) +en-u-kn-true; English (Sort Digits Numerically) +en-u-kr-arab; English (Script/Block Reordering: Arabic) +en-u-kr-digit-deva-latn; English (Script/Block Reordering: Digits, Devanagari, Latin) +en-u-kr-currency; English (Currency) +en-u-kr-digit; English (Digits) +en-u-kr-punct; English (Punctuation) +en-u-kr-space; English (Whitespace) +en-u-kr-symbol; English (Symbol) +en-u-ks-identic; English (Sort All) +en-u-ks-level1; English (Sort Base Letters Only) +en-u-ks-level2; English (Sort Accents) +en-u-ks-level3; English (Sort Accents/Case/Width) +en-u-ks-level4; English (Sort Accents/Case/Width/Kana) +en-u-kv-currency; English (Ignore Symbols affects spaces, punctuation, all symbols) +en-u-kv-punct; English (Ignore Symbols affects spaces and punctuation only) +en-u-kv-space; English (Ignore Symbols affects spaces only) +en-u-kv-symbol; English (Ignore Symbols affects spaces, punctuation, non-currency symbols) +en-u-lb-loose; English (Loose Line Break Style) +en-u-lb-normal; English (Normal Line Break Style) +en-u-lb-strict; English (Strict Line Break Style) +en-u-lw-breakall; English (Allow Line Breaks In All Words) +en-u-lw-keepall; English (Prevent Line Breaks In All Words) +en-u-lw-normal; English (Normal Line Breaks For Words) +en-u-lw-phrase; English (Prevent Line Breaks In Phrases) +en-t-m0-aethiopi; English (Encylopedia Aethiopica Transliteration) +en-t-m0-alaloc; English (US ALA-LOC Transliteration) +en-t-m0-betamets; English (Beta Maṣāḥǝft Transliteration) +en-t-m0-bgn; English (US BGN Transliteration) +en-t-m0-buckwalt; English (Buckwalter Arabic Transliteration) +en-t-m0-c11; English (Hex transform using C11 syntax) +en-t-m0-css; English (Hex transform using CSS syntax) +en-t-m0-din; English (German DIN Transliteration) +en-t-m0-es3842; English (Ethiopian Standards Agency ES 3842:2014 Ethiopic-Latin Transliteration) +en-t-m0-ewts; English (Extended Wylie Transliteration Scheme) +en-t-m0-gost; English (CIS GOST Transliteration) +en-t-m0-gurage; English (Gurage Legacy to Modern Transliteration) +en-t-m0-gutgarts; English (Yaros Gutgarts Ethiopic-Cyrillic Transliteration) +en-t-m0-iast; English (International Alphabet of Sanskrit Transliteration) +en-t-m0-iesjes; English (IES/JES Amharic Transliteration) +en-t-m0-iso; English (ISO Transliteration) +en-t-m0-java; English (Hex transform using Java syntax) +en-t-m0-lambdin; English (Thomas Oden Lambdin Ethiopic-Latin Transliteration) +en-t-m0-mcst; English (Korean MCST Transliteration) +en-t-m0-mns; English (Mongolian National Standard Transliteration) +en-t-m0-percent; English (Hex transform using percent syntax) +en-t-m0-perl; English (Hex transform using Perl syntax) +en-t-m0-plain; English (Hex transform with no surrounding syntax) +en-t-m0-prprname; English (Personal name transliteration variant) +en-t-m0-satts; English (Standard Arabic Technical Transliteration) +en-t-m0-sera; English (System for Ethiopic Representation in ASCII) +en-t-m0-tekieali; English (Tekie Alibekit Blin-Latin Transliteration) +en-t-m0-ungegn; English (UN GEGN Transliteration) +en-t-m0-unicode; English (Hex transform using Unicode syntax) +en-t-m0-xaleget; English (Eritrean Ministry of Education Blin-Latin Transliteration) +en-t-m0-xml; English (Hex transform using XML syntax) +en-t-m0-xml10; English (Hex transform using XML decimal syntax) +en-u-ms-metric; English (Metric System) +en-u-ms-uksystem; English (Imperial Measurement System) +en-u-ms-ussystem; English (US Measurement System) +en-u-mu-celsius; English (Celsius) +en-u-mu-fahrenhe; English (Fahrenheit) +en-u-mu-kelvin; English (Kelvin) +en-u-nu-adlm; English (Adlam Digits) +en-u-nu-ahom; English (Ahom Digits) +en-u-nu-arab; English (Arabic-Indic Digits) +en-u-nu-arabext; English (Extended Arabic-Indic Digits) +en-u-nu-armn; English (Armenian Numerals) +en-u-nu-armnlow; English (Armenian Lowercase Numerals) +en-u-nu-bali; English (Balinese Digits) +en-u-nu-beng; English (Bangla Digits) +en-u-nu-bhks; English (Bhaiksuki Digits) +en-u-nu-brah; English (Brahmi Digits) +en-u-nu-cakm; English (Chakma Digits) +en-u-nu-cham; English (Cham Digits) +en-u-nu-cyrl; English (Cyrillic Numerals) +en-u-nu-deva; English (Devanagari Digits) +en-u-nu-diak; English (Dives Akuru Digits) +en-u-nu-ethi; English (Ethiopic Numerals) +en-u-nu-finance; English (Financial Numerals) +en-u-nu-fullwide; English (Full-Width Digits) +en-u-nu-geor; English (Georgian Numerals) +en-u-nu-gong; English (Gunjala Gondi digits) +en-u-nu-gonm; English (Masaram Gondi digits) +en-u-nu-grek; English (Greek Numerals) +en-u-nu-greklow; English (Greek Lowercase Numerals) +en-u-nu-gujr; English (Gujarati Digits) +en-u-nu-guru; English (Gurmukhi Digits) +en-u-nu-hanidays; English (Chinese Calendar Day-of-Month Numerals) +en-u-nu-hanidec; English (Chinese Decimal Numerals) +en-u-nu-hans; English (Simplified Chinese Numerals) +en-u-nu-hansfin; English (Simplified Chinese Financial Numerals) +en-u-nu-hant; English (Traditional Chinese Numerals) +en-u-nu-hantfin; English (Traditional Chinese Financial Numerals) +en-u-nu-hebr; English (Hebrew Numerals) +en-u-nu-hmng; English (Pahawh Hmong Digits) +en-u-nu-hmnp; English (Nyiakeng Puachue Hmong Digits) +en-u-nu-java; English (Javanese Digits) +en-u-nu-jpan; English (Japanese Numerals) +en-u-nu-jpanfin; English (Japanese Financial Numerals) +en-u-nu-jpanyear; English (Japanese Calendar Gannen Year Numerals) +en-u-nu-kali; English (Kayah Li Digits) +en-u-nu-kawi; English (Kawi Digits) +en-u-nu-khmr; English (Khmer Digits) +en-u-nu-knda; English (Kannada Digits) +en-u-nu-lana; English (Tai Tham Hora Digits) +en-u-nu-lanatham; English (Tai Tham Tham Digits) +en-u-nu-laoo; English (Lao Digits) +en-u-nu-latn; English (Western Digits) +en-u-nu-lepc; English (Lepcha Digits) +en-u-nu-limb; English (Limbu Digits) +en-u-nu-mathbold; English (Mathematical Bold Digits) +en-u-nu-mathdbl; English (Mathematical Double-Struck Digits) +en-u-nu-mathmono; English (Mathematical Monospace Digits) +en-u-nu-mathsanb; English (Mathematical Sans-Serif Bold Digits) +en-u-nu-mathsans; English (Mathematical Sans-Serif Digits) +en-u-nu-mlym; English (Malayalam Digits) +en-u-nu-modi; English (Modi Digits) +en-u-nu-mong; English (Mongolian Digits) +en-u-nu-mroo; English (Mro Digits) +en-u-nu-mtei; English (Meetei Mayek Digits) +en-u-nu-mymr; English (Myanmar Digits) +en-u-nu-mymrshan; English (Myanmar Shan Digits) +en-u-nu-mymrtlng; English (Myanmar Tai Laing Digits) +en-u-nu-nagm; English (Nag Mundari Digits) +en-u-nu-native; English (Native Digits) +en-u-nu-newa; English (Newa Digits) +en-u-nu-nkoo; English (N’Ko Digits) +en-u-nu-olck; English (Ol Chiki Digits) +en-u-nu-orya; English (Odia Digits) +en-u-nu-osma; English (Osmanya Digits) +en-u-nu-rohg; English (Hanifi Rohingya digits) +en-u-nu-roman; English (Roman Numerals) +en-u-nu-romanlow; English (Roman Lowercase Numerals) +en-u-nu-saur; English (Saurashtra Digits) +en-u-nu-segment; English (Segmented Digits) +en-u-nu-shrd; English (Sharada Digits) +en-u-nu-sind; English (Khudawadi Digits) +en-u-nu-sinh; English (Sinhala Lith Digits) +en-u-nu-sora; English (Sora Sompeng Digits) +en-u-nu-sund; English (Sundanese Digits) +en-u-nu-takr; English (Takri Digits) +en-u-nu-talu; English (New Tai Lue Digits) +en-u-nu-taml; English (Traditional Tamil Numerals) +en-u-nu-tamldec; English (Tamil Digits) +en-u-nu-telu; English (Telugu Digits) +en-u-nu-thai; English (Thai Digits) +en-u-nu-tibt; English (Tibetan Digits) +en-u-nu-tirh; English (Tirhuta Digits) +en-u-nu-tnsa; English (Tangsa Digits) +en-u-nu-traditio; English (Traditional Numerals) +en-u-nu-vaii; English (Vai Digits) +en-u-nu-wara; English (Warang Citi Digits) +en-u-nu-wcho; English (Wancho Digits) +en-u-rg-gbsct; English (Region For Supplemental Data: Scotland) +en-u-rg-gbeng; English (Region For Supplemental Data: England) +en-t-s0-accents; English (From Accented Characters To ASCII Sequence) +en-t-s0-ascii; English (From ASCII) +en-t-s0-hex; English (From Hexadecimal Codes) +en-t-s0-morse; English (From Morse Code) +en-t-s0-npinyin; English (From Pinyin With Numeric Tones) +en-t-s0-publish; English (From Publishing Punctuation To ASCII) +en-t-s0-zawgyi; English (From Zawgyi Myanmar Encoding) +en-u-sd-gbsct; English (Region Subdivision: Scotland) +en-u-sd-gbwls; English (Region Subdivision: Wales) +en-u-ss-none; English (Sentence Breaks Without Abbreviation Handling) +en-u-ss-standard; English (Suppress Sentence Breaks After Standard Abbreviations) +en-t-t0-und; English (Unspecified Machine Translation) +en-u-tz-uslax; English (Time Zone: Los Angeles Time) +en-u-tz-gblon; English (Time Zone: United Kingdom Time) +en-u-tz-chzrh; English (Time Zone: Switzerland Time) +en-u-va-posix; English (POSIX Compliant Locale) +en-t-x0-foobar2; English (Private-Use Transform: foobar2) + + +@locale=af +@languageDisplay=standard + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latyn, België) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=af +@languageDisplay=dialect + +en-MM; Engels (Mianmar [Birma]) +es; Spaans +es-419; Spaans (Latyns-Amerika) +es-Cyrl-MX; Spaans (Sirillies, Meksiko) +hi-Latn; Hindi (Latyn) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latyn) +zh-Hans-fonipa; Chinees (Vereenvoudig, FONIPA) + + +@locale=am +@languageDisplay=standard + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓኒሽ +es-419; ስፓኒሽ (ላቲን አሜሪካ) +es-Cyrl-MX; ስፓኒሽ (ሲይሪልክ፣ሜክሲኮ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ደች (ቤልጄም) +nl-Latn-BE; ደች (ላቲን፣ቤልጄም) +zh-Hans-fonipa; ቻይንኛ (ቀለል ያለ፣FONIPA) + + +@locale=am +@languageDisplay=dialect + +en-MM; እንግሊዝኛ (ማይናማር[በርማ]) +es; ስፓኒሽ +es-419; የላቲን አሜሪካ ስፓኒሽ +es-Cyrl-MX; የሜክሲኮ ስፓኒሽ (ሲይሪልክ) +hi-Latn; ሒንዱኛ (ላቲን) +nl-BE; ፍሌሚሽ +nl-Latn-BE; ፍሌሚሽ (ላቲን) +zh-Hans-fonipa; ቀለል ያለ ቻይንኛ (FONIPA) + + +@locale=ar +@languageDisplay=standard + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية (أمريكا اللاتينية) +es-Cyrl-MX; الإسبانية (السيريلية، المكسيك) +hi-Latn; الهندية (اللاتينية) +nl-BE; الهولندية (بلجيكا) +nl-Latn-BE; الهولندية (اللاتينية، بلجيكا) +zh-Hans-fonipa; الصينية (المبسطة، FONIPA) + + +@locale=ar +@languageDisplay=dialect + +en-MM; الإنجليزية (ميانمار [بورما]) +es; الإسبانية +es-419; الإسبانية أمريكا اللاتينية +es-Cyrl-MX; الإسبانية المكسيكية (السيريلية) +hi-Latn; الهندية (اللاتينية) +nl-BE; الفلمنكية +nl-Latn-BE; الفلمنكية (اللاتينية) +zh-Hans-fonipa; الصينية المبسطة (FONIPA) + + +@locale=as +@languageDisplay=standard + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; স্পেনিচ (লেটিন আমেৰিকা) +es-Cyrl-MX; স্পেনিচ (চিৰিলিক, মেক্সিকো) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ডাচ (বেলজিয়াম) +nl-Latn-BE; ডাচ (লেটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সৰলীকৃত, FONIPA) + + +@locale=as +@languageDisplay=dialect + +en-MM; ইংৰাজী (ম্যানমাৰ [বাৰ্মা]) +es; স্পেনিচ +es-419; লেটিন আমেৰিকান স্পেনিচ +es-Cyrl-MX; মেক্সিকান স্পেনিচ (চিৰিলিক) +hi-Latn; হিন্দী (লেটিন) +nl-BE; ফ্লেমিচ +nl-Latn-BE; ফ্লেমিচ (লেটিন) +zh-Hans-fonipa; সৰলীকৃত চীনা (FONIPA) + + +@locale=az +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=az_Latn +@languageDisplay=standard + +en-MM; ingilis (Myanma) +es; ispan +es-419; ispan (Latın Amerikası) +es-Cyrl-MX; ispan (kiril, Meksika) +hi-Latn; hind (latın) +nl-BE; holland (Belçika) +nl-Latn-BE; holland (latın, Belçika) +zh-Hans-fonipa; çin (sadələşmiş, FONIPA) + + +@locale=az_Latn +@languageDisplay=dialect + +en-MM; ingilis (Myanma) +es; ispan +es-419; Latın Amerikası ispancası +es-Cyrl-MX; Meksika ispancası (kiril) +hi-Latn; Hindi [latın] +nl-BE; flamand +nl-Latn-BE; flamand (latın) +zh-Hans-fonipa; sadələşmiş çin (FONIPA) + + +@locale=be +@languageDisplay=standard + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; іспанская (Лацінская Амерыка) +es-Cyrl-MX; іспанская (кірыліца, Мексіка) +hi-Latn; хіндзі (лацініца) +nl-BE; нідэрландская (Бельгія) +nl-Latn-BE; нідэрландская (лацініца, Бельгія) +zh-Hans-fonipa; кітайская (спрошчанае кітайскае, FONIPA) + + +@locale=be +@languageDisplay=dialect + +en-MM; англійская (М’янма [Бірма]) +es; іспанская +es-419; лацінаамерыканская іспанская +es-Cyrl-MX; мексіканская іспанская (кірыліца) +hi-Latn; хіндзі (лацініца) +nl-BE; фламандская +nl-Latn-BE; фламандская (лацініца) +zh-Hans-fonipa; кітайская [спрошчаныя іерогліфы] (FONIPA) + + +@locale=bg +@languageDisplay=standard + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; нидерландски (Белгия) +nl-Latn-BE; нидерландски (латиница, Белгия) +zh-Hans-fonipa; китайски (опростена, Международна фонетична азбука) + + +@locale=bg +@languageDisplay=dialect + +en-MM; английски (Мианмар [Бирма]) +es; испански +es-419; испански (Латинска Америка) +es-Cyrl-MX; испански (кирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламандски +nl-Latn-BE; фламандски (латиница) +zh-Hans-fonipa; китайски [опростен] (Международна фонетична азбука) + + +@locale=bn +@languageDisplay=standard + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ওলন্দাজ (বেলজিয়াম) +nl-Latn-BE; ওলন্দাজ (ল্যাটিন, বেলজিয়াম) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bn +@languageDisplay=dialect + +en-MM; ইংরেজি (মায়ানমার [বার্মা]) +es; স্প্যানিশ +es-419; স্প্যানিশ (লাতিন আমেরিকা) +es-Cyrl-MX; স্প্যানিশ (সিরিলিক, মেক্সিকো) +hi-Latn; হিন্দি (ল্যাটিন) +nl-BE; ফ্লেমিশ +nl-Latn-BE; ফ্লেমিশ (ল্যাটিন) +zh-Hans-fonipa; চীনা (সরলীকৃত, FONIPA) + + +@locale=bs +@languageDisplay=standard + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs +@languageDisplay=dialect + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=standard + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno, IPA fonetika) + + +@locale=bs_Latn +@languageDisplay=dialect + +en-MM; engleski (Mijanmar) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=ca +@languageDisplay=standard + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol (Amèrica Llatina) +es-Cyrl-MX; espanyol (ciríl·lic, Mèxic) +hi-Latn; hindi (llatí) +nl-BE; neerlandès (Bèlgica) +nl-Latn-BE; neerlandès (llatí, Bèlgica) +zh-Hans-fonipa; xinès (simplificat, alfabet fonètic internacional) + + +@locale=ca +@languageDisplay=dialect + +en-MM; anglès (Myanmar [Birmània]) +es; espanyol +es-419; espanyol llatinoamericà +es-Cyrl-MX; espanyol de Mèxic (ciríl·lic) +hi-Latn; hindi (llatí) +nl-BE; flamenc +nl-Latn-BE; flamenc (llatí) +zh-Hans-fonipa; xinès simplificat (alfabet fonètic internacional) + + +@locale=chr +@languageDisplay=standard + +en-MM; ᎩᎵᏏ (ᎹᏯᎹᎵ [ᏇᎵᎹ]) +es; ᏍᏆᏂ +es-419; ᏍᏆᏂ (ᎳᏘᏂ ᎠᎹᏰᏟ) +es-Cyrl-MX; ᏍᏆᏂ (ᏲᏂᎢ ᏗᎪᏪᎵ, ᎠᏂᏍᏆᏂ) +hi-Latn; ᎯᏂᏗ (ᎳᏘᏂ) +nl-BE; ᏛᏥ (ᏇᎵᏥᎥᎻ) +nl-Latn-BE; ᏛᏥ (ᎳᏘᏂ, ᏇᎵᏥᎥᎻ) +zh-Hans-fonipa; ᏓᎶᏂᎨ (ᎠᎯᏗᎨ, FONIPA) + + +@locale=chr +@languageDisplay=dialect + +en-MM; ᎩᎵᏏ (ᎹᏯᎹᎵ [ᏇᎵᎹ]) +es; ᏍᏆᏂ +es-419; ᏔᏘᏂ ᎠᎹᏰᏟ ᏍᏆᏂ +es-Cyrl-MX; ᏍᏆᏂᏱ ᏍᏆᏂ (ᏲᏂᎢ ᏗᎪᏪᎵ) +hi-Latn; ᎯᏂᏗ (ᎳᏘᏂ) +nl-BE; ᏊᎵᏥᎥᎻ ᏛᏥ +nl-Latn-BE; ᏊᎵᏥᎥᎻ ᏛᏥ (ᎳᏘᏂ) +zh-Hans-fonipa; ᎠᎯᏗᎨ ᏓᎶᏂᎨ (FONIPA) + + +@locale=cs +@languageDisplay=standard + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština (Latinská Amerika) +es-Cyrl-MX; španělština (cyrilice, Mexiko) +hi-Latn; hindština (latinka) +nl-BE; nizozemština (Belgie) +nl-Latn-BE; nizozemština (latinka, Belgie) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=cs +@languageDisplay=dialect + +en-MM; angličtina (Myanmar [Barma]) +es; španělština +es-419; španělština (Latinská Amerika) +es-Cyrl-MX; španělština (cyrilice, Mexiko) +hi-Latn; hindština (latinka) +nl-BE; vlámština +nl-Latn-BE; vlámština (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=cy +@languageDisplay=standard + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg (America Ladin) +es-Cyrl-MX; Sbaeneg (Cyrilig, Mecsico) +hi-Latn; Hindi (Lladin) +nl-BE; Iseldireg (Gwlad Belg) +nl-Latn-BE; Iseldireg (Lladin, Gwlad Belg) +zh-Hans-fonipa; Tsieinëeg (Symledig, Seineg IPA) + + +@locale=cy +@languageDisplay=dialect + +en-MM; Saesneg (Myanmar [Burma]) +es; Sbaeneg +es-419; Sbaeneg America Ladin +es-Cyrl-MX; Sbaeneg Mecsico (Cyrilig) +hi-Latn; Hindi (Lladin) +nl-BE; Fflemeg +nl-Latn-BE; Fflemeg (Lladin) +zh-Hans-fonipa; Tsieinëeg Symledig (Seineg IPA) + + +@locale=da +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latinamerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgien) +nl-Latn-BE; nederlandsk (latinsk, Belgien) +zh-Hans-fonipa; kinesisk (forenklet, det internationale fonetiske alfabet) + + +@locale=da +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; latinamerikansk spansk +es-Cyrl-MX; mexicansk spansk (kyrillisk) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internationale fonetiske alfabet) + + +@locale=de +@languageDisplay=standard + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Niederländisch (Belgien) +nl-Latn-BE; Niederländisch (Lateinisch, Belgien) +zh-Hans-fonipa; Chinesisch (Vereinfacht, IPA Phonetisch) + + +@locale=de +@languageDisplay=dialect + +en-MM; Englisch (Myanmar) +es; Spanisch +es-419; Spanisch (Lateinamerika) +es-Cyrl-MX; Spanisch (Kyrillisch, Mexiko) +hi-Latn; Hindi (Lateinisch) +nl-BE; Flämisch +nl-Latn-BE; Flämisch (Lateinisch) +zh-Hans-fonipa; Chinesisch [vereinfacht] (IPA Phonetisch) + + +@locale=dsb +@languageDisplay=standard + +en-MM; engelšćina (Myanmar) +es; špańšćina +es-419; špańšćina (Łatyńska Amerika) +es-Cyrl-MX; špańšćina (kyriliski, Mexiko) +hi-Latn; hindišćina (łatyński) +nl-BE; nižozemšćina (Belgiska) +nl-Latn-BE; nižozemšćina (łatyński, Belgiska) +zh-Hans-fonipa; chinšćina (zjadnorjone, FONIPA) + + +@locale=dsb +@languageDisplay=dialect + +en-MM; engelšćina (Myanmar) +es; špańšćina +es-419; łatyńskoamerikańska špańšćina +es-Cyrl-MX; mexikańska špańšćina (kyriliski) +hi-Latn; hindišćina (łatyński) +nl-BE; flamšćina +nl-Latn-BE; flamšćina (łatyński) +zh-Hans-fonipa; chinšćina [zjadnorjona] (FONIPA) + + +@locale=el +@languageDisplay=standard + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά (Λατινική Αμερική) +es-Cyrl-MX; Ισπανικά (Κυριλλικό, Μεξικό) +hi-Latn; Χίντι (Λατινικό) +nl-BE; Ολλανδικά (Βέλγιο) +nl-Latn-BE; Ολλανδικά (Λατινικό, Βέλγιο) +zh-Hans-fonipa; Κινεζικά (Απλοποιημένο, Διεθνής φωνητική αλφάβητος) + + +@locale=el +@languageDisplay=dialect + +en-MM; Αγγλικά (Μιανμάρ [Βιρμανία]) +es; Ισπανικά +es-419; Ισπανικά Λατινικής Αμερικής +es-Cyrl-MX; Ισπανικά Μεξικού (Κυριλλικό) +hi-Latn; Χίντι (Λατινικό) +nl-BE; Φλαμανδικά +nl-Latn-BE; Φλαμανδικά (Λατινικό) +zh-Hans-fonipa; Απλοποιημένα Κινεζικά (Διεθνής φωνητική αλφάβητος) + + +@locale=en +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=en +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=es +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (Latinoamérica) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélgica) +nl-Latn-BE; neerlandés (latino, Bélgica) +zh-Hans-fonipa; chino (simplificado, Alfabeto fonético internacional IPA) + + +@locale=es +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español latinoamericano +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi (latino) +nl-BE; flamenco +nl-Latn-BE; flamenco (latino) +zh-Hans-fonipa; chino simplificado (Alfabeto fonético internacional IPA) + + +@locale=et +@languageDisplay=standard + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; hispaania (Ladina-Ameerika) +es-Cyrl-MX; hispaania (kirillitsa, Mehhiko) +hi-Latn; hindi (ladina) +nl-BE; hollandi (Belgia) +nl-Latn-BE; hollandi (ladina, Belgia) +zh-Hans-fonipa; hiina (lihtsustatud, IPA foneetika) + + +@locale=et +@languageDisplay=dialect + +en-MM; inglise (Myanmar [Birma]) +es; hispaania +es-419; Ladina-Ameerika hispaania +es-Cyrl-MX; Mehhiko hispaania (kirillitsa) +hi-Latn; hindi (ladina) +nl-BE; flaami +nl-Latn-BE; flaami (ladina) +zh-Hans-fonipa; lihtsustatud hiina (IPA foneetika) + + +@locale=eu +@languageDisplay=standard + +en-MM; ingelesa (Myanmar [Birmania]) +es; gaztelania +es-419; gaztelania (Latinoamerika) +es-Cyrl-MX; gaztelania (zirilikoa, Mexiko) +hi-Latn; hindia (latinoa) +nl-BE; nederlandera (Belgika) +nl-Latn-BE; nederlandera (latinoa, Belgika) +zh-Hans-fonipa; txinera (sinplifikatua, IPA ahoskera) + + +@locale=eu +@languageDisplay=dialect + +en-MM; ingelesa (Myanmar [Birmania]) +es; gaztelania +es-419; Latinoamerikako gaztelania +es-Cyrl-MX; Mexikoko gaztelania (zirilikoa) +hi-Latn; hindia [latindarra] +nl-BE; flandriera +nl-Latn-BE; flandriera (latinoa) +zh-Hans-fonipa; txinera sinplifikatua (IPA ahoskera) + + +@locale=fa +@languageDisplay=standard + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی (امریکای لاتین) +es-Cyrl-MX; اسپانیایی (سیریلی، مکزیک) +hi-Latn; هندی (لاتین) +nl-BE; هلندی (بلژیک) +nl-Latn-BE; هلندی (لاتین، بلژیک) +zh-Hans-fonipa; چینی (ساده‌شده، فونتیک IPA) + + +@locale=fa +@languageDisplay=dialect + +en-MM; انگلیسی (میانمار [برمه]) +es; اسپانیایی +es-419; اسپانیایی امریکای لاتین +es-Cyrl-MX; اسپانیایی مکزیک (سیریلی) +hi-Latn; هندی (لاتین) +nl-BE; فلمنگی +nl-Latn-BE; فلمنگی (لاتین) +zh-Hans-fonipa; چینی ساده‌شده (فونتیک IPA) + + +@locale=fi +@languageDisplay=standard + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; espanja (Latinalainen Amerikka) +es-Cyrl-MX; espanja (kyrillinen, Meksiko) +hi-Latn; hindi (latinalainen) +nl-BE; hollanti (Belgia) +nl-Latn-BE; hollanti (latinalainen, Belgia) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fi +@languageDisplay=dialect + +en-MM; englanti (Myanmar [Burma]) +es; espanja +es-419; amerikanespanja +es-Cyrl-MX; meksikonespanja (kyrillinen) +hi-Latn; hindi (latinalainen) +nl-BE; flaami +nl-Latn-BE; flaami (latinalainen) +zh-Hans-fonipa; kiina (yksinkertaistettu, kansainvälinen foneettinen aakkosto IPA) + + +@locale=fil +@languageDisplay=standard + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Pinasimple, FONIPA) + + +@locale=fil +@languageDisplay=dialect + +en-MM; Ingles (Myanmar [Burma]) +es; Spanish +es-419; Latin American na Espanyol +es-Cyrl-MX; Mexican na Espanyol (Cyrillic) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Pinasimpleng Chinese (FONIPA) + + +@locale=fr +@languageDisplay=standard + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol (Amérique latine) +es-Cyrl-MX; espagnol (cyrillique, Mexique) +hi-Latn; hindi (latin) +nl-BE; néerlandais (Belgique) +nl-Latn-BE; néerlandais (latin, Belgique) +zh-Hans-fonipa; chinois (simplifié, alphabet phonétique international) + + +@locale=fr +@languageDisplay=dialect + +en-MM; anglais (Myanmar [Birmanie]) +es; espagnol +es-419; espagnol d’Amérique latine +es-Cyrl-MX; espagnol du Mexique (cyrillique) +hi-Latn; hindi (latin) +nl-BE; flamand +nl-Latn-BE; flamand (latin) +zh-Hans-fonipa; chinois simplifié (alphabet phonétique international) + + +@locale=ga +@languageDisplay=standard + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis (Meiriceá Laidineach) +es-Cyrl-MX; Spáinnis (Coireallach, Meicsiceo) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Ollainnis (an Bheilg) +nl-Latn-BE; Ollainnis (Laidineach, an Bheilg) +zh-Hans-fonipa; Sínis (Simplithe, Fogharscríobh IPA) + + +@locale=ga +@languageDisplay=dialect + +en-MM; Béarla (Maenmar [Burma]) +es; Spáinnis +es-419; Spáinnis Mheiriceá Laidinigh +es-Cyrl-MX; Spáinnis Mheicsiceach (Coireallach) +hi-Latn; Hiondúis (Laidineach) +nl-BE; Pléimeannais +nl-Latn-BE; Pléimeannais (Laidineach) +zh-Hans-fonipa; Sínis Shimplithe (Fogharscríobh IPA) + + +@locale=gd +@languageDisplay=standard + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis (Aimeireaga Laidinneach) +es-Cyrl-MX; Spàinntis (Cirilis, Meagsago) +hi-Latn; Hindis (Laideann) +nl-BE; Duitsis (A’ Bheilg) +nl-Latn-BE; Duitsis (Laideann, A’ Bheilg) +zh-Hans-fonipa; Sìnis (Simplichte, Comharran fuaim-eòlais an IPA) + + +@locale=gd +@languageDisplay=dialect + +en-MM; Beurla (Miànmar) +es; Spàinntis +es-419; Spàinntis na h-Aimeireaga Laidinneach +es-Cyrl-MX; Spàinntis Mheagsagach (Cirilis) +hi-Latn; Hindis (Laideann) +nl-BE; Flànrais +nl-Latn-BE; Flànrais (Laideann) +zh-Hans-fonipa; Sìnis Shimplichte (Comharran fuaim-eòlais an IPA) + + +@locale=gl +@languageDisplay=standard + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español (América Latina) +es-Cyrl-MX; español (cirílico, México) +hi-Latn; hindi (latino) +nl-BE; neerlandés (Bélxica) +nl-Latn-BE; neerlandés (latino, Bélxica) +zh-Hans-fonipa; chinés (simplificado, FONIPA) + + +@locale=gl +@languageDisplay=dialect + +en-MM; inglés (Myanmar [Birmania]) +es; español +es-419; español de América +es-Cyrl-MX; español de México (cirílico) +hi-Latn; hindi [alfabeto latino] +nl-BE; flamengo +nl-Latn-BE; flamengo (latino) +zh-Hans-fonipa; chinés simplificado (FONIPA) + + +@locale=gu +@languageDisplay=standard + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; સ્પેનિશ (લેટિન અમેરિકા) +es-Cyrl-MX; સ્પેનિશ (સિરિલિક, મેક્સિકો) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ડચ (બેલ્જીયમ) +nl-Latn-BE; ડચ (લેટિન, બેલ્જીયમ) +zh-Hans-fonipa; ચાઇનીઝ (સરળીકૃત, FONIPA) + + +@locale=gu +@languageDisplay=dialect + +en-MM; અંગ્રેજી (મ્યાંમાર [બર્મા]) +es; સ્પેનિશ +es-419; લેટિન અમેરિકન સ્પેનિશ +es-Cyrl-MX; મેક્સિકન સ્પેનિશ (સિરિલિક) +hi-Latn; હિન્દી (લેટિન) +nl-BE; ફ્લેમિશ +nl-Latn-BE; ફ્લેમિશ (લેટિન) +zh-Hans-fonipa; સરળીકૃત ચાઇનીઝ (FONIPA) + + +@locale=ha +@languageDisplay=standard + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyanci (Latin Amurka) +es-Cyrl-MX; Sifaniyanci (Cyrillic, Mesiko) +hi-Latn; Harshen Hindi (Latin) +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Harshen Sinanci (Sauƙaƙaƙƙen, FONIPA) + + +@locale=ha +@languageDisplay=dialect + +en-MM; Turanci (Burma, Miyamar) +es; Sifaniyanci +es-419; Sifaniyancin Latin Amirka +es-Cyrl-MX; Sifaniyanci Mesiko (Cyrillic) +hi-Latn; Hindi [Latinanci] +nl-BE; Holanci (Belgiyom) +nl-Latn-BE; Holanci (Latin, Belgiyom) +zh-Hans-fonipa; Sauƙaƙaƙƙen Sinanci (FONIPA) + + +@locale=he +@languageDisplay=standard + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית (בלגיה) +nl-Latn-BE; הולנדית (לטיני, בלגיה) +zh-Hans-fonipa; סינית (פשוט, אלפבית פונטי בינלאומי) + + +@locale=he +@languageDisplay=dialect + +en-MM; אנגלית (מיאנמר [בורמה]) +es; ספרדית +es-419; ספרדית (אמריקה הלטינית) +es-Cyrl-MX; ספרדית (קירילי, מקסיקו) +hi-Latn; הינדי (לטיני) +nl-BE; הולנדית [פלמית] +nl-Latn-BE; הולנדית [פלמית] (לטיני) +zh-Hans-fonipa; סינית פשוטה (אלפבית פונטי בינלאומי) + + +@locale=hi +@languageDisplay=standard + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; स्पेनिश (लैटिन अमेरिका) +es-Cyrl-MX; स्पेनिश (सिरिलिक, मैक्सिको) +hi-Latn; हिन्दी (लैटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लैटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=hi +@languageDisplay=dialect + +en-MM; अंग्रेज़ी (म्यांमार [बर्मा]) +es; स्पेनिश +es-419; लैटिन अमेरिकी स्पेनिश +es-Cyrl-MX; मैक्सिकन स्पेनिश (सिरिलिक) +hi-Latn; हिन्दी (लैटिन) +nl-BE; फ़्लेमिश +nl-Latn-BE; फ़्लेमिश (लैटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=hi_Latn +@languageDisplay=standard + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Spanish (Latin America) +es-Cyrl-MX; Spanish (Cyrillic, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Dutch (Belgium) +nl-Latn-BE; Dutch (Latin, Belgium) +zh-Hans-fonipa; Chinese (Simplified, IPA Phonetics) + + +@locale=hi_Latn +@languageDisplay=dialect + +en-MM; English (Myanmar [Burma]) +es; Spanish +es-419; Latin American Spanish +es-Cyrl-MX; Mexican Spanish (Cyrillic) +hi-Latn; Hindi [Latin] +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Simplified Chinese (IPA Phonetics) + + +@locale=hr +@languageDisplay=standard + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; španjolski (Latinska Amerika) +es-Cyrl-MX; španjolski (ćirilica, Meksiko) +hi-Latn; hindski (latinica) +nl-BE; nizozemski (Belgija) +nl-Latn-BE; nizozemski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno pismo, IPA fonetika) + + +@locale=hr +@languageDisplay=dialect + +en-MM; engleski (Mjanmar [Burma]) +es; španjolski +es-419; latinoamerički španjolski +es-Cyrl-MX; meksički španjolski (ćirilica) +hi-Latn; hindski (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; kineski [pojednostavljeni] (IPA fonetika) + + +@locale=hsb +@languageDisplay=standard + +en-MM; jendźelšćina (Myanmar) +es; španišćina +es-419; španišćina (Łaćonska Amerika) +es-Cyrl-MX; španišćina (kyrilisce, Mexiko) +hi-Latn; hindišćina (łaćonsce) +nl-BE; nižozemšćina (Belgiska) +nl-Latn-BE; nižozemšćina (łaćonsce, Belgiska) +zh-Hans-fonipa; chinšćina (zjednorjene, FONIPA) + + +@locale=hsb +@languageDisplay=dialect + +en-MM; jendźelšćina (Myanmar) +es; španišćina +es-419; łaćonskoameriska španišćina +es-Cyrl-MX; mexiska španišćina (kyrilisce) +hi-Latn; hindišćina (łaćonsce) +nl-BE; flamšćina +nl-Latn-BE; flamšćina (łaćonsce) +zh-Hans-fonipa; chinšćina [zjednorjena] (FONIPA) + + +@locale=hu +@languageDisplay=standard + +en-MM; angol (Mianmar) +es; spanyol +es-419; spanyol (Latin-Amerika) +es-Cyrl-MX; spanyol (Cirill, Mexikó) +hi-Latn; hindi (Latin) +nl-BE; holland (Belgium) +nl-Latn-BE; holland (Latin, Belgium) +zh-Hans-fonipa; kínai (Egyszerűsített, IPA fonetika) + + +@locale=hu +@languageDisplay=dialect + +en-MM; angol (Mianmar) +es; spanyol +es-419; latin-amerikai spanyol +es-Cyrl-MX; spanyol [mexikói] (Cirill) +hi-Latn; hindi [latin] +nl-BE; flamand +nl-Latn-BE; flamand (Latin) +zh-Hans-fonipa; egyszerűsített kínai (IPA fonetika) + + +@locale=hy +@languageDisplay=standard + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; իսպաներեն (Լատինական Ամերիկա) +es-Cyrl-MX; իսպաներեն (կյուրեղագիր, Մեքսիկա) +hi-Latn; հինդի (լատինական) +nl-BE; հոլանդերեն (Բելգիա) +nl-Latn-BE; հոլանդերեն (լատինական, Բելգիա) +zh-Hans-fonipa; չինարեն (պարզեցված, FONIPA) + + +@locale=hy +@languageDisplay=dialect + +en-MM; անգլերեն (Մյանմա [Բիրմա]) +es; իսպաներեն +es-419; լատինամերիկյան իսպաներեն +es-Cyrl-MX; մեքսիկական իսպաներեն (կյուրեղագիր) +hi-Latn; հինդի (լատինական) +nl-BE; ֆլամանդերեն +nl-Latn-BE; ֆլամանդերեն (լատինական) +zh-Hans-fonipa; պարզեցված չինարեն (FONIPA) + + +@locale=id +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=id +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amerika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Meksiko) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgia) +nl-Latn-BE; Belanda (Latin, Belgia) +zh-Hans-fonipa; Tionghoa (Sederhana, Fonetik IPA) + + +@locale=ig +@languageDisplay=standard + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi (Latin America) +es-Cyrl-MX; Spanishi (Mkpụrụ Okwu Cyrillic, Mexico) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị (Belgium) +nl-Latn-BE; Dọchị (Latin, Belgium) +zh-Hans-fonipa; Chainisi (Nke dị mfe, FONIPA) + + +@locale=ig +@languageDisplay=dialect + +en-MM; Bekee (Myanmar [Burma]) +es; Spanishi +es-419; Spanishi ndị Latin America +es-Cyrl-MX; Spanishi ndị Mexico (Mkpụrụ Okwu Cyrillic) +hi-Latn; Hindị (Latin) +nl-BE; Dọchị (Belgium) +nl-Latn-BE; Dọchị (Latin, Belgium) +zh-Hans-fonipa; Asụsụ Chinese dị mfe (FONIPA) + + +@locale=is +@languageDisplay=standard + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; spænska (Rómanska Ameríka) +es-Cyrl-MX; spænska (kyrillískt, Mexíkó) +hi-Latn; hindí (latneskt) +nl-BE; hollenska (Belgía) +nl-Latn-BE; hollenska (latneskt, Belgía) +zh-Hans-fonipa; kínverska (einfaldað, FONIPA) + + +@locale=is +@languageDisplay=dialect + +en-MM; enska (Mjanmar [Búrma]) +es; spænska +es-419; rómönsk-amerísk spænska +es-Cyrl-MX; mexíkósk spænska (kyrillískt) +hi-Latn; hindí (latneskt) +nl-BE; flæmska +nl-Latn-BE; flæmska (latneskt) +zh-Hans-fonipa; kínverska [einfölduð] (FONIPA) + + +@locale=it +@languageDisplay=standard + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo (America Latina) +es-Cyrl-MX; spagnolo (cirillico, Messico) +hi-Latn; hindi (latino) +nl-BE; olandese (Belgio) +nl-Latn-BE; olandese (latino, Belgio) +zh-Hans-fonipa; cinese (semplificato, alfabeto fonetico internazionale IPA) + + +@locale=it +@languageDisplay=dialect + +en-MM; inglese (Myanmar [Birmania]) +es; spagnolo +es-419; spagnolo latinoamericano +es-Cyrl-MX; spagnolo messicano (cirillico) +hi-Latn; hindi (latino) +nl-BE; fiammingo +nl-Latn-BE; fiammingo (latino) +zh-Hans-fonipa; cinese semplificato (alfabeto fonetico internazionale IPA) + + +@locale=ja +@languageDisplay=standard + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 (ラテン文字) +nl-BE; オランダ語 (ベルギー) +nl-Latn-BE; オランダ語 (ラテン文字、ベルギー) +zh-Hans-fonipa; 中国語 (簡体字、国際音声記号) + + +@locale=ja +@languageDisplay=dialect + +en-MM; 英語 (ミャンマー [ビルマ]) +es; スペイン語 +es-419; スペイン語 (ラテンアメリカ) +es-Cyrl-MX; スペイン語 (キリル文字、メキシコ) +hi-Latn; ヒンディー語 (ラテン文字) +nl-BE; フラマン語 +nl-Latn-BE; フラマン語 (ラテン文字) +zh-Hans-fonipa; 簡体中国語 (国際音声記号) + + +@locale=jv +@languageDisplay=standard + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol (Amérika Latin) +es-Cyrl-MX; Spanyol (Sirilik, Mèksiko) +hi-Latn; India (Latin) +nl-BE; Walanda (Bèlgi) +nl-Latn-BE; Walanda (Latin, Bèlgi) +zh-Hans-fonipa; Tyonghwa (Prasaja, FONIPA) + + +@locale=jv +@languageDisplay=dialect + +en-MM; Inggris (Myanmar [Burma]) +es; Spanyol +es-419; Spanyol [Amerika Latin] +es-Cyrl-MX; Spanyol [Meksiko] (Sirilik) +hi-Latn; India (Latin) +nl-BE; Flemis +nl-Latn-BE; Flemis (Latin) +zh-Hans-fonipa; Tyonghwa [Ringkes] (FONIPA) + + +@locale=ka +@languageDisplay=standard + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ესპანური (ლათინური ამერიკა) +es-Cyrl-MX; ესპანური (კირილიცა, მექსიკა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ნიდერლანდური (ბელგია) +nl-Latn-BE; ნიდერლანდური (ლათინური, ბელგია) +zh-Hans-fonipa; ჩინური (გამარტივებული, FONIPA) + + +@locale=ka +@languageDisplay=dialect + +en-MM; ინგლისური (მიანმარი [ბირმა]) +es; ესპანური +es-419; ლათინურ ამერიკული ესპანური +es-Cyrl-MX; მექსიკური ესპანური (კირილიცა) +hi-Latn; ჰინდი (ლათინური) +nl-BE; ფლამანდიური +nl-Latn-BE; ფლამანდიური (ლათინური) +zh-Hans-fonipa; გამარტივებული ჩინური (FONIPA) + + +@locale=kk +@languageDisplay=standard + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; хинди тілі (латын жазуы) +nl-BE; нидерланд тілі (Бельгия) +nl-Latn-BE; нидерланд тілі (латын жазуы, Бельгия) +zh-Hans-fonipa; қытай тілі (жеңілдетілген жазу, Халықаралық фонетикалық әліпби) + + +@locale=kk +@languageDisplay=dialect + +en-MM; ағылшын тілі (Мьянма [Бирма]) +es; испан тілі +es-419; испан тілі (Латын Америкасы) +es-Cyrl-MX; испан тілі (кирилл жазуы, Мексика) +hi-Latn; хинди тілі (латын жазуы) +nl-BE; фламанд тілі +nl-Latn-BE; фламанд тілі (латын жазуы) +zh-Hans-fonipa; жеңілдетілген қытай тілі (Халықаралық фонетикалық әліпби) + + +@locale=km +@languageDisplay=standard + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ហូឡង់ (បែលហ្ស៊ិក) +nl-Latn-BE; ហូឡង់ (ឡាតាំង, បែលហ្ស៊ិក) +zh-Hans-fonipa; ចិន (អក្សរ​ចិន​កាត់, FONIPA) + + +@locale=km +@languageDisplay=dialect + +en-MM; អង់គ្លេស (មីយ៉ាន់ម៉ា [ភូមា]) +es; អេស្ប៉ាញ +es-419; អេស្ប៉ាញ (អាមេរិក​ឡាទីន) +es-Cyrl-MX; អេស្ប៉ាញ (ស៊ីរីលីក, ម៉ិកស៊ិក) +hi-Latn; ហិណ្ឌី (ឡាតាំង) +nl-BE; ផ្លាមីស +nl-Latn-BE; ផ្លាមីស (ឡាតាំង) +zh-Hans-fonipa; ចិន​អក្សរ​កាត់ (FONIPA) + + +@locale=kn +@languageDisplay=standard + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಸ್ಪ್ಯಾನಿಷ್ (ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕಾ) +es-Cyrl-MX; ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್, ಮೆಕ್ಸಿಕೊ) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಡಚ್ (ಬೆಲ್ಜಿಯಮ್) +nl-Latn-BE; ಡಚ್ (ಲ್ಯಾಟಿನ್, ಬೆಲ್ಜಿಯಮ್) +zh-Hans-fonipa; ಚೈನೀಸ್ (ಸರಳೀಕೃತ, FONIPA) + + +@locale=kn +@languageDisplay=dialect + +en-MM; ಇಂಗ್ಲಿಷ್ (ಮಯನ್ಮಾರ್ [ಬರ್ಮಾ]) +es; ಸ್ಪ್ಯಾನಿಷ್ +es-419; ಲ್ಯಾಟಿನ್ ಅಮೇರಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ +es-Cyrl-MX; ಮೆಕ್ಸಿಕನ್ ಸ್ಪ್ಯಾನಿಷ್ (ಸಿರಿಲಿಕ್) +hi-Latn; ಹಿಂದಿ (ಲ್ಯಾಟಿನ್) +nl-BE; ಫ್ಲೆಮಿಷ್ +nl-Latn-BE; ಫ್ಲೆಮಿಷ್ (ಲ್ಯಾಟಿನ್) +zh-Hans-fonipa; ಸರಳೀಕೃತ ಚೈನೀಸ್ (FONIPA) + + +@locale=ko +@languageDisplay=standard + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 네덜란드어(벨기에) +nl-Latn-BE; 네덜란드어(로마자, 벨기에) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=ko +@languageDisplay=dialect + +en-MM; 영어(미얀마) +es; 스페인어 +es-419; 스페인어(라틴 아메리카) +es-Cyrl-MX; 스페인어(키릴 문자, 멕시코) +hi-Latn; 힌디어(로마자) +nl-BE; 플라망어 +nl-Latn-BE; 플라망어(로마자) +zh-Hans-fonipa; 중국어(간체, FONIPA) + + +@locale=kok +@languageDisplay=standard + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; स्पॅनीश (लॅटीन अमेरिका) +es-Cyrl-MX; स्पॅनीश (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटीन, बेल्जियम) +zh-Hans-fonipa; चिनी (सोंपी, FONIPA) + + +@locale=kok +@languageDisplay=dialect + +en-MM; इंग्लीश (म्यानमार [बर्मा]) +es; स्पॅनीश +es-419; लातीं अमेरिकन स्पॅनीश +es-Cyrl-MX; मॅक्सिकन स्पॅनीश (सिरिलिक) +hi-Latn; हिन्दी (लॅटीन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटीन) +zh-Hans-fonipa; सोंपी चिनी (FONIPA) + + +@locale=ky +@languageDisplay=standard + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; голландча (Бельгия) +nl-Latn-BE; голландча (Латын, Бельгия) +zh-Hans-fonipa; кытайча (Жөнөкөйлөштүрүлгөн, FONIPA) + + +@locale=ky +@languageDisplay=dialect + +en-MM; англисче (Мьянма [Бирма]) +es; испанча +es-419; испанча (Латын Америкасы) +es-Cyrl-MX; испанча (Кирилл, Мексика) +hi-Latn; хиндиче (Латын) +nl-BE; фламандча +nl-Latn-BE; фламандча (Латын) +zh-Hans-fonipa; кытайча [жөнөкөйлөштүрүлгөн] (FONIPA) + + +@locale=lo +@languageDisplay=standard + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ສະແປນນິຊ (ລາຕິນ ອາເມລິກາ) +es-Cyrl-MX; ສະແປນນິຊ (ຊີຣິວລິກ, ເມັກຊິໂກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ດັຊ (ເບວຢຽມ) +nl-Latn-BE; ດັຊ (ລາຕິນ, ເບວຢຽມ) +zh-Hans-fonipa; ຈີນ (ແບບຮຽບງ່າຍ, ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lo +@languageDisplay=dialect + +en-MM; ອັງກິດ (ມຽນມາ [ເບີມາ]) +es; ສະແປນນິຊ +es-419; ລາຕິນ ອາເມຣິກັນ ສະແປນນິຊ +es-Cyrl-MX; ເມັກຊິກັນ ສະແປນນິຊ (ຊີຣິວລິກ) +hi-Latn; ຮິນດິ (ລາຕິນ) +nl-BE; ຟລີມິຊ +nl-Latn-BE; ຟລີມິຊ (ລາຕິນ) +zh-Hans-fonipa; ຈີນແບບຮຽບງ່າຍ (ສັດທະສາດອັກສອນສາກົນ) + + +@locale=lt +@languageDisplay=standard + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; ispanų (Lotynų Amerika) +es-Cyrl-MX; ispanų (kirilica, Meksika) +hi-Latn; hindi (lotynų) +nl-BE; olandų (Belgija) +nl-Latn-BE; olandų (lotynų, Belgija) +zh-Hans-fonipa; kinų (supaprastinti, Tarptautinės abėcėlės fonetika) + + +@locale=lt +@languageDisplay=dialect + +en-MM; anglų (Mianmaras [Birma]) +es; ispanų +es-419; Lotynų Amerikos ispanų +es-Cyrl-MX; Meksikos ispanų (kirilica) +hi-Latn; hindi (lotynų) +nl-BE; flamandų +nl-Latn-BE; flamandų (lotynų) +zh-Hans-fonipa; supaprastintoji kinų (Tarptautinės abėcėlės fonetika) + + +@locale=lv +@languageDisplay=standard + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi (latīņu) +nl-BE; holandiešu (Beļģija) +nl-Latn-BE; holandiešu (latīņu, Beļģija) +zh-Hans-fonipa; ķīniešu (vienkāršotā, Starptautiskais fonētiskais alfabēts) + + +@locale=lv +@languageDisplay=dialect + +en-MM; angļu (Mjanma [Birma]) +es; spāņu +es-419; spāņu (Latīņamerika) +es-Cyrl-MX; spāņu (kirilica, Meksika) +hi-Latn; hindi (latīņu) +nl-BE; flāmu +nl-Latn-BE; flāmu (latīņu) +zh-Hans-fonipa; ķīniešu vienkāršotā (Starptautiskais fonētiskais alfabēts) + + +@locale=mk +@languageDisplay=standard + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (кирилско писмо, Мексико) +hi-Latn; хинди (латинично писмо) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латинично писмо, Белгија) +zh-Hans-fonipa; кинески (поедноставено, FONIPA) + + +@locale=mk +@languageDisplay=dialect + +en-MM; англиски (Мјанмар [Бурма]) +es; шпански +es-419; латиноамерикански шпански +es-Cyrl-MX; мексикански шпански (кирилско писмо) +hi-Latn; хинди (латинично писмо) +nl-BE; фламански +nl-Latn-BE; фламански (латинично писмо) +zh-Hans-fonipa; поедноставен кинески (FONIPA) + + +@locale=ml +@languageDisplay=standard + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; സ്‌പാനിഷ് (ലാറ്റിനമേരിക്ക) +es-Cyrl-MX; സ്‌പാനിഷ് (സിറിലിക്, മെക്സിക്കോ) +hi-Latn; ഹിന്ദി (ലാറ്റിൻ) +nl-BE; ഡച്ച് (ബെൽജിയം) +nl-Latn-BE; ഡച്ച് (ലാറ്റിൻ, ബെൽജിയം) +zh-Hans-fonipa; ചൈനീസ് (ലളിതവൽക്കരിച്ചത്, ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=ml +@languageDisplay=dialect + +en-MM; ഇംഗ്ലീഷ് (മ്യാൻമാർ [ബർമ്മ]) +es; സ്‌പാനിഷ് +es-419; ലാറ്റിൻ അമേരിക്കൻ സ്‌പാനിഷ് +es-Cyrl-MX; മെക്സിക്കൻ സ്പാനിഷ് (സിറിലിക്) +hi-Latn; ഹിന്ദി (ലാറ്റിൻ) +nl-BE; ഫ്ലമിഷ് +nl-Latn-BE; ഫ്ലമിഷ് (ലാറ്റിൻ) +zh-Hans-fonipa; ലളിതമാക്കിയ ചൈനീസ് (ഐപി‌എ സ്വനവ്യവസ്ഥ) + + +@locale=mn +@languageDisplay=standard + +en-MM; англи (Мьянмар) +es; испани +es-419; испани (Латин Америк) +es-Cyrl-MX; испани (кирилл, Мексик) +hi-Latn; хинди (латин) +nl-BE; нидерланд (Бельги) +nl-Latn-BE; нидерланд (латин, Бельги) +zh-Hans-fonipa; хятад (хялбаршуулсан, FONIPA) + + +@locale=mn +@languageDisplay=dialect + +en-MM; англи (Мьянмар) +es; испани +es-419; испани хэл [Латин Америк] +es-Cyrl-MX; испани хэл [Мексик] (кирилл) +hi-Latn; хинди (латин) +nl-BE; фламанд +nl-Latn-BE; фламанд (латин) +zh-Hans-fonipa; хялбаршуулсан хятад (FONIPA) + + +@locale=mr +@languageDisplay=standard + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; स्पॅनिश (लॅटिन अमेरिका) +es-Cyrl-MX; स्पॅनिश (सीरिलिक, मेक्सिको) +hi-Latn; हिंदी (लॅटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (लॅटिन, बेल्जियम) +zh-Hans-fonipa; चीनी (सरलीकृत, FONIPA) + + +@locale=mr +@languageDisplay=dialect + +en-MM; इंग्रजी (म्यानमार [बर्मा]) +es; स्पॅनिश +es-419; लॅटिन अमेरिकन स्पॅनिश +es-Cyrl-MX; मेक्सिकन स्पॅनिश (सीरिलिक) +hi-Latn; हिंदी (लॅटिन) +nl-BE; फ्लेमिश +nl-Latn-BE; फ्लेमिश (लॅटिन) +zh-Hans-fonipa; सरलीकृत चीनी (FONIPA) + + +@locale=ms +@languageDisplay=standard + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol (Amerika Latin) +es-Cyrl-MX; Sepanyol (Cyril, Mexico) +hi-Latn; Hindi (Latin) +nl-BE; Belanda (Belgium) +nl-Latn-BE; Belanda (Latin, Belgium) +zh-Hans-fonipa; Cina (Ringkas, Fonetik IPA) + + +@locale=ms +@languageDisplay=dialect + +en-MM; Inggeris (Myanmar [Burma]) +es; Sepanyol +es-419; Sepanyol Amerika Latin +es-Cyrl-MX; Sepanyol Mexico (Cyril) +hi-Latn; Hindi (Latin) +nl-BE; Flemish +nl-Latn-BE; Flemish (Latin) +zh-Hans-fonipa; Cina Ringkas (Fonetik IPA) + + +@locale=my +@languageDisplay=standard + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် (စစ်ရိလစ်/ မက်ကဆီကို) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဒတ်ခ်ျ (ဘယ်လ်ဂျီယမ်) +nl-Latn-BE; ဒတ်ခ်ျ (လက်တင်/ ဘယ်လ်ဂျီယမ်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=my +@languageDisplay=dialect + +en-MM; အင်္ဂလိပ် (မြန်မာ) +es; စပိန် +es-419; စပိန် (လက်တင်အမေရိက) +es-Cyrl-MX; စပိန် [မက္ကဆီကို] (စစ်ရိလစ်) +hi-Latn; ဟိန်ဒူ (လက်တင်) +nl-BE; ဖလီမစ်ရှ် +nl-Latn-BE; ဖလီမစ်ရှ် (လက်တင်) +zh-Hans-fonipa; တရုတ် (ရိုးရှင်း/ IPA အသံထွက်) + + +@locale=nb +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=nb +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=ne +@languageDisplay=standard + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; स्पेनी (ल्याटिन अमेरिका) +es-Cyrl-MX; स्पेनी (सिरिलिक, मेक्सिको) +hi-Latn; हिन्दी (ल्याटिन) +nl-BE; डच (बेल्जियम) +nl-Latn-BE; डच (ल्याटिन, बेल्जियम) +zh-Hans-fonipa; चिनियाँ (सरलिकृत चिनियाँ, FONIPA) + + +@locale=ne +@languageDisplay=dialect + +en-MM; अङ्ग्रेजी (म्यान्मार [बर्मा]) +es; स्पेनी +es-419; ल्याटिन अमेरिकी स्पेनी +es-Cyrl-MX; मेक्सिकन स्पेनी (सिरिलिक) +hi-Latn; हिन्दी (ल्याटिन) +nl-BE; फ्लेमिस +nl-Latn-BE; फ्लेमिस (ल्याटिन) +zh-Hans-fonipa; सरलिकृत चिनियाँ (FONIPA) + + +@locale=nl +@languageDisplay=standard + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Nederlands (België) +nl-Latn-BE; Nederlands (Latijns, België) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nl +@languageDisplay=dialect + +en-MM; Engels (Myanmar [Birma]) +es; Spaans +es-419; Spaans (Latijns-Amerika) +es-Cyrl-MX; Spaans (Cyrillisch, Mexico) +hi-Latn; Hindi (Latijns) +nl-BE; Vlaams +nl-Latn-BE; Vlaams (Latijns) +zh-Hans-fonipa; Chinees (vereenvoudigd, Internationaal Fonetisch Alfabet) + + +@locale=nn +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenkla, det internasjonale fonetiske alfabetet [IPA]) + + +@locale=nn +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenkla kinesisk (det internasjonale fonetiske alfabetet [IPA]) + + +@locale=no +@languageDisplay=standard + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; nederlandsk (Belgia) +nl-Latn-BE; nederlandsk (latinsk, Belgia) +zh-Hans-fonipa; kinesisk (forenklet, det internasjonale fonetiske alfabet [IPA]) + + +@locale=no +@languageDisplay=dialect + +en-MM; engelsk (Myanmar [Burma]) +es; spansk +es-419; spansk (Latin-Amerika) +es-Cyrl-MX; spansk (kyrillisk, Mexico) +hi-Latn; hindi (latinsk) +nl-BE; flamsk +nl-Latn-BE; flamsk (latinsk) +zh-Hans-fonipa; forenklet kinesisk (det internasjonale fonetiske alfabet [IPA]) + + +@locale=or +@languageDisplay=standard + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ସ୍ପେନିୟ (ଲାଟିନ୍‌ ଆମେରିକା) +es-Cyrl-MX; ସ୍ପେନିୟ (ସିରିଲିକ୍, ମେକ୍ସିକୋ) +hi-Latn; ହିନ୍ଦୀ (ଲାଟିନ୍) +nl-BE; ଡଚ୍ (ବେଲଜିୟମ୍) +nl-Latn-BE; ଡଚ୍ (ଲାଟିନ୍, ବେଲଜିୟମ୍) +zh-Hans-fonipa; ଚାଇନିଜ୍‌ (ସରଳୀକୃତ, FONIPA) + + +@locale=or +@languageDisplay=dialect + +en-MM; ଇଂରାଜୀ (ମିଆଁମାର) +es; ସ୍ପେନିୟ +es-419; ଲାଟିନ୍‌ ଆମେରିକୀୟ ସ୍ପାନିସ୍‌ +es-Cyrl-MX; ମେକ୍ସିକାନ ସ୍ପାନିସ୍‌ (ସିରିଲିକ୍) +hi-Latn; ହିନ୍ଦୀ (ଲାଟିନ୍) +nl-BE; ଫ୍ଲେମିଶ୍ +nl-Latn-BE; ଫ୍ଲେମିଶ୍ (ଲାଟିନ୍) +zh-Hans-fonipa; ସରଳୀକୃତ ଚାଇନିଜ୍‌ (FONIPA) + + +@locale=pa +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa_Guru +@languageDisplay=standard + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ (ਲਾਤੀਨੀ ਅਮਰੀਕਾ) +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਡੱਚ (ਬੈਲਜੀਅਮ) +nl-Latn-BE; ਡੱਚ (ਲਾਤੀਨੀ, ਬੈਲਜੀਅਮ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pa_Guru +@languageDisplay=dialect + +en-MM; ਅੰਗਰੇਜ਼ੀ (ਮਿਆਂਮਾਰ [ਬਰਮਾ]) +es; ਸਪੇਨੀ +es-419; ਸਪੇਨੀ [ਲਾਤੀਨੀ ਅਮਰੀਕੀ] +es-Cyrl-MX; ਸਪੇਨੀ (ਸਿਰਿਲਿਕ, ਮੈਕਸੀਕੋ) +hi-Latn; ਹਿੰਦੀ (ਲਾਤੀਨੀ) +nl-BE; ਫਲੈਮਿਸ਼ +nl-Latn-BE; ਫਲੈਮਿਸ਼ (ਲਾਤੀਨੀ) +zh-Hans-fonipa; ਚੀਨੀ (ਸਰਲ, FONIPA) + + +@locale=pl +@languageDisplay=standard + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; hiszpański (Ameryka Łacińska) +es-Cyrl-MX; hiszpański (cyrylica, Meksyk) +hi-Latn; hindi (łacińskie) +nl-BE; niderlandzki (Belgia) +nl-Latn-BE; niderlandzki (łacińskie, Belgia) +zh-Hans-fonipa; chiński (uproszczone, fonetyczny międzynarodowy) + + +@locale=pl +@languageDisplay=dialect + +en-MM; angielski (Mjanma [Birma]) +es; hiszpański +es-419; amerykański hiszpański +es-Cyrl-MX; meksykański hiszpański (cyrylica) +hi-Latn; hindi [alfabet łaciński] +nl-BE; flamandzki +nl-Latn-BE; flamandzki (łacińskie) +zh-Hans-fonipa; chiński uproszczony (fonetyczny międzynarodowy) + + +@locale=ps +@languageDisplay=standard + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاتیني امریکا) +es-Cyrl-MX; هسپانوي (سیریلیک, میکسیکو) +hi-Latn; هندي (لاتين/لاتيني) +nl-BE; هالېنډي (بیلجیم) +nl-Latn-BE; هالېنډي (لاتين/لاتيني, بیلجیم) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=ps +@languageDisplay=dialect + +en-MM; انګليسي (ميانمار [برما]) +es; هسپانوي +es-419; لاتيني امريکايي هسپانوي +es-Cyrl-MX; ميکسيکي هسپانوي (سیریلیک) +hi-Latn; هندي [لاتيني] +nl-BE; فلېمېشي +nl-Latn-BE; فلېمېشي (لاتين/لاتيني) +zh-Hans-fonipa; چیني (ساده شوی, FONIPA) + + +@locale=pt +@languageDisplay=standard + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; holandês (Bélgica) +nl-Latn-BE; holandês (latim, Bélgica) +zh-Hans-fonipa; chinês (simplificado, fonética do Alfabeto Fonético Internacional) + + +@locale=pt +@languageDisplay=dialect + +en-MM; inglês (Mianmar [Birmânia]) +es; espanhol +es-419; espanhol (América Latina) +es-Cyrl-MX; espanhol (cirílico, México) +hi-Latn; híndi (latim) +nl-BE; flamengo +nl-Latn-BE; flamengo (latim) +zh-Hans-fonipa; chinês simplificado (fonética do Alfabeto Fonético Internacional) + + +@locale=ro +@languageDisplay=standard + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; neerlandeză (Belgia) +nl-Latn-BE; neerlandeză (latină, Belgia) +zh-Hans-fonipa; chineză (simplificată, alfabet fonetic internațional) + + +@locale=ro +@languageDisplay=dialect + +en-MM; engleză (Myanmar [Birmania]) +es; spaniolă +es-419; spaniolă (America Latină) +es-Cyrl-MX; spaniolă (chirilică, Mexic) +hi-Latn; hindi (latină) +nl-BE; flamandă +nl-Latn-BE; flamandă (latină) +zh-Hans-fonipa; chineză simplificată (alfabet fonetic internațional) + + +@locale=root +@languageDisplay=standard + +en-MM; en (MM) +es; es +es-419; es (419) +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=root +@languageDisplay=dialect + +en-MM; en (MM) +es; es +es-419; es_419 +es-Cyrl-MX; es (Cyrl, MX) +hi-Latn; hi (Latn) +nl-BE; nl (BE) +nl-Latn-BE; nl (Latn, BE) +zh-Hans-fonipa; zh (Hans, FONIPA) + + +@locale=ru +@languageDisplay=standard + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; испанский (Латинская Америка) +es-Cyrl-MX; испанский (кириллица, Мексика) +hi-Latn; хинди (латиница) +nl-BE; нидерландский (Бельгия) +nl-Latn-BE; нидерландский (латиница, Бельгия) +zh-Hans-fonipa; китайский (упрощенная, Международный фонетический алфавит) + + +@locale=ru +@languageDisplay=dialect + +en-MM; английский (Мьянма [Бирма]) +es; испанский +es-419; латиноамериканский испанский +es-Cyrl-MX; мексиканский испанский (кириллица) +hi-Latn; хинди (латиница) +nl-BE; фламандский +nl-Latn-BE; фламандский (латиница) +zh-Hans-fonipa; китайский, упрощенное письмо (Международный фонетический алфавит) + + +@locale=sd +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=standard + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; هسپانوي (لاطيني آمريڪا) +es-Cyrl-MX; هسپانوي (سيريلي, ميڪسيڪو) +hi-Latn; هندي (لاطيني) +nl-BE; ڊچ (بيلجيم) +nl-Latn-BE; ڊچ (لاطيني, بيلجيم) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=sd_Arab +@languageDisplay=dialect + +en-MM; انگريزي (ميانمار [برما]) +es; هسپانوي +es-419; لاطيني آمريڪي اسپينش +es-Cyrl-MX; ميڪسيڪين اسپيني (سيريلي) +hi-Latn; هندي (لاطيني) +nl-BE; فليمش +nl-Latn-BE; فليمش (لاطيني) +zh-Hans-fonipa; چيني (سادي, FONIPA) + + +@locale=si +@languageDisplay=standard + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ස්පාඤ්ඤ (ලතින් ඇමෙරිකාව) +es-Cyrl-MX; ස්පාඤ්ඤ (සිරිලික්, මෙක්සිකෝව) +hi-Latn; හින්දි (ලතින්) +nl-BE; ලන්දේසි (බෙල්ජියම) +nl-Latn-BE; ලන්දේසි (ලතින්, බෙල්ජියම) +zh-Hans-fonipa; චීන (සුළුකළ, FONIPA) + + +@locale=si +@languageDisplay=dialect + +en-MM; ඉංග්‍රීසි (මියන්මාරය [බුරුමය]) +es; ස්පාඤ්ඤ +es-419; ලතින් ඇමරිකානු ස්පාඤ්ඤ +es-Cyrl-MX; මෙක්සිකානු ස්පාඤ්ඤ (සිරිලික්) +hi-Latn; හින්දි (ලතින්) +nl-BE; ෆ්ලෙමිශ් +nl-Latn-BE; ෆ්ලෙමිශ් (ලතින්) +zh-Hans-fonipa; සරල චීන (FONIPA) + + +@locale=sk +@languageDisplay=standard + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina (Latinská Amerika) +es-Cyrl-MX; španielčina (cyrilika, Mexiko) +hi-Latn; hindčina (latinka) +nl-BE; holandčina (Belgicko) +nl-Latn-BE; holandčina (latinka, Belgicko) +zh-Hans-fonipa; čínština (zjednodušené, FONIPA) + + +@locale=sk +@languageDisplay=dialect + +en-MM; angličtina (Mjanmarsko) +es; španielčina +es-419; španielčina [latinskoamerická] +es-Cyrl-MX; španielčina [mexická] (cyrilika) +hi-Latn; hindčina (latinka) +nl-BE; flámčina +nl-Latn-BE; flámčina (latinka) +zh-Hans-fonipa; čínština [zjednodušená] (FONIPA) + + +@locale=sl +@languageDisplay=standard + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; španščina (Latinska Amerika) +es-Cyrl-MX; španščina (cirilica, Mehika) +hi-Latn; hindijščina (latinica) +nl-BE; nizozemščina (Belgija) +nl-Latn-BE; nizozemščina (latinica, Belgija) +zh-Hans-fonipa; kitajščina (poenostavljena pisava, mednarodna fonetična pisava IPA) + + +@locale=sl +@languageDisplay=dialect + +en-MM; angleščina (Mjanmar [Burma]) +es; španščina +es-419; latinskoameriška španščina +es-Cyrl-MX; mehiška španščina (cirilica) +hi-Latn; hindijščina (latinica) +nl-BE; flamščina +nl-Latn-BE; flamščina (latinica) +zh-Hans-fonipa; poenostavljena kitajščina (mednarodna fonetična pisava IPA) + + +@locale=so +@languageDisplay=standard + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanish (Laatiin Ameerika) +es-Cyrl-MX; Isbaanish (Siriylik, Meksiko) +hi-Latn; Hindi (Laatiin) +nl-BE; Holandays (Biljam) +nl-Latn-BE; Holandays (Laatiin, Biljam) +zh-Hans-fonipa; Shiinaha Mandarin (La fududeeyay, FONIPA) + + +@locale=so +@languageDisplay=dialect + +en-MM; Ingiriisi (Mayanmar) +es; Isbaanish +es-419; Isbaanishka Laatiin Ameerika +es-Cyrl-MX; Isbaanishka Mexico (Siriylik) +hi-Latn; Hindi [Latin] +nl-BE; Af faleemi +nl-Latn-BE; Af faleemi (Laatiin) +zh-Hans-fonipa; Shiinaha Rasmiga ah (FONIPA) + + +@locale=sq +@languageDisplay=standard + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjisht (Amerika Latine) +es-Cyrl-MX; spanjisht (cirilik, Meksikë) +hi-Latn; indisht (latin) +nl-BE; holandisht (Belgjikë) +nl-Latn-BE; holandisht (latin, Belgjikë) +zh-Hans-fonipa; kinezisht (i thjeshtuar, FONIPA) + + +@locale=sq +@languageDisplay=dialect + +en-MM; anglisht (Mianmar [Burmë]) +es; spanjisht +es-419; spanjishte amerikano-latine +es-Cyrl-MX; spanjishte meksikane (cirilik) +hi-Latn; indisht (latin) +nl-BE; flamandisht +nl-Latn-BE; flamandisht (latin) +zh-Hans-fonipa; kinezishte e thjeshtuar (FONIPA) + + +@locale=sr +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=standard + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; холандски (Белгија) +nl-Latn-BE; холандски (латиница, Белгија) +zh-Hans-fonipa; кинески (поједностављено кинеско писмо, ИПА фонетика) + + +@locale=sr_Cyrl +@languageDisplay=dialect + +en-MM; енглески (Мијанмар [Бурма]) +es; шпански +es-419; шпански (Латинска Америка) +es-Cyrl-MX; шпански (ћирилица, Мексико) +hi-Latn; хинди (латиница) +nl-BE; фламански +nl-Latn-BE; фламански (латиница) +zh-Hans-fonipa; поједностављени кинески (ИПА фонетика) + + +@locale=sr_Latn +@languageDisplay=standard + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; holandski (Belgija) +nl-Latn-BE; holandski (latinica, Belgija) +zh-Hans-fonipa; kineski (pojednostavljeno kinesko pismo, IPA fonetika) + + +@locale=sr_Latn +@languageDisplay=dialect + +en-MM; engleski (Mijanmar [Burma]) +es; španski +es-419; španski (Latinska Amerika) +es-Cyrl-MX; španski (ćirilica, Meksiko) +hi-Latn; hindi (latinica) +nl-BE; flamanski +nl-Latn-BE; flamanski (latinica) +zh-Hans-fonipa; pojednostavljeni kineski (IPA fonetika) + + +@locale=sv +@languageDisplay=standard + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; spanska (Latinamerika) +es-Cyrl-MX; spanska (kyrilliska, Mexiko) +hi-Latn; hindi (latinska) +nl-BE; nederländska (Belgien) +nl-Latn-BE; nederländska (latinska, Belgien) +zh-Hans-fonipa; kinesiska (förenklad, internationell fonetisk notation - IPA) + + +@locale=sv +@languageDisplay=dialect + +en-MM; engelska (Myanmar [Burma]) +es; spanska +es-419; latinamerikansk spanska +es-Cyrl-MX; mexikansk spanska (kyrilliska) +hi-Latn; hindi [latinsk] +nl-BE; flamländska +nl-Latn-BE; flamländska (latinska) +zh-Hans-fonipa; förenklad kinesiska (internationell fonetisk notation - IPA) + + +@locale=sw +@languageDisplay=standard + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania (Amerika ya Kilatini) +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiholanzi (Ubelgiji) +nl-Latn-BE; Kiholanzi (Kilatini, Ubelgiji) +zh-Hans-fonipa; Kichina (Rahisi, FONIPA) + + +@locale=sw +@languageDisplay=dialect + +en-MM; Kiingereza (Myanmar [Burma]) +es; Kihispania +es-419; Kihispania [Amerika ya Latini] +es-Cyrl-MX; Kihispania (Kisiriliki, Meksiko) +hi-Latn; Kihindi (Kilatini) +nl-BE; Kiflemi +nl-Latn-BE; Kiflemi (Kilatini) +zh-Hans-fonipa; Kichina [Kilichorahisishwa] (FONIPA) + + +@locale=ta +@languageDisplay=standard + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; ஸ்பானிஷ் (லத்தீன் அமெரிக்கா) +es-Cyrl-MX; ஸ்பானிஷ் (சிரிலிக், மெக்சிகோ) +hi-Latn; இந்தி (லத்தின்) +nl-BE; டச்சு (பெல்ஜியம்) +nl-Latn-BE; டச்சு (லத்தின், பெல்ஜியம்) +zh-Hans-fonipa; சீனம் (எளிதாக்கப்பட்டது, FONIPA) + + +@locale=ta +@languageDisplay=dialect + +en-MM; ஆங்கிலம் (மியான்மார் [பர்மா]) +es; ஸ்பானிஷ் +es-419; லத்தின் அமெரிக்க ஸ்பானிஷ் +es-Cyrl-MX; மெக்ஸிகன் ஸ்பானிஷ் (சிரிலிக்) +hi-Latn; இந்தி (லத்தின்) +nl-BE; ஃப்லெமிஷ் +nl-Latn-BE; ஃப்லெமிஷ் (லத்தின்) +zh-Hans-fonipa; எளிதாக்கப்பட்ட சீனம் (FONIPA) + + +@locale=te +@languageDisplay=standard + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; స్పానిష్ (లాటిన్ అమెరికా) +es-Cyrl-MX; స్పానిష్ (సిరిలిక్, మెక్సికో) +hi-Latn; హిందీ (లాటిన్) +nl-BE; డచ్ (బెల్జియం) +nl-Latn-BE; డచ్ (లాటిన్, బెల్జియం) +zh-Hans-fonipa; చైనీస్ (సరళీకృతం, FONIPA) + + +@locale=te +@languageDisplay=dialect + +en-MM; ఇంగ్లీష్ (మయన్మార్) +es; స్పానిష్ +es-419; లాటిన్ అమెరికన్ స్పానిష్ +es-Cyrl-MX; మెక్సికన్ స్పానిష్ (సిరిలిక్) +hi-Latn; హిందీ (లాటిన్) +nl-BE; ఫ్లెమిష్ +nl-Latn-BE; ఫ్లెమిష్ (లాటిన్) +zh-Hans-fonipa; సరళీకృత చైనీస్ (FONIPA) + + +@locale=th +@languageDisplay=standard + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน (ละตินอเมริกา) +es-Cyrl-MX; สเปน (ซีริลลิก, เม็กซิโก) +hi-Latn; ฮินดี (ละติน) +nl-BE; ดัตช์ (เบลเยียม) +nl-Latn-BE; ดัตช์ (ละติน, เบลเยียม) +zh-Hans-fonipa; จีน (ตัวย่อ, สัทอักษรสากล) + + +@locale=th +@languageDisplay=dialect + +en-MM; อังกฤษ (เมียนมา [พม่า]) +es; สเปน +es-419; สเปน - ละตินอเมริกา +es-Cyrl-MX; สเปน - เม็กซิโก (ซีริลลิก) +hi-Latn; ฮินดี (ละติน) +nl-BE; เฟลมิช +nl-Latn-BE; เฟลมิช (ละติน) +zh-Hans-fonipa; จีนตัวย่อ (สัทอักษรสากล) + + +@locale=tk +@languageDisplay=standard + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; niderland dili (Belgiýa) +nl-Latn-BE; niderland dili (Latyn elipbiýi, Belgiýa) +zh-Hans-fonipa; hytaý dili (Ýönekeýleşdirilen, FONIPA) + + +@locale=tk +@languageDisplay=dialect + +en-MM; iňlis dili (Mýanma [Birma]) +es; ispan dili +es-419; ispan dili (Latyn Amerikasy) +es-Cyrl-MX; ispan dili (Kiril elipbiýi, Meksika) +hi-Latn; hindi dili (Latyn elipbiýi) +nl-BE; flamand dili +nl-Latn-BE; flamand dili (Latyn elipbiýi) +zh-Hans-fonipa; ýönekeýleşdirilen hytaý dili (FONIPA) + + +@locale=tr +@languageDisplay=standard + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; İspanyolca (Latin Amerika) +es-Cyrl-MX; İspanyolca (Kiril, Meksika) +hi-Latn; Hintçe (Latin) +nl-BE; Felemenkçe (Belçika) +nl-Latn-BE; Felemenkçe (Latin, Belçika) +zh-Hans-fonipa; Çince (Basitleştirilmiş, IPA Ses Bilimi) + + +@locale=tr +@languageDisplay=dialect + +en-MM; İngilizce (Myanmar [Burma]) +es; İspanyolca +es-419; Latin Amerika İspanyolcası +es-Cyrl-MX; Meksika İspanyolcası (Kiril) +hi-Latn; Hintçe (Latin) +nl-BE; Flamanca +nl-Latn-BE; Flamanca (Latin) +zh-Hans-fonipa; Basitleştirilmiş Çince (IPA Ses Bilimi) + + +@locale=uk +@languageDisplay=standard + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; іспанська (Латинська Америка) +es-Cyrl-MX; іспанська (кирилиця, Мексика) +hi-Latn; гінді (латиниця) +nl-BE; нідерландська (Бельгія) +nl-Latn-BE; нідерландська (латиниця, Бельгія) +zh-Hans-fonipa; китайська (спрощена, Міжнародний фонетичний алфавіт) + + +@locale=uk +@languageDisplay=dialect + +en-MM; англійська (Мʼянма [Бірма]) +es; іспанська +es-419; іспанська (Латинська Америка) +es-Cyrl-MX; іспанська (кирилиця, Мексика) +hi-Latn; гінді (латиниця) +nl-BE; фламандська +nl-Latn-BE; фламандська (латиниця) +zh-Hans-fonipa; китайська [спрощене письмо] (Міжнародний фонетичний алфавіт) + + +@locale=ur +@languageDisplay=standard + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; ہسپانوی (لاطینی امریکہ) +es-Cyrl-MX; ہسپانوی (سیریلک،میکسیکو) +hi-Latn; ہندی (لاطینی) +nl-BE; ڈچ (بیلجیم) +nl-Latn-BE; ڈچ (لاطینی،بیلجیم) +zh-Hans-fonipa; چینی (آسان،FONIPA) + + +@locale=ur +@languageDisplay=dialect + +en-MM; انگریزی (میانمار [برما]) +es; ہسپانوی +es-419; لاطینی امریکی ہسپانوی +es-Cyrl-MX; میکسیکن ہسپانوی (سیریلک) +hi-Latn; ہندی (لاطینی) +nl-BE; فلیمِش +nl-Latn-BE; فلیمِش (لاطینی) +zh-Hans-fonipa; چینی [آسان کردہ] (FONIPA) + + +@locale=uz +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind (lotin) +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz_Latn +@languageDisplay=standard + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispancha (Lotin Amerikasi) +es-Cyrl-MX; ispancha (kirill, Meksika) +hi-Latn; hind (lotin) +nl-BE; niderland (Belgiya) +nl-Latn-BE; niderland (lotin, Belgiya) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=uz_Latn +@languageDisplay=dialect + +en-MM; inglizcha (Myanma [Birma]) +es; ispancha +es-419; ispan [Lotin Amerikasi] +es-Cyrl-MX; ispan [Meksika] (kirill) +hi-Latn; hind (lotin) +nl-BE; flamand +nl-Latn-BE; flamand (lotin) +zh-Hans-fonipa; xitoy (soddalashgan, FONIPA) + + +@locale=vi +@languageDisplay=standard + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha (Châu Mỹ La-tinh) +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Hà Lan (Bỉ) +nl-Latn-BE; Tiếng Hà Lan (Chữ La tinh, Bỉ) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=vi +@languageDisplay=dialect + +en-MM; Tiếng Anh (Myanmar [Miến Điện]) +es; Tiếng Tây Ban Nha +es-419; Tiếng Tây Ban Nha [Mỹ La tinh] +es-Cyrl-MX; Tiếng Tây Ban Nha (Chữ Kirin, Mexico) +hi-Latn; Tiếng Hindi (Chữ La tinh) +nl-BE; Tiếng Flemish +nl-Latn-BE; Tiếng Flemish (Chữ La tinh) +zh-Hans-fonipa; Tiếng Trung (Giản thể, Ngữ âm học IPA) + + +@locale=yo +@languageDisplay=standard + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì (Látín Amẹ́ríkà) +es-Cyrl-MX; Èdè Sípáníìṣì (èdè ilẹ̀ Rọ́ṣíà, Mesiko) +hi-Latn; Èdè Híńdì (Èdè Látìn) +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Edè Ṣáínà (tí wọ́n mú rọrùn., FONIPA) + + +@locale=yo +@languageDisplay=dialect + +en-MM; Èdè Gẹ̀ẹ́sì (Manamari) +es; Èdè Sípáníìṣì +es-419; Èdè Sípáníìṣì [orílẹ̀-èdè Látìn-Amẹ́ríkà] +es-Cyrl-MX; Èdè Sípáníìṣì [orílẹ̀-èdè Mẹ́síkò] (èdè ilẹ̀ Rọ́ṣíà) +hi-Latn; Èdè Híndì [Látìnì] +nl-BE; Èdè Dọ́ọ̀ṣì (Bégíọ́mù) +nl-Latn-BE; Èdè Dọ́ọ̀ṣì (Èdè Látìn, Bégíọ́mù) +zh-Hans-fonipa; Ẹdè Ṣáínà Onírọ̀rùn (FONIPA) + + +@locale=yue +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=standard + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷兰文 (比利时) +nl-Latn-BE; 荷兰文 (拉丁文,比利时) +zh-Hans-fonipa; 中文 (简体,IPA 拼音) + + +@locale=yue_Hans +@languageDisplay=dialect + +en-MM; 英文 (缅甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛兰芒文 +nl-Latn-BE; 佛兰芒文 (拉丁文) +zh-Hans-fonipa; 简体中文 (IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=standard + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 荷蘭文 (比利時) +nl-Latn-BE; 荷蘭文 (拉丁文,比利時) +zh-Hans-fonipa; 中文 (簡體,IPA 拼音) + + +@locale=yue_Hant +@languageDisplay=dialect + +en-MM; 英文 (緬甸) +es; 西班牙文 +es-419; 西班牙文 (拉丁美洲) +es-Cyrl-MX; 西班牙文 (斯拉夫文,墨西哥) +hi-Latn; 北印度文 (拉丁文) +nl-BE; 佛蘭芒文 +nl-Latn-BE; 佛蘭芒文 (拉丁文) +zh-Hans-fonipa; 簡體中文 (IPA 拼音) + + +@locale=zh +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hans +@languageDisplay=standard + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 西班牙语(拉丁美洲) +es-Cyrl-MX; 西班牙语(西里尔文,墨西哥) +hi-Latn; 印地语(拉丁文) +nl-BE; 荷兰语(比利时) +nl-Latn-BE; 荷兰语(拉丁文,比利时) +zh-Hans-fonipa; 中文(简体,国际音标) + + +@locale=zh_Hans +@languageDisplay=dialect + +en-MM; 英语(缅甸) +es; 西班牙语 +es-419; 拉丁美洲西班牙语 +es-Cyrl-MX; 墨西哥西班牙语(西里尔文) +hi-Latn; 印地语(拉丁文) +nl-BE; 弗拉芒语 +nl-Latn-BE; 弗拉芒语(拉丁文) +zh-Hans-fonipa; 简体中文(国际音标) + + +@locale=zh_Hant +@languageDisplay=standard + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地文(拉丁文) +nl-BE; 荷蘭文(比利時) +nl-Latn-BE; 荷蘭文(拉丁文,比利時) +zh-Hans-fonipa; 中文(簡體,IPA 拼音) + + +@locale=zh_Hant +@languageDisplay=dialect + +en-MM; 英文(緬甸) +es; 西班牙文 +es-419; 西班牙文(拉丁美洲) +es-Cyrl-MX; 西班牙文(西里爾文字,墨西哥) +hi-Latn; 印地語[拉丁文] +nl-BE; 法蘭德斯文 +nl-Latn-BE; 法蘭德斯文(拉丁文) +zh-Hans-fonipa; 簡體中文(IPA 拼音) + + +@locale=zu +@languageDisplay=standard + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Spanish (i-Latin America) +es-Cyrl-MX; isi-Spanish (isi-Cyrillic, i-Mexico) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Dutch (i-Belgium) +nl-Latn-BE; isi-Dutch (isi-Latin, i-Belgium) +zh-Hans-fonipa; isi-Chinese (enziwe lula, Ifonotiki ye-IPA) + + +@locale=zu +@languageDisplay=dialect + +en-MM; i-English (i-Myanmar [Burma]) +es; isi-Spanish +es-419; isi-Latin American Spanish +es-Cyrl-MX; isi-Mexican Spanish (isi-Cyrillic) +hi-Latn; isi-Hindi (isi-Latin) +nl-BE; isi-Flemish +nl-Latn-BE; isi-Flemish (isi-Latin) +zh-Hans-fonipa; isi-Chinese [esenziwe-lula] (Ifonotiki ye-IPA) + From f21de9830675e7f70da9e5bbe62ba13b31c58bbe Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Wed, 21 Aug 2024 15:43:19 -0700 Subject: [PATCH 20/26] ICU4X rel date time - non-Latn number system --> unsupported (#289) * ICU4X relative date time - label non-Latn numbering system as unsupported * Better setting of unicode extension in locale --- .../rust/1.3/src/relativedatetime_fmt.rs | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/executors/rust/1.3/src/relativedatetime_fmt.rs b/executors/rust/1.3/src/relativedatetime_fmt.rs index d609e908..61a8fcd9 100644 --- a/executors/rust/1.3/src/relativedatetime_fmt.rs +++ b/executors/rust/1.3/src/relativedatetime_fmt.rs @@ -1,7 +1,14 @@ // https://docs.rs/icu/1.3.2/icu/relativetime/struct.RelativeTimeFormatter.html +// https://docs.rs/icu_provider/1.3.0/icu_provider/struct.DataLocale.html#method.get_unicode_ext use fixed_decimal::FixedDecimal; + +use icu::locid::extensions::unicode; +use icu::locid::extensions::unicode::key; use icu::locid::Locale; + +use std::str::FromStr; + use icu_provider::DataLocale; use icu::relativetime::options::Numeric; @@ -128,16 +135,13 @@ pub fn run_relativedatetimeformat_test(json_obj: &Value) -> Result = &option_struct.numbering_system; + // Set up the locale with its options. let locale_json_str: &str = json_obj["locale"].as_str().unwrap(); - let mut locale_str: String = locale_json_str.to_string(); - if numbering_system_str.is_some() { - locale_str = - locale_json_str.to_string() + "-u-nu-" + &numbering_system_str.as_ref().unwrap(); - } + let locale_str: String = locale_json_str.to_string(); - let lang_id = if let Ok(lc) = locale_str.parse::() { + let locale_id = if let Ok(lc) = locale_str.parse::() { lc } else { return Ok(json!({ @@ -146,7 +150,31 @@ pub fn run_relativedatetimeformat_test(json_obj: &Value) -> Result Date: Fri, 23 Aug 2024 15:46:52 -0700 Subject: [PATCH 21/26] Updating logging output - simplifying output (#293) * Updating logging output - simplifying * Remove incorrect updates --- run_config.json | 19 +++++----- schema/check_test_output.py | 2 +- schema/schema_validator.py | 12 +++---- testdriver/testdriver.py | 12 ++++--- testdriver/testplan.py | 40 +++++++++------------- testgen/generators/datetime_fmt.py | 6 ++-- testgen/generators/list_fmt.py | 6 ++-- testgen/generators/relativedatetime_fmt.py | 6 ++-- verifier/verifier.py | 5 ++- 9 files changed, 51 insertions(+), 57 deletions(-) diff --git a/run_config.json b/run_config.json index 90bf3fcb..3f9201e4 100644 --- a/run_config.json +++ b/run_config.json @@ -11,7 +11,6 @@ "test_type": [ "collation_short", "datetime_fmt", - "lang_names", "likely_subtags", "list_fmt", "number_fmt", @@ -32,7 +31,6 @@ "test_type": [ "collation_short", "datetime_fmt", - "lang_names", "likely_subtags", "list_fmt", "number_fmt", @@ -113,7 +111,7 @@ "prereq": { "name": "nvm 22..0, icu75.1", "version": "22.1.0", - "command": "nvm install 22.1.0;nvm use 22.1.0" + "command": "nvm install 22.1.0;nvm use 22.1.0 --silent" }, "run": { "icu_version": "icu75", @@ -135,7 +133,7 @@ "prereq": { "name": "nvm", "version": "20.1.0", - "command": "nvm install 20.1.0;nvm use 20.1.0" + "command": "nvm install 20.1.0;nvm use 20.1.0 --silent" }, "run": { "icu_version": "icu73", @@ -153,7 +151,7 @@ "prereq": { "name": "nvm 21.6.0, icu74.1", "version": "21.6.0", - "command": "nvm install 21.6.0;nvm use 21.6.0" + "command": "nvm install 21.6.0;nvm use 21.6.0 --silent" }, "run": { "icu_version": "icu74", @@ -175,7 +173,7 @@ "prereq": { "name": "nvm", "version": "20.1.0", - "command": "nvm install 20.1.0;nvm use 20.1.0" + "command": "nvm install 20.1.0;nvm use 20.1.0 --silent" }, "run": { "icu_version": "icu73", @@ -197,7 +195,7 @@ "prereq": { "name": "nvm", "version": "18.14.2", - "command": "nvm install 18.14.2;nvm use 18.14.2" + "command": "nvm install 18.14.2;nvm use 18.14.2 --silent" }, "run": { "icu_version": "icu72", @@ -207,7 +205,6 @@ "datetime_fmt", "list_fmt", "number_fmt", - "lang_names", "likely_subtags", "rdt_fmt", "plural_rules" @@ -219,7 +216,7 @@ "prereq": { "name": "nvm", "version": "18.7.0", - "command": "nvm install 18.7.0;nvm use 18.7.0" + "command": "nvm install 18.7.0;nvm use 18.7.0 --silent" }, "run": { "icu_version": "icu71", @@ -239,7 +236,7 @@ "prereq": { "name": "nvm", "version": "14.21.3", - "command": "nvm install 14.21.3;nvm use 14.21.3" + "command": "nvm install 14.21.3;nvm use 14.21.3 --silent" }, "run": { "icu_version": "icu70", @@ -255,7 +252,7 @@ "prereq": { "name": "nvm", "version": "14.18.3", - "command": "nvm install 14.18.3;nvm use 14.18.3" + "command": "nvm install 14.18.3;nvm use 14.18.3 --silent" }, "run": { "icu_version": "icu69", diff --git a/schema/check_test_output.py b/schema/check_test_output.py index 68a6a5da..9be41429 100644 --- a/schema/check_test_output.py +++ b/schema/check_test_output.py @@ -55,7 +55,7 @@ def main(args): test_type = schema_files.TEST_FILE_TO_TEST_TYPE_MAP[test_file_prefix] test_type_set.add(test_type) except BaseException as err: - logging.info('No file (%s) during schema check output: %s', file, err + logging.debug('No file (%s) during schema check output: %s', file, err ) for dir in icu_dirs: icu_version_set.add(os.path.basename(dir)) diff --git a/schema/schema_validator.py b/schema/schema_validator.py index 051a2d1b..2686f03c 100644 --- a/schema/schema_validator.py +++ b/schema/schema_validator.py @@ -27,7 +27,7 @@ def parallel_validate_schema(validator, json_pairs): num_processors = mp.cpu_count() - loging.info('JSON validation: %s processors for %s plans' % num_processors, len(file_names)) + logging.info('JSON validation: %s processors for %s plans' % num_processors, len(file_names)) # How to get all the results processor_pool = mp.Pool(num_processors) @@ -134,7 +134,7 @@ def validate_test_data_with_schema(self): if file_path_pair: schema_test_info.append(file_path_pair) else: - # logging.info('No data test file %s for %s, %s', file_path_pair, test_type, icu_version) + logging.debug('No data test file %s for %s, %s', file_path_pair, test_type, icu_version) pass results = self.parallel_check_test_data_schema(schema_test_info) @@ -148,7 +148,7 @@ def validate_test_data_with_schema(self): logging.warning('FAIL: Test data %s, %s. MSG=%s', test_type, icu_version, result_data['err_info']) else: - logging.info('Test data validated: %s %s', result_data['test_type'], result_data['icu_version']) + logging.debug('Test data validated: %s %s', result_data['test_type'], result_data['icu_version']) all_results.append(result_data) return all_results @@ -207,7 +207,7 @@ def check_test_data_against_schema(self, schema_info): def check_test_data_schema(self, icu_version, test_type): # Check the generated test data for structure agains the schema - logging.info('Validating %s with %s', test_type, icu_version) + logging.debug('Validating %s with %s', test_type, icu_version) # Check test output vs. the test data schema schema_verify_file = os.path.join( self.schema_base, test_type, 'test_schema.json') @@ -238,7 +238,7 @@ def check_test_data_schema(self, icu_version, test_type): test_result = result results['result'] = result if result: - logging.info('Test data %s validated successfully, with ICU %s', test_type, icu_version) + logging.debug('Test data %s validated successfully, with ICU %s', test_type, icu_version) else: logging.error('Test data %s FAILED with ICU %s: %s', test_type, icu_version, err_info) @@ -265,7 +265,7 @@ def get_test_output_schema_plan(self, icu_version, test_type, executor): def check_test_output_schema(self, icu_version, test_type, executor): # Check the output of the tests for structure against the schema - logging.info('Validating test output: %s %s %s', executor , test_type, icu_version) + logging.debug('Validating test output: %s %s %s', executor , test_type, icu_version) # Check test output vs. the schema schema_file_name = SCHEMA_FILE_MAP[test_type]['result_data']['schema_file'] diff --git a/testdriver/testdriver.py b/testdriver/testdriver.py index a696acfd..3d2bb6b6 100644 --- a/testdriver/testdriver.py +++ b/testdriver/testdriver.py @@ -51,7 +51,7 @@ def set_args(self, arg_options): # Create a test plan based on data and options test_data_info = ddt_data.testDatasets[test_type] if self.debug: - logging.info('$$$$$ test_type = %s test_data_info = %s', + logging.debug('$$$$$ test_type = %s test_data_info = %s', test_type, test_data_info.testDataFilename) for executor in arg_options.exec: @@ -91,8 +91,7 @@ def parse_args(self, args): # Get all the arguments argparse = ddtargs.DdtArgs(args) - if self.debug: - logging.info('TestDriver OPTIONS: %s', argparse.getOptions()) + logging.debug('TestDriver OPTIONS: %s', argparse.getOptions()) # Now use the argparse.options to set the values in the driver self.set_args(argparse.getOptions()) @@ -105,13 +104,13 @@ def run_plans(self): plan.run_plan() def run_one(self, plan): - logging.info("Parallel of %s %s %s" % (plan.test_lang, plan.test_type, plan.icu_version)) + logging.debug("Parallel of %s %s %s" % (plan.test_lang, plan.test_type, plan.icu_version)) plan.run_plan() def run_plans_parallel(self): # Testing 15-Jan-2024 num_processors = mp.cpu_count() - logging.info('There are %s processors for %s plans' % (num_processors, len(self.test_plans))) + logging.info('TestDriver: %s processors for %s plans' % (num_processors, len(self.test_plans))) processor_pool = mp.Pool(num_processors) with processor_pool as p: @@ -125,6 +124,9 @@ def main(args): # print('ARGS = %s' % (args)) driver.parse_args(args[1:]) + logger = logging.Logger("TEST DRIVER LOGGER") + logger.setLevel(logging.INFO) + if driver.run_serial: driver.run_plans() else: diff --git a/testdriver/testplan.py b/testdriver/testplan.py index 310527ec..91db2aa5 100644 --- a/testdriver/testplan.py +++ b/testdriver/testplan.py @@ -98,7 +98,7 @@ def run_plan(self): # Test data versions are given as "icu" + primary number, e.g., "73" # TODO: Consider sorting with possible dotted versions, e.g., 73.1.3 newest_version = sorted(icu_test_dirs, reverse=True)[0] - logging.info('** Replacing proposed icu version of %s with version %s', + logging.warning('** Replacing proposed icu version of %s with version %s', self.icu_version, newest_version) self.icu_version = newest_version @@ -130,12 +130,10 @@ def run_plan(self): if self.options.run_limit: self.run_limit = int(self.options.run_limit) - if self.debug: - logging.debug('!!! RUN LIMIT SET: %d', self.run_limit) + logging.debug('!!! RUN LIMIT SET: %d', self.run_limit) - if self.debug: - logging.debug('Running plan %s on data %s', - self.exec_command, self.inputFilePath) + logging.debug('Running plan %s on data %s', + self.exec_command, self.inputFilePath) if self.options.exec_mode == 'one_test': self.run_one_test_mode() @@ -155,8 +153,7 @@ def request_executor_info(self): self.jsonOutput["platform error"] = self.run_error_message return None else: - if self.debug: - logging.debug('EXECUTOR INFO = %s', result) + logging.debug('EXECUTOR INFO = %s', result) try: self.jsonOutput["platform"] = json.loads(result) @@ -199,9 +196,8 @@ def request_executor_termination(self, terminate_args=None): if not result: self.jsonOutput["platform error"] = self.run_error_message else: - if self.debug: - logging.debug('TERMINATION INFO = %s', result) - self.jsonOutput["platform"] = json.loads(result) + logging.debug('TERMINATION INFO = %s', result) + self.jsonOutput["platform"] = json.loads(result) def generate_header(self): # TODO: Create JSON versions of each of these rather than printing @@ -237,9 +233,8 @@ def complete_output_file(self, error_info): self.resultsFile.close() def run_one_test_mode(self): - if self.debug: - logging.debug(' Running OneTestMode %s on data %s', - self.exec_command, self.inputFilePath) + logging.debug(' Running OneTestMode %s on data %s', + self.exec_command, self.inputFilePath) # Set up calls for version data --> results @@ -252,17 +247,15 @@ def run_one_test_mode(self): # The test data was not found. Skip this test. return None - if self.debug: - logging.info('@@@ %d tests found', len(tests)) + logging.debug('@@@ %d tests found', len(tests)) # Initialize JSON output headers --> results self.exec_list = self.exec_command.split() # TODO: get other things about the exec - if self.debug: - logging.info('EXEC info: exec_command %s, exec_list >%s<', - self.exec_command, - self.exec_list) + logging.debug('EXEC info: exec_command %s, exec_list >%s<', + self.exec_command, + self.exec_list) # Start the JSON output # Set up calls for version data --> results @@ -284,9 +277,8 @@ def run_one_test_mode(self): # Create results file try: - if self.debug: - logging.debug('++++++ Results file path = %s', self.outputFilePath) - self.resultsFile = open(self.outputFilePath, encoding='utf-8', mode='w') + logging.debug('++++++ Results file path = %s', self.outputFilePath) + self.resultsFile = open(self.outputFilePath, encoding='utf-8', mode='w') except BaseException as error: logging.error('*** Cannot open results file at %s. Err = %s', self.outputFilePath, error) @@ -375,7 +367,7 @@ def run_all_single_tests(self, tests_per_execution=1): test_num += 1 if self.run_limit and test_num > self.run_limit: - logging.info('** Stopped after %d tests', (test_num - 1)) + logging.debug('** Stopped after %d tests', (test_num - 1)) break # PROCESS THE LAST BATCH, if any diff --git a/testgen/generators/datetime_fmt.py b/testgen/generators/datetime_fmt.py index 8e968c16..fae7addb 100644 --- a/testgen/generators/datetime_fmt.py +++ b/testgen/generators/datetime_fmt.py @@ -23,7 +23,7 @@ def process_test_data(self): } run_list = [ - ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0'], + ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0 --silent'], ['node generators/datetime_gen.js'], ['mv datetime_fmt*.json icu74'] ] @@ -35,10 +35,10 @@ def process_test_data(self): # Set up Node version and call the generator # Add temporal to the package. nvm_version = icu_nvm_versions[self.icu_version] - generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; npm ci; node generators/datetime_gen.js %s %s' % ( + generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s --silent; npm ci; node generators/datetime_gen.js %s %s' % ( nvm_version, nvm_version, '-run_limit', self.run_limit) - logging.info('Running this command: %s', generate_command) + logging.debug('Running this command: %s', generate_command) result = result = subprocess.run(generate_command, shell=True) # Move results to the right directory diff --git a/testgen/generators/list_fmt.py b/testgen/generators/list_fmt.py index 0e18e054..9dd1401f 100644 --- a/testgen/generators/list_fmt.py +++ b/testgen/generators/list_fmt.py @@ -23,7 +23,7 @@ def process_test_data(self): } run_list = [ - ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0'], + ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0 --silent'], ['node generators/list_fmt_gen.js'], ['mv list_fmt*.json icu74'] ] @@ -34,9 +34,9 @@ def process_test_data(self): # Set up Node version and call the generator nvm_version = icu_nvm_versions[self.icu_version] - generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/list_fmt_gen.js' % (nvm_version, nvm_version) + generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s --silent; node generators/list_fmt_gen.js' % (nvm_version, nvm_version) - logging.info('Running this command: %s', generate_command) + logging.debug('Running this command: %s', generate_command) result = result = subprocess.run(generate_command, shell=True) # Move results to the right directory diff --git a/testgen/generators/relativedatetime_fmt.py b/testgen/generators/relativedatetime_fmt.py index ae202cda..34729894 100644 --- a/testgen/generators/relativedatetime_fmt.py +++ b/testgen/generators/relativedatetime_fmt.py @@ -23,7 +23,7 @@ def process_test_data(self): } run_list = [ - ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0'], + ['source ~/.nvm/nvm.sh; nvm install 21.6.0; nvm use 21.6.0 --silent'], ['node generators/rdt_gen.js'], ['mv rdt_fmt*.json icu74'] ] @@ -34,9 +34,9 @@ def process_test_data(self): # Set up Node version and call the generator nvm_version = icu_nvm_versions[self.icu_version] - generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/rdt_fmt_gen.js' % (nvm_version, nvm_version) + generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s --silent; node generators/rdt_fmt_gen.js' % (nvm_version, nvm_version) - logging.info('Running this command: %s', generate_command) + logging.debug('Running this command: %s', generate_command) result = subprocess.run(generate_command, shell=True) # Move results to the right directory diff --git a/verifier/verifier.py b/verifier/verifier.py index da6e890b..134a0417 100644 --- a/verifier/verifier.py +++ b/verifier/verifier.py @@ -60,6 +60,9 @@ def __init__(self): logging.config.fileConfig("../logging.conf") + logger = logging.Logger("VERIFIER LOGGER") + logger.setLevel(logging.WARNING) + def open_verify_files(self, vplan): # Get test data, verify data, and results for a case. try: @@ -282,7 +285,7 @@ def analyze_failures(self): def setup_paths(self, executor, testfile, verify_file): base_dir = self.file_base if self.debug > 1: - logging.deubg('&&& FILE BASE = %s', base_dir) + logging.debug('&&& FILE BASE = %s', base_dir) # Check on the path defined here test_output_dir = 'testOutput' self.resultPath = os.path.join( From 3dd59033d6971f901f290d95be82171a7170ecee Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Mon, 26 Aug 2024 15:29:11 -0700 Subject: [PATCH 22/26] Lang name generator from cldr and using it (#290) * CLDR locale display names: generate data. Update Node and ICU4J * Working for language names, not locale names * Locale names now working without variants * Rename langnames.rs --> localenames.rs * Updating locale display names with dialect and standard * Move CPP LangNames to LocaleDisplayNames * Cleaning up some code * Rename node langNames to localeDisplayNames * Renaming node langnames stuff * Updated based on suggestions --- executors/cpp/Makefile | 2 +- executors/cpp/langnames.cpp | 66 --------- executors/cpp/localedisplaynames.cpp | 82 +++++++++++ executors/cpp/main.cpp | 4 +- .../langnames/LangNamesDisplayOptions.java | 16 +++ .../langnames/LangNamesInputJson.java | 2 + .../testtype/langnames/LangNamesTester.java | 9 +- .../langnames/icu74/LangNamesTest.java | 22 +++ executors/node/executor.js | 8 +- .../{langnames.js => localedisplaynames.js} | 13 +- .../1.3/src/{langnames.rs => localenames.rs} | 36 +++-- executors/rust/1.3/src/main.rs | 12 +- schema/lang_names/test_schema.json | 4 + testgen/generators/localeDisplayNames.py | 127 ++++++++++++++++++ testgen/testdata_gen.py | 14 +- verifier/testreport.py | 1 + 16 files changed, 320 insertions(+), 98 deletions(-) delete mode 100644 executors/cpp/langnames.cpp create mode 100644 executors/cpp/localedisplaynames.cpp create mode 100644 executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesDisplayOptions.java rename executors/node/{langnames.js => localedisplaynames.js} (81%) rename executors/rust/1.3/src/{langnames.rs => localenames.rs} (65%) create mode 100644 testgen/generators/localeDisplayNames.py diff --git a/executors/cpp/Makefile b/executors/cpp/Makefile index 0534c2f4..6d6604f9 100644 --- a/executors/cpp/Makefile +++ b/executors/cpp/Makefile @@ -16,7 +16,7 @@ TARGET=executor # All object files (C or C++) -OBJECTS=main.o coll.o datetime_fmt.o langnames.o likely_subtags.o list_fmt.o message_fmt2.o number_fmt.o plural_rules.o relativedatetime_fmt.o util.o +OBJECTS=main.o coll.o datetime_fmt.o localedisplaynames.o likely_subtags.o list_fmt.o message_fmt2.o number_fmt.o plural_rules.o relativedatetime_fmt.o util.o #### rules # Load in standard makefile definitions diff --git a/executors/cpp/langnames.cpp b/executors/cpp/langnames.cpp deleted file mode 100644 index 4d9add5c..00000000 --- a/executors/cpp/langnames.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************** - * testing icu4c for language display names - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "./util.h" - -using std::cout; -using std::endl; -using std::string; - -using icu::Locale; -using icu::UnicodeString; - -const string TestLangNames (json_object *json_in) { - UErrorCode status = U_ZERO_ERROR; - - json_object *label_obj = json_object_object_get(json_in, "label"); - string label_string = json_object_get_string(label_obj); - - - // The locale in which the name is given. - json_object *locale_label_obj = - json_object_object_get(json_in, "locale_label"); - string locale_string = json_object_get_string(locale_label_obj); - - // The language's name to be displayed. - json_object *language_label_obj = json_object_object_get( - json_in, "language_label"); - string language_label_string = json_object_get_string(language_label_obj); - - Locale displayLocale(locale_string.c_str()); - - Locale testLocale(language_label_string.c_str()); - - UnicodeString testLang; - - testLocale.getDisplayName(displayLocale, testLang); - - json_object *return_json = json_object_new_object(); - json_object_object_add(return_json, "label", label_obj); - - string result_string; - testLang.toUTF8String(result_string); - - json_object_object_add(return_json, - "result", - json_object_new_string(result_string.c_str())); - - string return_string = json_object_to_json_string(return_json); - return return_string; -} diff --git a/executors/cpp/localedisplaynames.cpp b/executors/cpp/localedisplaynames.cpp new file mode 100644 index 00000000..565fa679 --- /dev/null +++ b/executors/cpp/localedisplaynames.cpp @@ -0,0 +1,82 @@ +/******************************************************************** + * testing icu4c for locale display names + */ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include "./util.h" + +using icu::Locale; +using icu::UnicodeString; +using icu::LocaleDisplayNames; + +const string TestLocaleDisplayNames (json_object *json_in) { + UErrorCode status = U_ZERO_ERROR; + + json_object *label_obj = json_object_object_get(json_in, "label"); + string label_string = json_object_get_string(label_obj); + + // The locale in which the name is given. + json_object *locale_label_obj = + json_object_object_get(json_in, "locale_label"); + string locale_string = json_object_get_string(locale_label_obj); + + // The locales's name to be displayed. + json_object *displayed_locale_label_obj = json_object_object_get( + json_in, "language_label"); + string displayed_locale_label_string = + json_object_get_string(displayed_locale_label_obj); + + // Either standard or dialect names for the locale. + string language_display_string = "standard"; + json_object *language_display_obj = json_object_object_get( + json_in, "languageDisplay"); + if (language_display_obj) { + language_display_string = json_object_get_string(language_display_obj); + } + + // In what language to show the locale name + Locale displayLocale(locale_string.c_str()); + + // The id of the locale to be formatted. + Locale testLocale(displayed_locale_label_string.c_str()); + + // Create display names object with the kind of locale name. + // Default is "standard". + UDialectHandling display_handling = ULDN_STANDARD_NAMES; + if (language_display_string == "dialect") { + display_handling = ULDN_DIALECT_NAMES; + } + + LocaleDisplayNames* ldn = + LocaleDisplayNames::createInstance(displayLocale, display_handling); + + // Get the resulting string for this testLocale + UnicodeString locale_name_result; + ldn->localeDisplayName(testLocale, locale_name_result); + delete ldn; + + string result_string; + locale_name_result.toUTF8String(result_string); + + // Create the output with label and resulting locale name. + json_object *return_json = json_object_new_object(); + json_object_object_add(return_json, "label", label_obj); + + + json_object_object_add(return_json, + "result", + json_object_new_string(result_string.c_str())); + + string return_string = json_object_to_json_string(return_json); + return return_string; +} diff --git a/executors/cpp/main.cpp b/executors/cpp/main.cpp index a703f718..d75d1457 100644 --- a/executors/cpp/main.cpp +++ b/executors/cpp/main.cpp @@ -41,7 +41,7 @@ using std::string; // Test functions extern const string TestCollator(json_object *json_in); extern const string TestDatetimeFmt(json_object *json_in); -extern const string TestLangNames(json_object *json_in); +extern const string TestLocaleDisplayNames(json_object *json_in); extern const string TestLikelySubtags(json_object *json_in); extern const string TestListFmt(json_object *json_in); @@ -127,7 +127,7 @@ int main(int argc, const char** argv) { } else if (test_type == "list_fmt") { outputLine = TestListFmt(json_input); } else if (test_type == "lang_names") { - outputLine = TestLangNames(json_input); + outputLine = TestLocaleDisplayNames(json_input); } else if (test_type == "plural_rules") { outputLine = TestPluralRules(json_input); } else if (test_type == "rdt_fmt") { diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesDisplayOptions.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesDisplayOptions.java new file mode 100644 index 00000000..75a650c1 --- /dev/null +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesDisplayOptions.java @@ -0,0 +1,16 @@ +package org.unicode.conformance.testtype.langnames; + +public enum LangNamesDisplayOptions { + STANDARD, + DIALECT; // ULDN_DIALECT_NAMES is the ICU4C enum + + public static org.unicode.conformance.testtype.langnames.LangNamesDisplayOptions DEFAULT = STANDARD; + + public static org.unicode.conformance.testtype.langnames.LangNamesDisplayOptions getFromString(String s) { + try { + return org.unicode.conformance.testtype.langnames.LangNamesDisplayOptions.valueOf(s.toUpperCase()); + } catch (Exception e){ + return DEFAULT; + } + } +} diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesInputJson.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesInputJson.java index a1ae247b..5532f69d 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesInputJson.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesInputJson.java @@ -12,4 +12,6 @@ public class LangNamesInputJson implements ITestTypeInputJson { public String locale_label; + public LangNamesDisplayOptions language_display; // For standard or dialect + } diff --git a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesTester.java b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesTester.java index 76ae2ddb..175094c0 100644 --- a/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesTester.java +++ b/executors/icu4j/74/executor-icu4j/src/main/java/org/unicode/conformance/testtype/langnames/LangNamesTester.java @@ -24,6 +24,9 @@ public ITestTypeInputJson inputMapToJson(Map inputMapData) { result.language_label = (String) inputMapData.get("language_label", null); result.locale_label = (String) inputMapData.get("locale_label", null); + String lang_display_string = (String) inputMapData.get("languageDisplay", null); + result.language_display = LangNamesDisplayOptions.getFromString(lang_display_string); + return result; } @@ -71,6 +74,10 @@ public String formatOutputJson(ITestTypeOutputJson outputJson) { public String getDisplayLanguageString(LangNamesInputJson input) { String localeID = input.language_label; String displayLocaleID = input.locale_label; - return ULocale.getDisplayNameWithDialect(localeID, displayLocaleID); + if (input.language_display == LangNamesDisplayOptions.STANDARD) { + return ULocale.getDisplayName(localeID, displayLocaleID); + } else { + return ULocale.getDisplayNameWithDialect(localeID, displayLocaleID); + } } } diff --git a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java index 6cfa35b4..fa2b879a 100644 --- a/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java +++ b/executors/icu4j/74/executor-icu4j/src/test/java/org/unicode/conformance/langnames/icu74/LangNamesTest.java @@ -19,4 +19,26 @@ public void testLocaleAndDisplayLocale() { assertEquals("Französisch", output.result); } + @Test + public void testLocaleNameStandardDutchBelgium() { + String testInput = + "{\"test_type\": \"lang_names\", \"label\": \"nl1\", \"language_label\": \"nl-BE\", \"locale_label\": \"en\", \"languageDisplay\": \"standard\"}"; + + LangNamesOutputJson output = + (LangNamesOutputJson) LangNamesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("Dutch (Belgium)", output.result); + } + + @Test + public void testLocaleNameDialectFlemish() { + String testInput = + "{\"test_type\": \"lang_names\", \"label\": \"nl2\", \"language_label\": \"nl-BE\", \"locale_label\": \"en\", \"languageDisplay\": \"dialect\"}"; + + LangNamesOutputJson output = + (LangNamesOutputJson) LangNamesTester.INSTANCE.getStructuredOutputFromInputStr(testInput); + + assertEquals("Flemish", output.result); + } + } diff --git a/executors/node/executor.js b/executors/node/executor.js index 2bfd7dc4..4d12aa71 100644 --- a/executors/node/executor.js +++ b/executors/node/executor.js @@ -22,7 +22,7 @@ let numberformatter = require('./numberformat.js'); let displaynames = require('./displaynames.js'); -let langnames = require('./langnames.js'); +let localedisplaynames = require('./localedisplaynames.js') let likely_subtags = require('./likely_subtags.js'); @@ -62,8 +62,8 @@ const testTypes = { TestDateTimeFormat : Symbol("datetime_fmt"), TestPluralRules : Symbol("plural_rules"), TestDisplayNames : Symbol("display_names"), - TestLangNames : Symbol("language_display_name"), TestListFmt : Symbol("list_fmt"), + TestLocaleDisplayNames : Symbol("language_display_name"), TestRelativeDateTimeFormat : Symbol("rdt_fmt") }; @@ -138,7 +138,7 @@ function parseJsonForTestId(parsed) { } if (testId == "language_display_name" || testId == "lang_names") { - return testTypes.TestLangNames; + return testTypes.TestLocaleDisplayNames; } if (testId == "datetime_fmt") { @@ -231,7 +231,7 @@ rl.on('line', function(line) { outputLine = displaynames.testDisplayNames(parsedJson); } else if (test_type == "language_display_name" || test_type == "lang_names") { - outputLine = langnames.testLangNames(parsedJson); + outputLine = localedisplaynames.testLocaleDisplayNames(parsedJson); } else if (test_type == "likely_subtags") { outputLine = likely_subtags.testLikelySubtags(parsedJson); diff --git a/executors/node/langnames.js b/executors/node/localedisplaynames.js similarity index 81% rename from executors/node/langnames.js rename to executors/node/localedisplaynames.js index 970d3d21..fe73937e 100644 --- a/executors/node/langnames.js +++ b/executors/node/localedisplaynames.js @@ -2,7 +2,7 @@ module.exports = { - testLangNames: function (json) { + testLocaleDisplayNames: function (json) { let locale = 'en'; // Default let options = {}; if (json['locale_label']) { @@ -15,9 +15,12 @@ module.exports = { let label = json['label']; let input = json['language_label'].replace(/_/g, '-'); + if (json['languageDisplay']) { + // Fix to use dash, not underscore. + options['languageDisplay'] = json['languageDisplay']; + } + let outputLine; - //console.log("langnames input: " + input + - // " options: " + JSON.stringify(options) + " locale " + locale); let dn; try { @@ -42,12 +45,12 @@ module.exports = { "result": resultString }; } catch (error) { - //console.log("LangName problem: input = " + input + ", error = " + error); outputLine = {"label": json['label'], "locale_label": locale, "language_label": input, "result": resultString, - "error": error.toString() + "error": error.toString(), + "actual_options": options.toString() }; } return outputLine; diff --git a/executors/rust/1.3/src/langnames.rs b/executors/rust/1.3/src/localenames.rs similarity index 65% rename from executors/rust/1.3/src/langnames.rs rename to executors/rust/1.3/src/localenames.rs index 1803f861..ea0aba4d 100644 --- a/executors/rust/1.3/src/langnames.rs +++ b/executors/rust/1.3/src/localenames.rs @@ -2,22 +2,23 @@ use serde_json::{json, Value}; -use icu::displaynames::{DisplayNamesOptions, LanguageDisplayNames}; +use icu::displaynames::{DisplayNamesOptions, LocaleDisplayNamesFormatter}; -use icu::locid::subtags::Language; use icu::locid::Locale; -// Function runs language names tests -pub fn run_language_name_test(json_obj: &Value) -> Result { +use icu::displaynames::LanguageDisplay; + +// Function runs locale names tests +pub fn run_locale_name_test(json_obj: &Value) -> Result { let label = &json_obj["label"].as_str().unwrap(); - let options: DisplayNamesOptions = Default::default(); + let mut options: DisplayNamesOptions = Default::default(); let language_label = json_obj["language_label"] .as_str() .unwrap() .replace('_', "-"); - let input_lang_result = language_label.parse::(); - let input_lang = match input_lang_result { + let input_locale_result = language_label.parse::(); + let input_locale = match input_locale_result { Ok(l) => l, Err(_e) => { return Ok(json!({ @@ -44,11 +45,24 @@ pub fn run_language_name_test(json_obj: &Value) -> Result { "test_type": "display_names", "unsupported": "locale name", "error_type": "unsupported", - "error_detail": {"unsupported_locale": &locale_name_result} + "error_detail": {"cannot parse locale": &locale_name_result} })) } }; + // Get either standard or dialect form of locale name. + let language_display_result = json_obj["languageDisplay"].as_str(); + let language_display: LanguageDisplay = match language_display_result { + Some(s) => match s { + "standard" => LanguageDisplay::Standard, + "dialect" => LanguageDisplay::Dialect, + &_ => LanguageDisplay::Standard, + }, + None => LanguageDisplay::Standard, // The default + }; + + options.language_display = language_display; + let langid_result = locale_name.parse::(); let langid = match langid_result { @@ -67,13 +81,13 @@ pub fn run_language_name_test(json_obj: &Value) -> Result { } }; - let display_name_formatter = LanguageDisplayNames::try_new(&langid.into(), options); + let display_name_formatter = LocaleDisplayNamesFormatter::try_new(&langid.into(), options); let json_result = match display_name_formatter { Ok(formatter) => { json!({ "label": label, - "result": formatter.of(input_lang) + "result": formatter.of(&input_locale) }) } Err(e) => { @@ -83,7 +97,7 @@ pub fn run_language_name_test(json_obj: &Value) -> Result { "error": e.to_string(), "error_type": "unsupported", "unsupported": e.to_string(), - "error_detail": {"unsupported_locale": locale_name} + "error_detail": {"formatting fails for": locale_name} }) } }; diff --git a/executors/rust/1.3/src/main.rs b/executors/rust/1.3/src/main.rs index 97b79afc..7c412c47 100644 --- a/executors/rust/1.3/src/main.rs +++ b/executors/rust/1.3/src/main.rs @@ -8,10 +8,10 @@ // DONE 5. Move parameter extraction into function. // 6. Fix NumberFormat with options // 7. Clean up code -// 8. Decide on a repository structure -// DONE 9. Modularize into separate files for each type of test +// 8. DONE Decide on a repository structure +// 9. DONE Modularize into separate files for each type of test // 10. Fix test_type and switch statement -// 11. Add language names +// 11. DONE Add language names --> locale names // References for ICU4X: // https://unicode-org.github.io/icu4x-docs/doc/icu_collator/index.html @@ -20,18 +20,18 @@ mod collator; mod datetimefmt; mod decimalfmt; mod displaynames; -mod langnames; mod likelysubtags; mod listfmt; +mod localenames; mod numberfmt; mod pluralrules; mod relativedatetime_fmt; use collator::run_collation_test; use datetimefmt::run_datetimeformat_test; -use langnames::run_language_name_test; use likelysubtags::run_likelysubtags_test; use listfmt::run_list_fmt_test; +use localenames::run_locale_name_test; use numberfmt::run_numberformat_test; use pluralrules::run_plural_rules_test; use relativedatetime_fmt::run_relativedatetimeformat_test; @@ -111,7 +111,7 @@ fn main() -> io::Result<()> { || (test_type == "language_display_name") || (test_type == "lang_names") { - run_language_name_test(&json_info) + run_locale_name_test(&json_info) } else if test_type == "likely_subtags" { run_likelysubtags_test(&json_info) } else if test_type == "list_fmt" { diff --git a/schema/lang_names/test_schema.json b/schema/lang_names/test_schema.json index b0716b28..3985c944 100644 --- a/schema/lang_names/test_schema.json +++ b/schema/lang_names/test_schema.json @@ -49,6 +49,10 @@ "description": "locale tag of the source language ", "type": "string" }, + "languageDisplay": { + "description": "either 'standard' or 'dialect'", + "type": "string" + }, "locale_label": { "description": "locale tag of the language being described ", "type": "string" diff --git a/testgen/generators/localeDisplayNames.py b/testgen/generators/localeDisplayNames.py new file mode 100644 index 00000000..1e1a7613 --- /dev/null +++ b/testgen/generators/localeDisplayNames.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +import os +import json +import re +import logging +from generators.base import DataGenerator + +reblankline = re.compile("^\s*$") + + +class LocaleNamesGenerator(DataGenerator): + json_test = {"test_type": "lang_names"} + json_verify = {"test_type": "lang_names"} + + + def process_test_data(self): + self.languageNameDescr() + # Data constructed from CLDR data + filename = "localeDisplayName.txt" + raw_locale_display_names_testdata = self.readFile(filename, self.icu_version) + + if not raw_locale_display_names_testdata: + # File may not exist + return None + + # TODO: add standard vs. dialect vs. alternate names + self.generateLanguageNameTestDataObjects(raw_locale_display_names_testdata) + self.generateTestHashValues(self.json_test) + output_path = os.path.join(self.icu_version, "lang_name_test_file.json") + lang_name_test_file = open(output_path, "w", encoding="UTF-8") + json.dump(self.json_test, lang_name_test_file, indent=1) + lang_name_test_file.close() + + output_path = os.path.join(self.icu_version, "lang_name_verify_file.json") + lang_name_verify_file = open(output_path, "w", encoding="UTF-8") + json.dump(self.json_verify, lang_name_verify_file, indent=1) + lang_name_verify_file.close() + + return True + + def languageNameDescr(self): + # Adds information to LanguageName tests and verify JSON + descr = "Language display name test cases. The first code declares the language whose display name is requested while the second code declares the locale to display the language name in." + test_id = "lang_names" + source_url = "No URL yet." + version = "unspecified" + self.json_test = { + "test_type": test_id, + "Test scenario": test_id, + "description": descr, + "source": { + "repository": "conformance-test", + "version": "trunk", + "url": source_url, + "source_version": version, + }, + } + return + + def generateLanguageNameTestDataObjects(self, rawtestdata): + # Get the JSON data for tests and verification for language names + recommentline = re.compile("^\s*#") + + set_locale = re.compile(r"@locale=(\w+)") + set_languageDisplay = re.compile(r"@languageDisplay=(\w+)") + + count = 0 + + jtests = [] + jverify = [] + + # Compute max size needed for label number + test_lines = rawtestdata.splitlines() + num_samples = len(test_lines) + max_digits = self.computeMaxDigitsForCount(num_samples) + + language_label = 'und' + language_display = 'standard' + + for item in test_lines: + if not (recommentline.match(item) or reblankline.match(item)): + + locale_match = set_locale.match(item) + if locale_match: + locale_label = locale_match.group(1) + continue + + language_display_match = set_languageDisplay.match(item) + if language_display_match: + language_display = language_display_match.group(1) + continue + + test_data = self.parseLanguageNameData(item) + if test_data == None: + logging.debug( + " LanguageNames (%s): Line '%s' not recognized as valid test data entry", + self.icu_version, + item, + ) + continue + else: + label = str(count).rjust(max_digits, "0") + test_json = { + "label": label, + "language_label": test_data[0], + "locale_label": locale_label, + "languageDisplay": language_display + } + jtests.append(test_json) + jverify.append({"label": label, "verify": test_data[1]}) + count += 1 + + self.json_test["tests"] = self.sample_tests(jtests) + self.json_verify["verifications"] = self.sample_tests(jverify) + + logging.info("LocaleDisplayNames Test (%s): %d lines processed", self.icu_version, count) + return + + def parseLanguageNameData(self, rawtestdata): + reformat = re.compile(r"(\w+(\-\w+)*);\s*(.+)$") + + test_match = reformat.search(rawtestdata) + + if test_match != None: + return (test_match.group(1), test_match.group(3)) + else: + return None diff --git a/testgen/testdata_gen.py b/testgen/testdata_gen.py index b734a643..9c469432 100644 --- a/testgen/testdata_gen.py +++ b/testgen/testdata_gen.py @@ -9,6 +9,7 @@ from generators.collation_short import CollationShortGenerator from generators.datetime_fmt import DateTimeFmtGenerator from generators.lang_names import LangNamesGenerator +from generators.localeDisplayNames import LocaleNamesGenerator from generators.likely_subtags import LikelySubtagsGenerator from generators.message_fmt2 import MessageFmt2Generator from generators.list_fmt import ListFmtGenerator @@ -80,8 +81,17 @@ def generate_versioned_data(version_info): if TestType.LANG_NAMES in args.test_types: # This is slow - generator = LangNamesGenerator(icu_version, args.run_limit) - generator.process_test_data() + + # First try with the new source of data. If not found, then use the older + # lang names generator. + generator = LocaleNamesGenerator(icu_version, args.run_limit) + if not generator: + logging.info('lang generated from old LangNames data in %s', icu_version) + generator = LangNamesGenerator(icu_version, args.run_limit) + else: + logging.info('lang generated from new LocaleNames data in %s', icu_version) + if generator: + generator.process_test_data() if TestType.LIKELY_SUBTAGS in args.test_types: generator = LikelySubtagsGenerator(icu_version, args.run_limit) diff --git a/verifier/testreport.py b/verifier/testreport.py index 487275a2..738dbde2 100644 --- a/verifier/testreport.py +++ b/verifier/testreport.py @@ -654,6 +654,7 @@ def characterize_results_by_options(self, test_list, category): 'error_detail', 'ignorePunctuation', 'language_label', + 'languageDisplay', 'locale_label', 'locale', 'options', From e93e6228ee7fa50a81a5784077a2dafeaadeeca6 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Sat, 31 Aug 2024 20:25:06 -0500 Subject: [PATCH 23/26] Update README.md (#296) Site wide changes, see https://github.com/unicode-org/.github/issues/17 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5201cbcb..0e5e0d58 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,6 @@ package was delivered in October, 2022. Copyright © 2022-2024 Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries. -The project is released under [LICENSE](./LICENSE). - A CLA is required to contribute to this project - please refer to the [CONTRIBUTING.md](https://github.com/unicode-org/.github/blob/main/.github/CONTRIBUTING.md) file (or start a Pull Request) for more information. + +The contents of this repository are governed by the Unicode [Terms of Use](https://www.unicode.org/copyright.html) and are released under [LICENSE](./LICENSE). From 71ef18612c47cf4e14f85293fbdc3462b55dec14 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Thu, 5 Sep 2024 15:36:53 -0700 Subject: [PATCH 24/26] Add missing plural rules ordinals test data for ICU75 (#298) --- testgen/icu75/ordinals.xml | 176 +++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 testgen/icu75/ordinals.xml diff --git a/testgen/icu75/ordinals.xml b/testgen/icu75/ordinals.xml new file mode 100644 index 00000000..58f7b016 --- /dev/null +++ b/testgen/icu75/ordinals.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + @integer 0~15, 100, 1000, 10000, 100000, 1000000, … + + + + + + n % 10 = 1,2 and n % 100 != 11,12 @integer 1, 2, 21, 22, 31, 32, 41, 42, 51, 52, 61, 62, 71, 72, 81, 82, 101, 1001, … + @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … + + + n = 1 @integer 1 + @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … + + + n = 1,5 @integer 1, 5 + @integer 0, 2~4, 6~17, 100, 1000, 10000, 100000, 1000000, … + + + n = 1..4 @integer 1~4 + @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … + + + + + + n % 10 = 2,3 and n % 100 != 12,13 @integer 2, 3, 22, 23, 32, 33, 42, 43, 52, 53, 62, 63, 72, 73, 82, 83, 102, 1002, … + @integer 0, 1, 4~17, 100, 1000, 10000, 100000, 1000000, … + + + n % 10 = 3 and n % 100 != 13 @integer 3, 23, 33, 43, 53, 63, 73, 83, 103, 1003, … + @integer 0~2, 4~16, 100, 1000, 10000, 100000, 1000000, … + + + n % 10 = 6,9 or n = 10 @integer 6, 9, 10, 16, 19, 26, 29, 36, 39, 106, 1006, … + @integer 0~5, 7, 8, 11~15, 17, 18, 20, 100, 1000, 10000, 100000, 1000000, … + + + + + + n % 10 = 6 or n % 10 = 9 or n % 10 = 0 and n != 0 @integer 6, 9, 10, 16, 19, 20, 26, 29, 30, 36, 39, 40, 100, 1000, 10000, 100000, 1000000, … + @integer 0~5, 7, 8, 11~15, 17, 18, 21, 101, 1001, … + + + n = 11,8,80,800 @integer 8, 11, 80, 800 + @integer 0~7, 9, 10, 12~17, 100, 1000, 10000, 100000, 1000000, … + + + n = 11,8,80..89,800..899 @integer 8, 11, 80~89, 800~803 + @integer 0~7, 9, 10, 12~17, 100, 1000, 10000, 100000, 1000000, … + + + + + + i = 1 @integer 1 + i = 0 or i % 100 = 2..20,40,60,80 @integer 0, 2~16, 102, 1002, … + @integer 21~36, 100, 1000, 10000, 100000, 1000000, … + + + n = 1 @integer 1 + n % 10 = 4 and n % 100 != 14 @integer 4, 24, 34, 44, 54, 64, 74, 84, 104, 1004, … + @integer 0, 2, 3, 5~17, 100, 1000, 10000, 100000, 1000000, … + + + n = 1..4 or n % 100 = 1..4,21..24,41..44,61..64,81..84 @integer 1~4, 21~24, 41~44, 61~64, 101, 1001, … + n = 5 or n % 100 = 5 @integer 5, 105, 205, 305, 405, 505, 605, 705, 1005, … + @integer 0, 6~20, 100, 1000, 10000, 100000, 1000000, … + + + + + + n % 10 = 1 and n % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … + n % 10 = 2 and n % 100 != 12 @integer 2, 22, 32, 42, 52, 62, 72, 82, 102, 1002, … + n % 10 = 3 and n % 100 != 13 @integer 3, 23, 33, 43, 53, 63, 73, 83, 103, 1003, … + @integer 0, 4~18, 100, 1000, 10000, 100000, 1000000, … + + + n = 1 @integer 1 + n = 2,3 @integer 2, 3 + n = 4 @integer 4 + @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … + + + n = 1,11 @integer 1, 11 + n = 2,12 @integer 2, 12 + n = 3,13 @integer 3, 13 + @integer 0, 4~10, 14~21, 100, 1000, 10000, 100000, 1000000, … + + + n = 1,3 @integer 1, 3 + n = 2 @integer 2 + n = 4 @integer 4 + @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … + + + + + + i % 10 = 1 and i % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … + i % 10 = 2 and i % 100 != 12 @integer 2, 22, 32, 42, 52, 62, 72, 82, 102, 1002, … + i % 10 = 7,8 and i % 100 != 17,18 @integer 7, 8, 27, 28, 37, 38, 47, 48, 57, 58, 67, 68, 77, 78, 87, 88, 107, 1007, … + @integer 0, 3~6, 9~19, 100, 1000, 10000, 100000, 1000000, … + + + + + + i % 10 = 1,2,5,7,8 or i % 100 = 20,50,70,80 @integer 1, 2, 5, 7, 8, 11, 12, 15, 17, 18, 20~22, 25, 101, 1001, … + i % 10 = 3,4 or i % 1000 = 100,200,300,400,500,600,700,800,900 @integer 3, 4, 13, 14, 23, 24, 33, 34, 43, 44, 53, 54, 63, 64, 73, 74, 100, 1003, … + i = 0 or i % 10 = 6 or i % 100 = 40,60,90 @integer 0, 6, 16, 26, 36, 40, 46, 56, 106, 1006, … + @integer 9, 10, 19, 29, 30, 39, 49, 59, 69, 79, 109, 1000, 10000, 100000, 1000000, … + + + + + + i = 0 @integer 0 + i = 1 @integer 1 + i = 2,3,4,5,6 @integer 2~6 + @integer 7~19, 100, 1000, 10000, 100000, 1000000, … + + + + + + n = 1 @integer 1 + n = 2,3 @integer 2, 3 + n = 4 @integer 4 + n = 6 @integer 6 + @integer 0, 5, 7~20, 100, 1000, 10000, 100000, 1000000, … + + + n = 1,5,7,8,9,10 @integer 1, 5, 7~10 + n = 2,3 @integer 2, 3 + n = 4 @integer 4 + n = 6 @integer 6 + @integer 0, 11~25, 100, 1000, 10000, 100000, 1000000, … + + + n = 1,5,7..9 @integer 1, 5, 7~9 + n = 2,3 @integer 2, 3 + n = 4 @integer 4 + n = 6 @integer 6 + @integer 0, 10~24, 100, 1000, 10000, 100000, 1000000, … + + + + + + n = 0,7,8,9 @integer 0, 7~9 + n = 1 @integer 1 + n = 2 @integer 2 + n = 3,4 @integer 3, 4 + n = 5,6 @integer 5, 6 + @integer 10~25, 100, 1000, 10000, 100000, 1000000, … + + + From f33de0bc807a090ffd0c0da2577f79ac5d1db455 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Tue, 17 Sep 2024 14:43:15 -0700 Subject: [PATCH 25/26] Remove 'und' as a locale in testing (#301) --- testgen/generators/datetime_gen.js | 11 ++++++----- testgen/generators/list_fmt_gen.js | 17 +++++++++-------- testgen/generators/rdt_fmt_gen.js | 3 ++- verifier/testreport.py | 3 +++ 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/testgen/generators/datetime_gen.js b/testgen/generators/datetime_gen.js index 625de31c..4c76fb13 100644 --- a/testgen/generators/datetime_gen.js +++ b/testgen/generators/datetime_gen.js @@ -31,13 +31,14 @@ let use_milliseconds = false; const numbering_systems = ['latn', 'arab', 'beng'] // ICU4X locales, maybe 20 +// Don't include "und" as a locale because the behavior depends on the platform. const locales = [ 'en-US', 'en-GB', 'zh-TW', 'vi', 'ar', 'mt-MT', - 'bn', 'zu', - 'und']; + 'bn', 'zu' +]: -// maybe 10 calendars + // maybe 10 calendars const calendars = ['gregory', 'buddhist', 'hebrew', 'chinese', 'roc', 'japanese', 'islamic', 'islamic-umalqura', 'persian' @@ -246,11 +247,11 @@ const dt_fields = { }, 'minute': { 'numeric': 'm', - // '2-digit': 'mm' + // '2-digit': 'mm' }, 'second': { 'numeric': 's', -// '2-digit': 'ss' + // '2-digit': 'ss' }, 'fractionalSecondDigits': { 1:'S', 2:'SS', 3:'SSS'}, diff --git a/testgen/generators/list_fmt_gen.js b/testgen/generators/list_fmt_gen.js index b278bca9..ea2a8e2f 100644 --- a/testgen/generators/list_fmt_gen.js +++ b/testgen/generators/list_fmt_gen.js @@ -14,10 +14,11 @@ const fs = require('node:fs'); let debug = false; -const locales = ['und', - 'en-US', 'zh-TW', 'es', - 'pt', 'vi', 'el', 'mt-MT', 'ru', 'en-GB', - 'bn', 'ar','mr', 'zu']; +// Don't include "und" as a locale because the behavior depends on the platform. +const locales = [ + 'en-US', 'zh-TW', 'es', + 'pt', 'vi', 'el', 'mt-MT', 'ru', 'en-GB', + 'bn', 'ar','mr', 'zu']; const types = ['conjunction', 'disjunction', 'unit']; @@ -122,11 +123,11 @@ function generateAll() { // TODO: Save this as a test case. let test_list; let test_case = { - 'input_list': list, - 'options': {...all_options} - }; + 'input_list': list, + 'options': {...all_options} + }; gen_hash.generate_hash_for_test(test_case); - test_case['label'] = label_string; + test_case['label'] = label_string; if (locale != '') { test_case["locale"] = locale; diff --git a/testgen/generators/rdt_fmt_gen.js b/testgen/generators/rdt_fmt_gen.js index 3d319445..4b5c92ee 100644 --- a/testgen/generators/rdt_fmt_gen.js +++ b/testgen/generators/rdt_fmt_gen.js @@ -21,11 +21,12 @@ const debug = false; // Add numbering system to the test options const numbering_systems = [null, 'latn', 'arab', 'beng', 'adlm'] +// Don't include "und" as a locale because the behavior depends on the platform. const locales = [ 'en-US', 'en-GB', 'zh-TW', 'vi', 'el', 'mt-MT', 'bn', 'zu', - 'und']; +]; const spec_options = [null, {'style': 'long'}, diff --git a/verifier/testreport.py b/verifier/testreport.py index 738dbde2..2b513b7b 100644 --- a/verifier/testreport.py +++ b/verifier/testreport.py @@ -589,6 +589,9 @@ def characterize_results_by_options(self, test_list, category): for test in test_list: # Get input_data, if available input_data = test.get('input_data', None) + if not input_data: + # Why no data? + continue label = test.get('label', '') From f89ea86ee992e8eb7d218565b2136ee76feb8b33 Mon Sep 17 00:00:00 2001 From: Craig Cornelius Date: Tue, 17 Sep 2024 15:47:47 -0700 Subject: [PATCH 26/26] Fix dumb typo (#304) --- testgen/generators/datetime_gen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgen/generators/datetime_gen.js b/testgen/generators/datetime_gen.js index 4c76fb13..abd10ace 100644 --- a/testgen/generators/datetime_gen.js +++ b/testgen/generators/datetime_gen.js @@ -36,7 +36,7 @@ const locales = [ 'en-US', 'en-GB', 'zh-TW', 'vi', 'ar', 'mt-MT', 'bn', 'zu' -]: +]; // maybe 10 calendars const calendars = ['gregory',
' + output +'' + output +'