Stage 3 Draft / December 15, 2021

Intl Locale Info Proposal

Introduction

This proposal exposes Locale information, such as week data (first day in a week, weekend start day, weekend end day, minimun day in the first week), hour cycle used in the locale, measurement system used in the locale. See the README for more context.

1 Locale Objects

1.1 Abstract Operations for Locale Objects

1.1.1 CreateArrayFromListOrRestricted ( list , restricted )

The abstract operation CreateArrayFromListOrRestricted accepts the arguments list and restricted , and performs the following steps:

  1. If restricted is not undefined, then
    1. Set list to « restricted ».
  2. Return ! CreateArrayFromList( list ).

1.1.2 CalendarsOfLocale ( loc )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Let restricted be loc.[[Calendar]].
  2. Let locale be loc.[[Locale]].
  3. Assert: locale matches the unicode_locale_id production.
  4. Let list be a List of 1 or more unique canonical calendar identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for date and time formatting in locale.
  5. Return ! CreateArrayFromListOrRestricted( list, restricted ).

1.1.3 CollationsOfLocale ( loc )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Let restricted be loc.[[Collation]].
  2. Let locale be loc.[[Locale]].
  3. Assert: locale matches the unicode_locale_id production.
  4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
  5. Return ! CreateArrayFromListOrRestricted( list, restricted ).

1.1.4 HourCyclesOfLocale ( loc )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Let restricted be loc.[[HourCycle]].
  2. Let locale be loc.[[Locale]].
  3. Assert: locale matches the unicode_locale_id production.
  4. Let list be a List of 1 or more unique hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
  5. Return ! CreateArrayFromListOrRestricted( list, restricted ).

1.1.5 NumberingSystemsOfLocale ( loc )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Let restricted be loc.[[NumberingSystem]].
  2. Let locale be loc.[[Locale]].
  3. Assert: locale matches the unicode_locale_id production.
  4. Let list be a List of 1 or more unique canonical numbering system identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for formatting numeric values in locale.
  5. Return ! CreateArrayFromListOrRestricted( list, restricted ).

1.1.6 TimeZonesOfLocale ( loc )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Let locale be loc.[[Locale]].
  2. Assert: locale matches the unicode_locale_id production.
  3. Let region be the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
  4. Let list be a List of unique canonical time zone identifiers, which must be String values indicating a canonical Zone name of the IANA Time Zone Database, ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn, of those in common use in region. If no time zones are commonly used in region, let list be a new empty List.
  5. Return ! CreateArrayFromList( list ).

1.1.7 CharacterDirectionOfLocale ( loc )

The abstract operation CharacterDirectionOfLocale accepts the argument loc , and performs the following steps:

  1. Let locale be loc.[[Locale]].
  2. Assert: locale matches the unicode_locale_id production.
  3. If the default general ordering of characters (characterOrder) within a line in locale is right-to-left, return "rtl".
  4. Return "ltr".

1.1.8 WeekInfoOfLocale ( loc )

The abstract operation WeekInfoOfLocale accepts the argument loc , and performs the following steps:

  1. Let locale be loc.[[Locale]].
  2. Assert: locale matches the unicode_locale_id production.
  3. Return a record whose fields are defined by Table 1, with values based on locale.
Table 1: WeekInfo Record Fields
Field Name Value Meaning
[[FirstDay]] Integer value between 1 and 7: 1 specifies Monday; 2 specifies Tuesday; 3 specifies Wednesday; 4 specifies Thursday; 5 specifies Friday; 6 specifies Saturday; and 7 specifies Sunday. The weekday value indicating which day of the week is considered the 'first' day, for calendar purposes.
[[Weekend]] A List of 1 or more integer values, in ascending order, between 1 and 7: 1 specifies Monday; 2 specifies Tuesday; 3 specifies Wednesday; 4 specifies Thursday; 5 specifies Friday; 6 specifies Saturday; and 7 specifies Sunday. The list of weekday values indicating which days of the week are considered as part of the 'weekend', for calendar purposes. Notice that the number of days in the weekend are different in each locale and may not be contiguous.
[[MinimalDays]] Integer value between 1 and 7. The minimal days required in the first week of a month or year, for calendar purposes.

