2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2025-02-28 12:15:49 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 - 2025 ,  Tim  Flynn  < trflynn89 @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/AllOf.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Find.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <AK/QuickSort.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/TypeCasts.h> 
  
						 
					
						
							
								
									
										
										
										
											2025-02-28 12:15:49 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/AbstractOperations.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Array.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/GlobalObject.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Intl/AbstractOperations.h> 
  
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Intl/IntlObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Intl/Locale.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-06-17 16:24:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Intl/SingleUnitIdentifiers.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/VM.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-10-06 17:54:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/ValueInlines.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-06-25 11:06:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibUnicode/TimeZone.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibUnicode/UnicodeKeywords.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS : : Intl  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Optional < LocaleKey >  locale_key_from_value ( Value  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_undefined ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  OptionalNone  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . as_string ( ) . utf8_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-25 10:07:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 6.2.1 IsStructurallyValidLanguageTag ( locale ), https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag
  
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_structurally_valid_language_tag ( StringView  locale )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-08-22 15:39:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  contains_duplicate_variant  =  [ & ] ( auto &  variants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 14:46:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( variants . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        quick_sort ( variants ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  variants . size ( )  -  1 ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-08 13:03:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( variants [ i ] . equals_ignoring_case ( variants [ i  +  1 ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 14:46:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. Let lowerLocale be the ASCII-lowercase of locale.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: LibUnicode's parsing is case-insensitive.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. If lowerLocale cannot be matched by the unicode_locale_id Unicode locale nonterminal, return false.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  locale_id  =  Unicode : : parse_unicode_locale_id ( locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( ! locale_id . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. If lowerLocale uses any of the backwards compatibility syntax described in Unicode Technical Standard #35 Part 1 Core,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    Section 3.3 BCP 47 Conformance, return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    https://unicode.org/reports/tr35/#BCP_47_Conformance
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( locale . contains ( ' _ ' )  | |  locale_id - > language_id . is_root  | |  ! locale_id - > language_id . language . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Let languageId be the longest prefix of lowerLocale matched by the unicode_language_id Unicode locale nonterminal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  language_id  =  locale_id - > language_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let variants be GetLocaleVariants(languageId).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. If variants is not undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto &  variants  =  language_id . variants ;  ! variants . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If variants contains any duplicate subtags, return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( contains_duplicate_variant ( variants ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    HashTable < char >  unique_keys ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Let allExtensions be the suffix of lowerLocale following languageId.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. If allExtensions contains a substring matched by the pu_extensions Unicode locale nonterminal, let extensions be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    the prefix of allExtensions preceding the longest such substring. Otherwise, let extensions be allExtensions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. If extensions is not the empty String, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 14:46:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  extension  :  locale_id - > extensions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        char  key  =  extension . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ ] ( Unicode : : LocaleExtension  const & )  {  return  ' u ' ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ ] ( Unicode : : TransformedExtension  const & )  {  return  ' t ' ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ ] ( Unicode : : OtherExtension  const &  ext )  {  return  static_cast < char > ( to_ascii_lowercase ( ext . key ) ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 14:46:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. If extensions contains any duplicate singleton subtags, return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( unique_keys . set ( key )  ! =  HashSetResult : : InsertedNewEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 14:46:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. Let transformExtension be the longest substring of extensions matched by the transformed_extensions Unicode
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //    locale nonterminal. If there is no such substring, return true.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  transformed  =  extension . get_pointer < Unicode : : TransformedExtension > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // c. Assert: The substring of transformExtension from 0 to 3 is "-t-".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // d. Let tPrefix be the substring of transformExtension from 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // e. Let tlang be the longest prefix of tPrefix matched by the tlang Unicode locale nonterminal. If there is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //    no such prefix, return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  transformed_language  =  transformed - > language ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! transformed_language . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // f. Let tlangRefinements be the longest suffix of tlang following a non-empty prefix matched by the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //    unicode_language_subtag Unicode locale nonterminal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  transformed_refinements  =  transformed_language - > variants ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // g. If tlangRefinements contains any duplicate substrings matched greedily by the unicode_variant_subtag
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //    Unicode locale nonterminal, return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( contains_duplicate_variant ( transformed_refinements ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 10. Return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-25 10:07:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 6.2.2 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
  
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  canonicalize_unicode_locale_id ( StringView  locale )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Unicode : : canonicalize_unicode_locale_id ( locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 09:53:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-iswellformedcurrencycode
  
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_well_formed_currency_code ( StringView  currency )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-28 09:53:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. If the length of currency is not 3, return false.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( currency . length ( )  ! =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 09:53:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let normalized be the ASCII-uppercase of currency.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If normalized contains any code unit outside of 0x0041 through 0x005A (corresponding to Unicode characters LATIN CAPITAL LETTER A through LATIN CAPITAL LETTER Z), return false.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( ! all_of ( currency ,  is_ascii_alpha ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-25 11:06:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 6.5.1 AvailableNamedTimeZoneIdentifiers ( ), https://tc39.es/ecma402/#sup-availablenamedtimezoneidentifiers
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Vector < TimeZoneIdentifier >  const &  available_named_time_zone_identifiers ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // It is recommended that the result of AvailableNamedTimeZoneIdentifiers remains the same for the lifetime of the surrounding agent.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  auto  named_time_zone_identifiers  =  [ ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let identifiers be a List containing the String value of each Zone or Link name in the IANA Time Zone Database.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  identifiers  =  Unicode : : available_time_zones ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Assert: No element of identifiers is an ASCII-case-insensitive match for any other element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 3. Assert: Every element of identifiers identifies a Zone or Link name in the IANA Time Zone Database.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 4. Sort identifiers according to lexicographic code unit order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: All of the above is handled by LibUnicode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 5. Let result be a new empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Vector < TimeZoneIdentifier >  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . ensure_capacity ( identifiers . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  found_utc  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 6. For each element identifier of identifiers, do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  const &  identifier  :  identifiers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // a. Let primary be identifier.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  primary  =  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // b. If identifier is a Link name and identifier is not "UTC", then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( identifier  ! =  " UTC " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  resolved  =  Unicode : : resolve_primary_time_zone ( identifier ) ;  resolved . has_value ( )  & &  identifier  ! =  resolved )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // i. Set primary to the Zone name that identifier resolves to, according to the rules for resolving Link
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    //    names in the IANA Time Zone Database.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    primary  =  resolved . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // ii. NOTE: An implementation may need to resolve identifier iteratively.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // c. If primary is one of "Etc/UTC", "Etc/GMT", or "GMT", set primary to "UTC".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( primary . is_one_of ( " Etc/UTC " sv ,  " Etc/GMT " sv ,  " GMT " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                primary  =  " UTC " _string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // d. Let record be the Time Zone Identifier Record { [[Identifier]]: identifier, [[PrimaryIdentifier]]: primary }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TimeZoneIdentifier  record  {  . identifier  =  identifier ,  . primary_identifier  =  primary  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // e. Append record to result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            result . unchecked_append ( move ( record ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! found_utc  & &  identifier  = =  " UTC " sv  & &  primary  = =  " UTC " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                found_utc  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 7. Assert: result contains a Time Zone Identifier Record r such that r.[[Identifier]] is "UTC" and r.[[PrimaryIdentifier]] is "UTC".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( found_utc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 8. Return result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  named_time_zone_identifiers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 6.5.2 GetAvailableNamedTimeZoneIdentifier ( timeZoneIdentifier ), https://tc39.es/ecma402/#sec-getavailablenamedtimezoneidentifier
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < TimeZoneIdentifier  const & >  get_available_named_time_zone_identifier ( StringView  time_zone_identifier )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. For each element record of AvailableNamedTimeZoneIdentifiers(), do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  record  :  available_named_time_zone_identifiers ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If record.[[Identifier]] is an ASCII-case-insensitive match for timeZoneIdentifier, return record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( record . identifier . equals_ignoring_ascii_case ( time_zone_identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  record ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Return EMPTY.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-25 10:07:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 6.6.1 IsWellFormedUnitIdentifier ( unitIdentifier ), https://tc39.es/ecma402/#sec-iswellformedunitidentifier
  
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_well_formed_unit_identifier ( StringView  unit_identifier )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-25 10:07:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6.6.2 IsSanctionedSingleUnitIdentifier ( unitIdentifier ), https://tc39.es/ecma402/#sec-issanctionedsingleunitidentifier
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    constexpr  auto  is_sanctioned_single_unit_identifier  =  [ ] ( StringView  unit_identifier )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 1. If unitIdentifier is listed in Table 2 below, return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Else, return false.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        static  constexpr  auto  sanctioned_units  =  sanctioned_single_unit_identifiers ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  find ( sanctioned_units . begin ( ) ,  sanctioned_units . end ( ) ,  unit_identifier )  ! =  sanctioned_units . end ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. If ! IsSanctionedSingleUnitIdentifier(unitIdentifier) is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_sanctioned_single_unit_identifier ( unit_identifier ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let i be StringIndexOf(unitIdentifier, "-per-", 0).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  indices  =  unit_identifier . find_all ( " -per- " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. If i is -1 or StringIndexOf(unitIdentifier, "-per-", i + 1) is not -1, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( indices . size ( )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. Assert: The five-character substring "-per-" occurs exactly once in unitIdentifier, at index i.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: We skip this because the indices vector being of size 1 already verifies this invariant.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let numerator be the substring of unitIdentifier from 0 to i.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  numerator  =  unit_identifier . substring_view ( 0 ,  indices [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. Let denominator be the substring of unitIdentifier from i + 5.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  denominator  =  unit_identifier . substring_view ( indices [ 0 ]  +  5 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. If ! IsSanctionedSingleUnitIdentifier(numerator) and ! IsSanctionedSingleUnitIdentifier(denominator) are both true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_sanctioned_single_unit_identifier ( numerator )  & &  is_sanctioned_single_unit_identifier ( denominator ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 12:05:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist
  
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < Vector < String > >  canonicalize_locale_list ( VM &  vm ,  Value  locales )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If locales is undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( locales . is_undefined ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Return a new empty List.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Vector < String >  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let seen be a new empty List.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < String >  seen ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Object *  object  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( locales . is_string ( )  | |  ( locales . is_object ( )  & &  is < Locale > ( locales . as_object ( ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let O be CreateArrayFromList(« locales »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        object  =  Array : : create_from ( realm ,  {  locales  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let O be ? ToObject(locales).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-21 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        object  =  TRY ( locales . to_object ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let len be ? ToLength(? Get(O, "length")).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-17 23:57:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  length_value  =  TRY ( object - > get ( vm . names . length ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-21 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  length  =  TRY ( length_value . to_length ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let k be 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Repeat, while k < len,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  k  =  0 ;  k  <  length ;  + + k )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let Pk be ToString(k).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  property_key  =  PropertyKey  {  k  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Let kPresent be ? HasProperty(O, Pk).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 02:00:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  key_present  =  TRY ( object - > has_property ( property_key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. If kPresent is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( key_present )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let kValue be ? Get(O, Pk).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  key_value  =  TRY ( object - > get ( property_key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. If Type(kValue) is not String or Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 19:24:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! key_value . is_string ( )  & &  ! key_value . is_object ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  vm . throw_completion < TypeError > ( ErrorType : : NotAnObjectOrString ,  key_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            String  tag ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( key_value . is_object ( )  & &  is < Locale > ( key_value . as_object ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Let tag be kValue.[[Locale]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tag  =  static_cast < Locale  const & > ( key_value . as_object ( ) ) . locale ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // iv. Else,
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Let tag be ? ToString(kValue).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                tag  =  TRY ( key_value . to_string ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:26:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 08:30:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! is_structurally_valid_language_tag ( tag ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 20:33:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  vm . throw_completion < RangeError > ( ErrorType : : IntlInvalidLanguageTag ,  tag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 08:30:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // vi. Let canonicalizedTag be ! CanonicalizeUnicodeLocaleId(tag).
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  canonicalized_tag  =  canonicalize_unicode_locale_id ( tag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // vii. If canonicalizedTag is not an element of seen, append canonicalizedTag as the last element of seen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! seen . contains_slow ( canonicalized_tag ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 11:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                seen . append ( move ( canonicalized_tag ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Increase k by 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Return seen.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  seen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.3 LookupMatchingLocaleByPrefix ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupmatchinglocalebyprefix
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < MatchedLocale >  lookup_matching_locale_by_prefix ( ReadonlySpan < String >  requested_locales )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. For each element locale of requestedLocales, do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  locale  :  requested_locales )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  locale_id  =  Unicode : : parse_unicode_locale_id ( locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( locale_id . has_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let extension be empty.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Optional < Unicode : : Extension >  extension ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        String  locale_without_extension ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. If locale contains a Unicode locale extension sequence, then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto  extensions  =  locale_id - > remove_extension_type < Unicode : : LocaleExtension > ( ) ;  ! extensions . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( extensions . size ( )  = =  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Set extension to the Unicode locale extension sequence of locale.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            extension  =  extensions . take_first ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // ii. Set locale to the String value that is locale with any Unicode locale extension sequences removed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            locale  =  locale_id - > to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // c. Let prefix be locale.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        StringView  prefix  {  locale  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // d. Repeat, while prefix is not the empty String,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ! prefix . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. If availableLocales contains prefix, return the Record { [[locale]]: prefix, [[extension]]: extension }.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( Unicode : : is_locale_available ( prefix ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  MatchedLocale  {  MUST ( String : : from_utf8 ( prefix ) ) ,  move ( extension )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // ii. If prefix contains "-" (code unit 0x002D HYPHEN-MINUS), let pos be the index into prefix of the last
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //     occurrence of "-"; else let pos be 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  position  =  prefix . find_last ( ' - ' ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Repeat, while pos ≥ 2 and the substring of prefix from pos - 2 to pos - 1 is "-",
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            while  ( position  > =  2  & &  prefix . substring_view ( position  -  2 ,  1 )  = =  ' - ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Set pos to pos - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                position  - =  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // iv. Set prefix to the substring of prefix from 0 to pos.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            prefix  =  prefix . substring_view ( 0 ,  position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.4 LookupMatchingLocaleByBestFit ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupmatchinglocalebybestfit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < MatchedLocale >  lookup_matching_locale_by_best_fit ( ReadonlySpan < String >  requested_locales )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // The algorithm is implementation dependent, but should produce results that a typical user of the requested locales
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // would consider at least as good as those produced by the LookupMatchingLocaleByPrefix algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  lookup_matching_locale_by_prefix ( requested_locales ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, attributes, keywords ), https://tc39.es/ecma402/#sec-insert-unicode-extension-and-canonicalize
  
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  insert_unicode_extension_and_canonicalize ( Unicode : : LocaleID  locale ,  Vector < String >  attributes ,  Vector < Unicode : : Keyword >  keywords )  
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: This implementation differs from the spec in how the extension is inserted. The spec assumes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // the input to this method is a string, and is written such that operations are performed on parts
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // of that string. LibUnicode gives us the parsed locale in a structure, so we can mutate that
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // structure directly.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    locale . extensions . append ( Unicode : : LocaleExtension  {  move ( attributes ) ,  move ( keywords )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 11:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 10. Return CanonicalizeUnicodeLocaleId(newLocale).
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-08 11:22:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  JS : : Intl : : canonicalize_unicode_locale_id ( locale . to_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  auto &  find_key_in_value ( T &  value ,  StringView  key )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-28 17:55:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( key  = =  " ca " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . ca ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 11:30:46 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( key  = =  " co " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . co ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 17:55:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( key  = =  " hc " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . hc ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-29 11:30:46 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( key  = =  " kf " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . kf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( key  = =  " kn " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . kn ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( key  = =  " nu " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . nu ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // If you hit this point, you must add any missing keys from [[RelevantExtensionKeys]] to LocaleOptions and ResolvedLocale.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Vector < LocaleKey >  available_keyword_values ( StringView  locale ,  StringView  key )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  key_locale_data  =  Unicode : : available_keyword_values ( locale ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < LocaleKey >  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result . ensure_capacity ( key_locale_data . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  keyword  :  key_locale_data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . unchecked_append ( move ( keyword ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( key  = =  " hc " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // https://tc39.es/ecma402/#sec-intl.datetimeformat-internal-slots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // [[LocaleData]].[[<locale>]].[[hc]] must be « null, "h11", "h12", "h23", "h24" ».
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . prepend ( Empty  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ), https://tc39.es/ecma402/#sec-resolvelocale
  
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ResolvedLocale  resolve_locale ( ReadonlySpan < String >  requested_locales ,  LocaleOptions  const &  options ,  ReadonlySpan < StringView >  relevant_extension_keys )  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  auto  true_string  =  " true " _string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // 1. Let matcher be options.[[localeMatcher]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const &  matcher  =  options . locale_matcher ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < MatchedLocale >  matcher_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If matcher is "lookup", then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( matcher . is_string ( )  & &  matcher . as_string ( ) . utf8_string_view ( )  = =  " lookup " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let r be LookupMatchingLocaleByPrefix(availableLocales, requestedLocales).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        matcher_result  =  lookup_matching_locale_by_prefix ( requested_locales ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let r be LookupMatchingLocaleByBestFit(availableLocales, requestedLocales).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        matcher_result  =  lookup_matching_locale_by_best_fit ( requested_locales ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. If r is undefined, set r to the Record { [[locale]]: DefaultLocale(), [[extension]]: empty }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! matcher_result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        matcher_result  =  MatchedLocale  {  MUST ( String : : from_utf8 ( Unicode : : default_locale ( ) ) ) ,  { }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let foundLocale be r.[[locale]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  found_locale  =  move ( matcher_result - > locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. Let foundLocaleData be localeData.[[<foundLocale>]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Assert: Type(foundLocaleData) is Record.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Let result be a new Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. Set result.[[LocaleData]] to foundLocaleData.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ResolvedLocale  result  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < Unicode : : Keyword >  keywords ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 10. If r.[[extension]] is not empty, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( matcher_result - > extension . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let components be UnicodeExtensionComponents(r.[[extension]]).
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  components  =  matcher_result - > extension - > get < Unicode : : LocaleExtension > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. Let keywords be components.[[Keywords]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        keywords  =  move ( components . keywords ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 11. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     a. Let keywords be a new empty List.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 12. Let supportedKeywords be a new empty List.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < Unicode : : Keyword >  supported_keywords ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-17 16:24:09 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < Unicode : : Keyword >  icu_keywords ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 13. For each element key of relevantExtensionKeys, do
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  key  :  relevant_extension_keys )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let keyLocaleData be foundLocaleData.[[<key>]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Assert: keyLocaleData is a List.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  key_locale_data  =  available_keyword_values ( found_locale ,  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // c. Let value be keyLocaleData[0].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Assert: value is a String or value is null.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-15 20:23:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  value  =  key_locale_data [ 0 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // e. Let supportedKeyword be empty.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Optional < Unicode : : Keyword >  supported_keyword ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // f. If keywords contains an element whose [[Key]] is key, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  entry  =  keywords . find_if ( [ & ] ( auto  const &  entry )  {  return  entry . key  = =  key ;  } ) ;  entry  ! =  keywords . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let entry be the element of keywords whose [[Key]] is key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Let requestedValue be entry.[[Value]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  requested_value  =  entry - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // iii. If requestedValue is not the empty String, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! requested_value . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 1. If keyLocaleData contains requestedValue, then
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( key_locale_data . contains_slow ( requested_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // a. Set value to requestedValue.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    value  =  move ( requested_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // b. Set supportedKeyword to the Record { [[Key]]: key, [[Value]]: value }.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    supported_keyword  =  Unicode : : Keyword  {  MUST ( String : : from_utf8 ( key ) ) ,  move ( entry - > value )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // iv. Else if keyLocaleData contains "true", then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else  if  ( key_locale_data . contains_slow ( true_string ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 1. Set value to "true".
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                value  =  true_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 2. Set supportedKeyword to the Record { [[Key]]: key, [[Value]]: "" }.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                supported_keyword  =  Unicode : : Keyword  {  MUST ( String : : from_utf8 ( key ) ) ,  { }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // g. Assert: options has a field [[<key>]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // h. Let optionsValue be options.[[<key>]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Assert: optionsValue is a String, or optionsValue is either undefined or null.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  options_value  =  find_key_in_value ( options ,  key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // j. If optionsValue is a String, then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  options_string  =  options_value . has_value ( )  ?  options_value - > get_pointer < String > ( )  :  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Let ukey be the ASCII-lowercase of key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // NOTE: `key` is always lowercase, and this step is likely to be removed:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //        https://github.com/tc39/ecma402/pull/846#discussion_r1428263375
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Set optionsValue to CanonicalizeUValue(ukey, optionsValue).
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            * options_string  =  Unicode : : canonicalize_unicode_extension_values ( key ,  * options_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // iii. If optionsValue is the empty String, then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( options_string - > is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 1. Set optionsValue to "true".
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-16 15:36:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                * options_string  =  true_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // k. If SameValue(optionsValue, value) is false and keyLocaleData contains optionsValue, then
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 10:53:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( options_value . has_value ( )  & &  ( options_value  ! =  value )  & &  key_locale_data . contains_slow ( * options_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Set value to optionsValue.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-15 20:23:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value  =  options_value . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 10:53:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // ii. Set supportedKeyword to empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            supported_keyword . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // l. If supportedKeyword is not empty, append supportedKeyword to supportedKeywords.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( supported_keyword . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            supported_keywords . append ( supported_keyword . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-17 16:24:09 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  value_string  =  value . get_pointer < String > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            icu_keywords . empend ( MUST ( String : : from_utf8 ( key ) ) ,  * value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // m. Set result.[[<key>]] to value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        find_key_in_value ( result ,  key )  =  move ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-17 16:24:09 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // AD-HOC: For ICU, we need to form a locale with all relevant extension keys present.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( icu_keywords . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . icu_locale  =  found_locale ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  locale_id  =  Unicode : : parse_unicode_locale_id ( found_locale ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( locale_id . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . icu_locale  =  insert_unicode_extension_and_canonicalize ( locale_id . release_value ( ) ,  { } ,  move ( icu_keywords ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 14. If supportedKeywords is not empty, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! supported_keywords . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-23 09:14:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  locale_id  =  Unicode : : parse_unicode_locale_id ( found_locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( locale_id . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let supportedAttributes be a new empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Set foundLocale to InsertUnicodeExtensionAndCanonicalize(foundLocale, supportedAttributes, supportedKeywords).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        found_locale  =  insert_unicode_extension_and_canonicalize ( locale_id . release_value ( ) ,  { } ,  move ( supported_keywords ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 10:01:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 15. Set result.[[Locale]] to foundLocale.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 08:51:52 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    result . locale  =  move ( found_locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 16. Return result.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.8 ResolveOptions ( constructor, localeData, locales, options [ , specialBehaviours [ , modifyResolutionOptions ] ] ), https://tc39.es/ecma402/#sec-resolveoptions
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < ResolvedOptions >  resolve_options ( VM &  vm ,  IntlObject &  object ,  Value  locales ,  Value  options_value ,  SpecialBehaviors  special_behaviours ,  Function < void ( LocaleOptions & ) >  modify_resolution_options )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  requested_locales  =  TRY ( canonicalize_locale_list ( vm ,  locales ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If specialBehaviours is present and contains REQUIRE-OPTIONS and options is undefined, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_flag ( special_behaviours ,  SpecialBehaviors : : RequireOptions )  & &  options_value . is_undefined ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  vm . throw_completion < TypeError > ( ErrorType : : IsUndefined ,  " options " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If specialBehaviours is present and contains COERCE-OPTIONS, set options to ? CoerceOptionsToObject(options).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    Otherwise, set options to ? GetOptionsObject(options).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    GC : : Ref < Object >  options  =  has_flag ( special_behaviours ,  SpecialBehaviors : : CoerceOptions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ?  * TRY ( coerce_options_to_object ( vm ,  options_value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  * TRY ( get_options_object ( vm ,  options_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  matcher  =  TRY ( get_option ( vm ,  options ,  vm . names . localeMatcher ,  OptionType : : String ,  {  " lookup " sv ,  " best fit " sv  } ,  " best fit " sv ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let opt be the Record { [[localeMatcher]]: matcher }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LocaleOptions  opt  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    opt . locale_matcher  =  matcher ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. For each Resolution Option Descriptor desc of constructor.[[ResolutionOptionDescriptors]], do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  descriptor  :  object . resolution_option_descriptors ( vm ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If desc has a [[Type]] field, let type be desc.[[Type]]. Otherwise, let type be STRING.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  type  =  descriptor . type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. If desc has a [[Values]] field, let values be desc.[[Values]]. Otherwise, let values be EMPTY.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  values  =  descriptor . values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Let value be ? GetOption(options, desc.[[Property]], type, values, undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  TRY ( get_option ( vm ,  options ,  descriptor . property ,  type ,  values ,  Empty  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Optional < LocaleKey >  locale_key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. If value is not undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! value . is_undefined ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Set value to ! ToString(value).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value_string  =  MUST ( value . to_string ( vm ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. If value cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! Unicode : : is_type_identifier ( value_string ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  vm . throw_completion < RangeError > ( ErrorType : : OptionIsNotValidValue ,  value_string ,  descriptor . property ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            locale_key  =  move ( value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // e. Let key be desc.[[Key]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  key  =  descriptor . key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // f. Set opt.[[<key>]] to value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( descriptor . property  = =  vm . names . hour12 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            opt . hour12  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            find_key_in_value ( opt ,  key )  =  move ( locale_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. If modifyResolutionOptions is present, perform ! modifyResolutionOptions(opt).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( modify_resolution_options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        modify_resolution_options ( opt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. Let resolution be ResolveLocale(constructor.[[AvailableLocales]], requestedLocales, opt, constructor.[[RelevantExtensionKeys]], localeData).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  resolution  =  resolve_locale ( requested_locales ,  opt ,  object . relevant_extension_keys ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. Return the Record { [[Options]]: options, [[ResolvedLocale]]: resolution, [[ResolutionOptions]]: opt }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ResolvedOptions  {  . options  =  options ,  . resolved_locale  =  move ( resolution ) ,  . resolution_options  =  move ( opt )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 9.2.9 FilterLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-lookupsupportedlocales
  
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < Array * >  filter_locales ( VM &  vm ,  ReadonlySpan < String >  requested_locales ,  Value  options )  
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Set options to ? CoerceOptionsToObject(options).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  options_object  =  TRY ( coerce_options_to_object ( vm ,  options ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  matcher  =  TRY ( get_option ( vm ,  * options_object ,  vm . names . localeMatcher ,  OptionType : : String ,  {  " lookup " sv ,  " best fit " sv  } ,  " best fit " sv ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let subset be a new empty List.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-19 13:13:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < String >  subset ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. For each element locale of requestedLocales, do
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  locale  :  requested_locales )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Optional < MatchedLocale >  match ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. If matcher is "lookup", then
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( matcher . as_string ( ) . utf8_string_view ( )  = =  " lookup " sv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Let match be LookupMatchingLocaleByPrefix(availableLocales, « locale »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            match  =  lookup_matching_locale_by_prefix ( {  {  locale  }  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. Else,
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Let match be LookupMatchingLocaleByBestFit(availableLocales, « locale »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            match  =  lookup_matching_locale_by_best_fit ( {  {  locale  }  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-15 15:55:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // c. If match is not undefined, append locale to subset.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            subset . append ( locale ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-18 10:13:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Return CreateArrayFromList(subset).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  Array : : create_from < String > ( realm ,  subset ,  [ & vm ] ( auto &  locale )  {  return  PrimitiveString : : create ( vm ,  move ( locale ) ) ;  } ) . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.11 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
  
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < Object * >  coerce_options_to_object ( VM &  vm ,  Value  options )  
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. If options is undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( options . is_undefined ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Return OrdinaryObjectCreate(null).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 20:49:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Object : : create ( realm ,  nullptr ) . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Return ? ToObject(options).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 15:26:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY ( options . to_object ( vm ) ) . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 22:08:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NOTE: 9.2.12 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal.
  
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.13 GetBooleanOrStringNumberFormatOption ( options, property, stringValues, fallback ), https://tc39.es/ecma402/#sec-getbooleanorstringnumberformatoption
  
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < StringOrBoolean >  get_boolean_or_string_number_format_option ( VM &  vm ,  Object  const &  options ,  PropertyKey  const &  property ,  ReadonlySpan < StringView >  string_values ,  StringOrBoolean  fallback )  
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let value be ? Get(options, property).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  value  =  TRY ( options . get ( property ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If value is undefined, return fallback.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_undefined ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  fallback ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. If value is true, return true.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( value . is_boolean ( )  & &  value . as_bool ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  StringOrBoolean  {  true  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. If ToBoolean(value) is false, return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! value . to_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  StringOrBoolean  {  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let value be ? ToString(value).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 10:31:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value_string  =  TRY ( value . to_string ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. If stringValues does not contain value, throw a RangeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  it  =  find ( string_values . begin ( ) ,  string_values . end ( ) ,  value_string . bytes_as_string_view ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( it  = =  string_values . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-13 11:00:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  vm . throw_completion < RangeError > ( ErrorType : : OptionIsNotValidValue ,  value_string ,  property . as_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 10:36:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Return value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 13:18:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  StringOrBoolean  {  * it  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.14 DefaultNumberOption ( value, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-defaultnumberoption
  
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < Optional < int > >  default_number_option ( VM &  vm ,  Value  value ,  int  minimum ,  int  maximum ,  Optional < int >  fallback )  
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If value is undefined, return fallback.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_undefined ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  fallback ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-24 08:51:03 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Set value to ? ToNumber(value).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-21 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    value  =  TRY ( value . to_number ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If value is NaN or less than minimum or greater than maximum, throw a RangeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 19:37:39 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( value . is_nan ( )  | |  ( value . as_double ( )  <  minimum )  | |  ( value . as_double ( )  >  maximum ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 20:33:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  vm . throw_completion < RangeError > ( ErrorType : : IntlNumberIsNaNOrOutOfRange ,  value ,  minimum ,  maximum ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Return floor(value).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 19:17:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  floor ( value . as_double ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-07 16:40:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption
  
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < Optional < int > >  get_number_option ( VM &  vm ,  Object  const &  options ,  PropertyKey  const &  property ,  int  minimum ,  int  maximum ,  Optional < int >  fallback )  
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Assert: Type(options) is Object.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let value be ? Get(options, property).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value  =  TRY ( options . get ( property ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Return ? DefaultNumberOption(value, minimum, maximum, fallback).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 08:25:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  default_number_option ( vm ,  value ,  minimum ,  maximum ,  move ( fallback ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 11:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 22:58:45 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}