1.2 The Intl.Locale Constructor

The Locale constructor is the %Locale% intrinsic object and a standard built-in property of the Intl object.

1.2.1 ApplyOptionsToTag ( tag, options )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Assert: Type(tag) is String.
  2. Assert: Type(options) is Object.
  3. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
  4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
  5. If language is not undefined, then
    1. If language does not match the unicode_language_subtag production, throw a RangeError exception.
  6. Let script be ? GetOption(options, "script", "string", undefined, undefined).
  7. If script is not undefined, then
    1. If script does not match the unicode_script_subtag production, throw a RangeError exception.
  8. Let region be ? GetOption(options, "region", "string", undefined, undefined).
  9. If region is not undefined, then
    1. If region does not match the unicode_region_subtag production, throw a RangeError exception.
  10. Set tag to CanonicalizeUnicodeLocaleId(tag).
  11. Assert: tag matches the unicode_locale_id production.
  12. Let languageId be the substring of tag corresponding to the unicode_language_id production.
  13. If language is not undefined, then
    1. Set languageId to languageId with the substring corresponding to the unicode_language_subtag production replaced by the string language.
  14. If script is not undefined, then
    1. If languageId does not contain a unicode_script_subtag production, then
      1. Set languageId to the string-concatenation of the unicode_language_subtag production of languageId, "-", script, and the rest of languageId.
    2. Else,
      1. Set languageId to languageId with the substring corresponding to the unicode_script_subtag production replaced by the string script.
  15. If region is not undefined, then
    1. If languageId does not contain a unicode_region_subtag production, then
      1. Set languageId to the string-concatenation of the unicode_language_subtag production of languageId, the substring corresponding to "-" and the unicode_script_subtag production if present, "-", region, and the rest of languageId.
    2. Else,
      1. Set languageId to languageId with the substring corresponding to the unicode_region_subtag production replaced by the string region.
  16. Set tag to tag with the substring corresponding to the unicode_language_id production replaced by the string languageId.
  17. Return CanonicalizeUnicodeLocaleId(tag).

1.2.2 ApplyUnicodeExtensionToTag ( tag, options, relevantExtensionKeys )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Assert: Type(tag) is String.
  2. Assert: tag matches the unicode_locale_id production.
  3. If tag contains a substring that is a Unicode locale extension sequence, then
    1. Let extension be the String value consisting of the first substring of tag that is a Unicode locale extension sequence.
    2. Let components be ! UnicodeExtensionComponents(extension).
    3. Let attributes be components.[[Attributes]].
    4. Let keywords be components.[[Keywords]].
  4. Else,
    1. Let attributes be the empty List.
    2. Let keywords be the empty List.
  5. Let result be a new Record.
  6. For each element key of relevantExtensionKeys in List order, do
    1. Let value be undefined.
    2. If keywords contains an element whose [[Key]] is the same as key, then
      1. Let entry be the element of keywords whose [[Key]] is the same as key.
      2. Let value be entry.[[Value]].
    3. Else,
      1. Let entry be empty.
    4. Assert: options has a field [[<key>]].
    5. Let optionsValue be options.[[<key>]].
    6. If optionsValue is not undefined, then
      1. Assert: Type(optionsValue) is String.
      2. Let value be optionsValue.
      3. If entry is not empty, then
        1. Set entry.[[Value]] to value.
      4. Else,
        1. Append the Record{[[Key]]: key, [[Value]]: value} to keywords.
    7. Set result.[[<key>]] to value.
  7. Let locale be the String value that is tag with all Unicode locale extension sequences removed.
  8. Let newExtension be a Unicode BCP 47 U Extension based on attributes and keywords.
  9. If newExtension is not the empty String, then
    1. Let locale be ! InsertUnicodeExtensionAndCanonicalize(locale, newExtension).
  10. Set result.[[locale]] to locale.
  11. Return result.

1.2.3 Intl.Locale ( tag [ , options ] )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. When the Intl.Locale function is called with an argument tag and an optional argument options, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let relevantExtensionKeys be %Locale%.[[RelevantExtensionKeys]].
  3. Let internalSlotsList be « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[HourCycle]], [[NumberingSystem]] ».
  4. If relevantExtensionKeys contains "kf", then
    1. Append [[CaseFirst]] as the last element of internalSlotsList.
  5. If relevantExtensionKeys contains "kn", then
    1. Append [[Numeric]] as the last element of internalSlotsList.
  6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, %Locale.prototype%, internalSlotsList).
  7. If Type(tag) is not String or Object, throw a TypeError exception.
  8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal slot, then
    1. Let tag be tag.[[Locale]].
  9. Else,
    1. Let tag be ? ToString(tag).
  10. If options is undefined, then
    1. Let options be ! ObjectCreate(null).
  11. Else,
    1. Let options be ? ToObject(options).
  12. Set tag to ? ApplyOptionsToTag(tag, options).
  13. Let opt be a new Record.
  14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
  15. If calendar is not undefined, then
    1. If calendar does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  16. Set opt.[[ca]] to calendar.
  17. Let collation be ? GetOption(options, "collation", "string", undefined, undefined).
  18. If collation is not undefined, then
    1. If collation does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  19. Set opt.[[co]] to collation.
  20. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
  21. Set opt.[[hc]] to hc.
  22. Let kf be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined).
  23. Set opt.[[kf]] to kf.
  24. Let kn be ? GetOption(options, "numeric", "boolean", undefined, undefined).
  25. If kn is not undefined, set kn to ! ToString(kn).
  26. Set opt.[[kn]] to kn.
  27. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
  28. If numberingSystem is not undefined, then
    1. If numberingSystem does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  29. Set opt.[[nu]] to numberingSystem.
  30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
  31. Set locale.[[Locale]] to r.[[locale]].
  32. Set locale.[[Calendar]] to r.[[ca]].
  33. Set locale.[[Collation]] to r.[[co]].
  34. Set locale.[[HourCycle]] to r.[[hc]].
  35. If relevantExtensionKeys contains "kf", then
    1. Set locale.[[CaseFirst]] to r.[[kf]].
  36. If relevantExtensionKeys contains "kn", then
    1. If ! SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
      1. Set locale.[[Numeric]] to true.
    2. Else,
      1. Set locale.[[Numeric]] to false.
  37. Set locale.[[NumberingSystem]] to r.[[nu]].
  38. Return locale.

1.3 Properties of the Intl.Locale Constructor

The Intl.Locale constructor has the following properties:

1.3.1 Intl.Locale.prototype

The value of Intl.Locale.prototype is %Locale.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

1.3.2 Internal slots

The value of the [[RelevantExtensionKeys]] internal slot is « "ca", "co", "hc", "kf", "kn", "nu" ». If %Collator%.[[RelevantExtensionKeys]] does not contain "kf", then remove "kf" from %Locale%.[[RelevantExtensionKeys]]. If %Collator%.[[RelevantExtensionKeys]] does not contain "kn", then remove "kn" from %Locale%.[[RelevantExtensionKeys]].

1.4 Properties of the Intl.Locale Prototype Object

The Intl.Locale prototype object is itself an ordinary object. %Locale.prototype% is not an Intl.Locale instance and does not have an [[InitializedLocale]] internal slot or any of the other internal slots of Intl.Locale instance objects.

1.4.1 Intl.Locale.prototype.constructor

The initial value of Intl.Locale.prototype.constructor is %Locale%.

1.4.2 Intl.Locale.prototype[ @@toStringTag ]

The initial value of the @@toStringTag property is the string value "Intl.Locale".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

1.4.3 Intl.Locale.prototype.maximize ( )

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
  4. Return ! Construct(%Locale%, maximal).

1.4.4 Intl.Locale.prototype.minimize ( )

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
  4. Return ! Construct(%Locale%, minimal).

1.4.5 Intl.Locale.prototype.toString ( )

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[Locale]].

1.4.6 get Intl.Locale.prototype.baseName

Intl.Locale.prototype.baseName is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let locale be loc.[[Locale]].
  4. Return the substring of locale corresponding to the unicode_language_id production.

1.4.7 get Intl.Locale.prototype.calendar

Intl.Locale.prototype.calendar is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[Calendar]].

1.4.8 get Intl.Locale.prototype.caseFirst

This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kf".

Intl.Locale.prototype.caseFirst is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[CaseFirst]].

1.4.9 get Intl.Locale.prototype.collation

Intl.Locale.prototype.collation is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[Collation]].

1.4.10 get Intl.Locale.prototype.hourCycle

Intl.Locale.prototype.hourCycle is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[HourCycle]].

1.4.11 get Intl.Locale.prototype.numeric

This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kn".

Intl.Locale.prototype.numeric is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[Numeric]].

1.4.12 get Intl.Locale.prototype.numberingSystem

Intl.Locale.prototype.numberingSystem is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[NumberingSystem]].

1.4.13 get Intl.Locale.prototype.language

Intl.Locale.prototype.language is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. Return the substring of locale corresponding to the unicode_language_subtag production of the unicode_language_id.

1.4.14 get Intl.Locale.prototype.script

Intl.Locale.prototype.script is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. If the unicode_language_id production of locale does not contain the ["-" unicode_script_subtag] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_script_subtag production of the unicode_language_id.

1.4.15 get Intl.Locale.prototype.region

Intl.Locale.prototype.region is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.

1.4.16 get Intl.Locale.prototype.calendars

Intl.Locale.prototype.calendars is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return ! CalendarsOfLocale(loc).

1.4.17 get Intl.Locale.prototype.collations

Intl.Locale.prototype.collations is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return ! CollationsOfLocale(loc).

1.4.18 get Intl.Locale.prototype.hourCycles

Intl.Locale.prototype.hourCycles is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return ! HourCyclesOfLocale(loc).

1.4.19 get Intl.Locale.prototype.numberingSystems

Intl.Locale.prototype.numberingSystems is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return ! NumberingSystemsOfLocale(loc).

1.4.20 get Intl.Locale.prototype.timeZones

Intl.Locale.prototype.timeZones is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let locale be loc.[[Locale]].
  4. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
  5. Return ! TimeZonesOfLocale(loc).

1.4.21 get Intl.Locale.prototype.textInfo

Intl.Locale.prototype.textInfo is an accessor property whose set accessor function is undefined. The following algorithm refers to Locale data specified in UTS 35's Layouts Elements. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let info be ! ObjectCreate(%Object.prototype%).
  4. Let dir be ! CharacterDirectionOfLocale(loc).
  5. Perform ! CreateDataPropertyOrThrow(info, "direction", dir).
  6. Return info.

1.4.22 get Intl.Locale.prototype.weekInfo

Intl.Locale.prototype.weekInfo is an accessor property whose set accessor function is undefined. The following algorithm refers to Locale data specified in UTS 35's Week Elements. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let info be ! ObjectCreate(%Object.prototype%).
  4. Let wi be ! WeekInfoOfLocale(loc).
  5. Let we be ! CreateArrayFromList( wi.[[Weekend]] ).
  6. Perform ! CreateDataPropertyOrThrow(info, "firstDay", wi.[[FirstDay]]).
  7. Perform ! CreateDataPropertyOrThrow(info, "weekend", we).
  8. Perform ! CreateDataPropertyOrThrow(info, "minimalDays", wi.[[MinimalDays]]).
  9. Return info.

A Implementation Dependent Behaviour

The following aspects of the ECMAScript 2022 Internationalization API Specification are implementation dependent:

  • In Locale:
    • Support for the Unicode extensions keys "kf", "kn" and the parallel options properties "caseFirst", "numeric" (1.2.3)
    • The set of preferred calendars (1.1.2), collations (1.1.3), hour cycles (1.1.4), numbering systems (1.1.5), and time zones (1.1.6) per locale
    • The default general ordering of characters (characterOrder) within a line per locale (1.1.7)
    • The 'first' day of a week, the minimal days required in the first week of a month or year, and which days of the week are considered as part of the 'weekend', for calendar purposes, per locale (1.1.8)

B Copyright & Software License

Copyright Notice

© 2021 Google, Ecma International

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.