@fgv/ts-bcp47 5.1.0-2 → 5.1.0-21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/bcp/overrides.json +21 -0
- package/dist/data/unsd/m49.json +3723 -0
- package/dist/index.browser.js +30 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/packlets/bcp47/bcp47Subtags/converters.js +32 -0
- package/dist/packlets/bcp47/bcp47Subtags/converters.js.map +1 -0
- package/dist/packlets/bcp47/bcp47Subtags/index.js +26 -0
- package/dist/packlets/bcp47/bcp47Subtags/index.js.map +1 -0
- package/dist/packlets/bcp47/bcp47Subtags/model.js +23 -0
- package/dist/packlets/bcp47/bcp47Subtags/model.js.map +1 -0
- package/dist/packlets/bcp47/bcp47Subtags/validate.js +48 -0
- package/dist/packlets/bcp47/bcp47Subtags/validate.js.map +1 -0
- package/dist/packlets/bcp47/common.js +53 -0
- package/dist/packlets/bcp47/common.js.map +1 -0
- package/dist/packlets/bcp47/helpers.js +96 -0
- package/dist/packlets/bcp47/helpers.js.map +1 -0
- package/dist/packlets/bcp47/index.js +32 -0
- package/dist/packlets/bcp47/index.js.map +1 -0
- package/dist/packlets/bcp47/languageRegistryData.js +202 -0
- package/dist/packlets/bcp47/languageRegistryData.js.map +1 -0
- package/dist/packlets/bcp47/languageTag.js +363 -0
- package/dist/packlets/bcp47/languageTag.js.map +1 -0
- package/dist/packlets/bcp47/languageTagParser.js +275 -0
- package/dist/packlets/bcp47/languageTagParser.js.map +1 -0
- package/dist/packlets/bcp47/match/chooser.js +88 -0
- package/dist/packlets/bcp47/match/chooser.js.map +1 -0
- package/dist/packlets/bcp47/match/common.js +49 -0
- package/dist/packlets/bcp47/match/common.js.map +1 -0
- package/dist/packlets/bcp47/match/index.js +26 -0
- package/dist/packlets/bcp47/match/index.js.map +1 -0
- package/dist/packlets/bcp47/match/similarity.js +205 -0
- package/dist/packlets/bcp47/match/similarity.js.map +1 -0
- package/dist/packlets/bcp47/normalization/baseNormalizer.js +89 -0
- package/dist/packlets/bcp47/normalization/baseNormalizer.js.map +1 -0
- package/dist/packlets/bcp47/normalization/canonicalNormalizer.js +86 -0
- package/dist/packlets/bcp47/normalization/canonicalNormalizer.js.map +1 -0
- package/dist/packlets/bcp47/normalization/common.js +77 -0
- package/dist/packlets/bcp47/normalization/common.js.map +1 -0
- package/dist/packlets/bcp47/normalization/index.js +27 -0
- package/dist/packlets/bcp47/normalization/index.js.map +1 -0
- package/dist/packlets/bcp47/normalization/normalizeTag.js +101 -0
- package/dist/packlets/bcp47/normalization/normalizeTag.js.map +1 -0
- package/dist/packlets/bcp47/normalization/preferredTagNormalizer.js +177 -0
- package/dist/packlets/bcp47/normalization/preferredTagNormalizer.js.map +1 -0
- package/dist/packlets/bcp47/overrides/converters.js +49 -0
- package/dist/packlets/bcp47/overrides/converters.js.map +1 -0
- package/dist/packlets/bcp47/overrides/defaultRegistries.js +38 -0
- package/dist/packlets/bcp47/overrides/defaultRegistries.js.map +1 -0
- package/dist/packlets/bcp47/overrides/index.js +25 -0
- package/dist/packlets/bcp47/overrides/index.js.map +1 -0
- package/dist/packlets/bcp47/overrides/model.js +23 -0
- package/dist/packlets/bcp47/overrides/model.js.map +1 -0
- package/dist/packlets/bcp47/overrides/overridesRegistry.js +83 -0
- package/dist/packlets/bcp47/overrides/overridesRegistry.js.map +1 -0
- package/dist/packlets/bcp47/validation/baseValidator.js +86 -0
- package/dist/packlets/bcp47/validation/baseValidator.js.map +1 -0
- package/dist/packlets/bcp47/validation/common.js +77 -0
- package/dist/packlets/bcp47/validation/common.js.map +1 -0
- package/dist/packlets/bcp47/validation/index.js +29 -0
- package/dist/packlets/bcp47/validation/index.js.map +1 -0
- package/dist/packlets/bcp47/validation/isCanonical.js +79 -0
- package/dist/packlets/bcp47/validation/isCanonical.js.map +1 -0
- package/dist/packlets/bcp47/validation/isInPreferredForm.js +46 -0
- package/dist/packlets/bcp47/validation/isInPreferredForm.js.map +1 -0
- package/dist/packlets/bcp47/validation/isStrictlyValid.js +94 -0
- package/dist/packlets/bcp47/validation/isStrictlyValid.js.map +1 -0
- package/dist/packlets/bcp47/validation/isValid.js +92 -0
- package/dist/packlets/bcp47/validation/isValid.js.map +1 -0
- package/dist/packlets/bcp47/validation/isWellFormed.js +75 -0
- package/dist/packlets/bcp47/validation/isWellFormed.js.map +1 -0
- package/dist/packlets/bcp47/validation/validateTag.js +153 -0
- package/dist/packlets/bcp47/validation/validateTag.js.map +1 -0
- package/dist/packlets/iana/common/converters.js +58 -0
- package/dist/packlets/iana/common/converters.js.map +1 -0
- package/dist/packlets/iana/common/model.js +23 -0
- package/dist/packlets/iana/common/model.js.map +1 -0
- package/dist/packlets/iana/common/registeredItems.js +120 -0
- package/dist/packlets/iana/common/registeredItems.js.map +1 -0
- package/dist/packlets/iana/common/utils.js +30 -0
- package/dist/packlets/iana/common/utils.js.map +1 -0
- package/dist/packlets/iana/common/validate.js +59 -0
- package/dist/packlets/iana/common/validate.js.map +1 -0
- package/dist/packlets/iana/converters.js +25 -0
- package/dist/packlets/iana/converters.js.map +1 -0
- package/dist/packlets/iana/defaultRegistries.js +38 -0
- package/dist/packlets/iana/defaultRegistries.js.map +1 -0
- package/dist/packlets/iana/iana-data-embedded.js +60 -0
- package/dist/packlets/iana/iana-data-embedded.js.map +1 -0
- package/dist/packlets/iana/index.browser.js +34 -0
- package/dist/packlets/iana/index.browser.js.map +1 -0
- package/dist/packlets/iana/index.js +34 -0
- package/dist/packlets/iana/index.js.map +1 -0
- package/dist/packlets/iana/jar/converters.js +25 -0
- package/dist/packlets/iana/jar/converters.js.map +1 -0
- package/dist/packlets/iana/jar/index.js +26 -0
- package/dist/packlets/iana/jar/index.js.map +1 -0
- package/dist/packlets/iana/jar/jarConverters.js +60 -0
- package/dist/packlets/iana/jar/jarConverters.js.map +1 -0
- package/dist/packlets/iana/jar/jarModel.js +23 -0
- package/dist/packlets/iana/jar/jarModel.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/converters.js +25 -0
- package/dist/packlets/iana/jar/language-subtags/converters.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/index.js +26 -0
- package/dist/packlets/iana/jar/language-subtags/index.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/model.js +25 -0
- package/dist/packlets/iana/jar/language-subtags/model.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/registry/converters.js +180 -0
- package/dist/packlets/iana/jar/language-subtags/registry/converters.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/registry/index.js +26 -0
- package/dist/packlets/iana/jar/language-subtags/registry/index.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/registry/model.js +43 -0
- package/dist/packlets/iana/jar/language-subtags/registry/model.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/tags/converters.js +101 -0
- package/dist/packlets/iana/jar/language-subtags/tags/converters.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/tags/index.js +27 -0
- package/dist/packlets/iana/jar/language-subtags/tags/index.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/tags/model.js +23 -0
- package/dist/packlets/iana/jar/language-subtags/tags/model.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/tags/tagValidation.js +66 -0
- package/dist/packlets/iana/jar/language-subtags/tags/tagValidation.js.map +1 -0
- package/dist/packlets/iana/jar/language-subtags/tags/validate.js +85 -0
- package/dist/packlets/iana/jar/language-subtags/tags/validate.js.map +1 -0
- package/dist/packlets/iana/jar/model.js +25 -0
- package/dist/packlets/iana/jar/model.js.map +1 -0
- package/dist/packlets/iana/language-subtags/common.js +23 -0
- package/dist/packlets/iana/language-subtags/common.js.map +1 -0
- package/dist/packlets/iana/language-subtags/converters.js +182 -0
- package/dist/packlets/iana/language-subtags/converters.js.map +1 -0
- package/dist/packlets/iana/language-subtags/index.browser.js +30 -0
- package/dist/packlets/iana/language-subtags/index.browser.js.map +1 -0
- package/dist/packlets/iana/language-subtags/index.js +29 -0
- package/dist/packlets/iana/language-subtags/index.js.map +1 -0
- package/dist/packlets/iana/language-subtags/jarConverters.js +288 -0
- package/dist/packlets/iana/language-subtags/jarConverters.js.map +1 -0
- package/dist/packlets/iana/language-subtags/model.js +23 -0
- package/dist/packlets/iana/language-subtags/model.js.map +1 -0
- package/dist/packlets/iana/language-subtags/scope.js +169 -0
- package/dist/packlets/iana/language-subtags/scope.js.map +1 -0
- package/dist/packlets/iana/language-subtags/subtagRegistry.js +108 -0
- package/dist/packlets/iana/language-subtags/subtagRegistry.js.map +1 -0
- package/dist/packlets/iana/language-subtags/validate.js +23 -0
- package/dist/packlets/iana/language-subtags/validate.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/converters.js +59 -0
- package/dist/packlets/iana/language-tag-extensions/converters.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/extensionsRegistry.js +64 -0
- package/dist/packlets/iana/language-tag-extensions/extensionsRegistry.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/extensionsScope.js +50 -0
- package/dist/packlets/iana/language-tag-extensions/extensionsScope.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/index.js +28 -0
- package/dist/packlets/iana/language-tag-extensions/index.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/jarConverters.js +143 -0
- package/dist/packlets/iana/language-tag-extensions/jarConverters.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/model.js +24 -0
- package/dist/packlets/iana/language-tag-extensions/model.js.map +1 -0
- package/dist/packlets/iana/language-tag-extensions/validate.js +33 -0
- package/dist/packlets/iana/language-tag-extensions/validate.js.map +1 -0
- package/dist/packlets/iana/languageRegistries.js +80 -0
- package/dist/packlets/iana/languageRegistries.js.map +1 -0
- package/dist/packlets/iana/languageRegistriesFileLoader.js +73 -0
- package/dist/packlets/iana/languageRegistriesFileLoader.js.map +1 -0
- package/dist/packlets/iana/languageRegistriesLoader.js +113 -0
- package/dist/packlets/iana/languageRegistriesLoader.js.map +1 -0
- package/dist/packlets/iana/model.js +25 -0
- package/dist/packlets/iana/model.js.map +1 -0
- package/dist/packlets/iana/validate.js +23 -0
- package/dist/packlets/iana/validate.js.map +1 -0
- package/dist/packlets/unsd/areas.js +92 -0
- package/dist/packlets/unsd/areas.js.map +1 -0
- package/dist/packlets/unsd/common.js +23 -0
- package/dist/packlets/unsd/common.js.map +1 -0
- package/dist/packlets/unsd/csv/converters.js +75 -0
- package/dist/packlets/unsd/csv/converters.js.map +1 -0
- package/dist/packlets/unsd/csv/index.js +25 -0
- package/dist/packlets/unsd/csv/index.js.map +1 -0
- package/dist/packlets/unsd/csv/model.js +23 -0
- package/dist/packlets/unsd/csv/model.js.map +1 -0
- package/dist/packlets/unsd/defaultRegistries.js +38 -0
- package/dist/packlets/unsd/defaultRegistries.js.map +1 -0
- package/dist/packlets/unsd/index.js +27 -0
- package/dist/packlets/unsd/index.js.map +1 -0
- package/dist/packlets/unsd/regionCodes.js +115 -0
- package/dist/packlets/unsd/regionCodes.js.map +1 -0
- package/dist/packlets/unsd/regions.js +71 -0
- package/dist/packlets/unsd/regions.js.map +1 -0
- package/dist/packlets/utils/index.js +24 -0
- package/dist/packlets/utils/index.js.map +1 -0
- package/dist/packlets/utils/jsonHelpers.js +25 -0
- package/dist/packlets/utils/jsonHelpers.js.map +1 -0
- package/dist/packlets/utils/public.js +24 -0
- package/dist/packlets/utils/public.js.map +1 -0
- package/dist/packlets/utils/validationHelpers.js +116 -0
- package/dist/packlets/utils/validationHelpers.js.map +1 -0
- package/dist/ts-bcp47.d.ts +5 -5
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.browser.d.ts.map +1 -0
- package/lib/index.browser.js.map +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/converters.d.ts.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/converters.js.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/index.js.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/model.d.ts.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/model.js.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/validate.d.ts.map +1 -0
- package/lib/packlets/bcp47/bcp47Subtags/validate.js.map +1 -0
- package/lib/packlets/bcp47/common.d.ts.map +1 -0
- package/lib/packlets/bcp47/common.js.map +1 -0
- package/lib/packlets/bcp47/helpers.d.ts.map +1 -0
- package/lib/packlets/bcp47/helpers.js.map +1 -0
- package/lib/packlets/bcp47/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/index.js.map +1 -0
- package/lib/packlets/bcp47/languageRegistryData.d.ts.map +1 -0
- package/lib/packlets/bcp47/languageRegistryData.js.map +1 -0
- package/lib/packlets/bcp47/languageTag.d.ts +1 -1
- package/lib/packlets/bcp47/languageTag.d.ts.map +1 -0
- package/lib/packlets/bcp47/languageTag.js +1 -1
- package/lib/packlets/bcp47/languageTag.js.map +1 -0
- package/lib/packlets/bcp47/languageTagParser.d.ts.map +1 -0
- package/lib/packlets/bcp47/languageTagParser.js.map +1 -0
- package/lib/packlets/bcp47/match/chooser.d.ts.map +1 -0
- package/lib/packlets/bcp47/match/chooser.js.map +1 -0
- package/lib/packlets/bcp47/match/common.d.ts.map +1 -0
- package/lib/packlets/bcp47/match/common.js.map +1 -0
- package/lib/packlets/bcp47/match/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/match/index.js.map +1 -0
- package/lib/packlets/bcp47/match/similarity.d.ts.map +1 -0
- package/lib/packlets/bcp47/match/similarity.js.map +1 -0
- package/lib/packlets/bcp47/normalization/baseNormalizer.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/baseNormalizer.js.map +1 -0
- package/lib/packlets/bcp47/normalization/canonicalNormalizer.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/canonicalNormalizer.js.map +1 -0
- package/lib/packlets/bcp47/normalization/common.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/common.js.map +1 -0
- package/lib/packlets/bcp47/normalization/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/index.js.map +1 -0
- package/lib/packlets/bcp47/normalization/normalizeTag.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/normalizeTag.js.map +1 -0
- package/lib/packlets/bcp47/normalization/preferredTagNormalizer.d.ts.map +1 -0
- package/lib/packlets/bcp47/normalization/preferredTagNormalizer.js.map +1 -0
- package/lib/packlets/bcp47/overrides/converters.d.ts.map +1 -0
- package/lib/packlets/bcp47/overrides/converters.js.map +1 -0
- package/lib/packlets/bcp47/overrides/defaultRegistries.d.ts.map +1 -0
- package/lib/packlets/bcp47/overrides/defaultRegistries.js.map +1 -0
- package/lib/packlets/bcp47/overrides/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/overrides/index.js.map +1 -0
- package/lib/packlets/bcp47/overrides/model.d.ts.map +1 -0
- package/lib/packlets/bcp47/overrides/model.js.map +1 -0
- package/lib/packlets/bcp47/overrides/overridesRegistry.d.ts.map +1 -0
- package/lib/packlets/bcp47/overrides/overridesRegistry.js.map +1 -0
- package/lib/packlets/bcp47/validation/baseValidator.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/baseValidator.js.map +1 -0
- package/lib/packlets/bcp47/validation/common.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/common.js.map +1 -0
- package/lib/packlets/bcp47/validation/index.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/index.js.map +1 -0
- package/lib/packlets/bcp47/validation/isCanonical.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/isCanonical.js.map +1 -0
- package/lib/packlets/bcp47/validation/isInPreferredForm.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/isInPreferredForm.js.map +1 -0
- package/lib/packlets/bcp47/validation/isStrictlyValid.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/isStrictlyValid.js.map +1 -0
- package/lib/packlets/bcp47/validation/isValid.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/isValid.js.map +1 -0
- package/lib/packlets/bcp47/validation/isWellFormed.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/isWellFormed.js.map +1 -0
- package/lib/packlets/bcp47/validation/validateTag.d.ts.map +1 -0
- package/lib/packlets/bcp47/validation/validateTag.js.map +1 -0
- package/lib/packlets/iana/common/converters.d.ts +2 -2
- package/lib/packlets/iana/common/converters.d.ts.map +1 -0
- package/lib/packlets/iana/common/converters.js +2 -2
- package/lib/packlets/iana/common/converters.js.map +1 -0
- package/lib/packlets/iana/common/model.d.ts.map +1 -0
- package/lib/packlets/iana/common/model.js.map +1 -0
- package/lib/packlets/iana/common/registeredItems.d.ts.map +1 -0
- package/lib/packlets/iana/common/registeredItems.js.map +1 -0
- package/lib/packlets/iana/common/utils.d.ts.map +1 -0
- package/lib/packlets/iana/common/utils.js.map +1 -0
- package/lib/packlets/iana/common/validate.d.ts.map +1 -0
- package/lib/packlets/iana/common/validate.js.map +1 -0
- package/lib/packlets/iana/converters.d.ts.map +1 -0
- package/lib/packlets/iana/converters.js.map +1 -0
- package/lib/packlets/iana/defaultRegistries.d.ts.map +1 -0
- package/lib/packlets/iana/defaultRegistries.js.map +1 -0
- package/lib/packlets/iana/iana-data-embedded.d.ts.map +1 -0
- package/lib/packlets/iana/iana-data-embedded.js.map +1 -0
- package/lib/packlets/iana/index.browser.d.ts.map +1 -0
- package/lib/packlets/iana/index.browser.js.map +1 -0
- package/lib/packlets/iana/index.d.ts.map +1 -0
- package/lib/packlets/iana/index.js.map +1 -0
- package/lib/packlets/iana/jar/converters.d.ts.map +1 -0
- package/lib/packlets/iana/jar/converters.js.map +1 -0
- package/lib/packlets/iana/jar/index.d.ts.map +1 -0
- package/lib/packlets/iana/jar/index.js.map +1 -0
- package/lib/packlets/iana/jar/jarConverters.d.ts +2 -2
- package/lib/packlets/iana/jar/jarConverters.d.ts.map +1 -0
- package/lib/packlets/iana/jar/jarConverters.js +2 -2
- package/lib/packlets/iana/jar/jarConverters.js.map +1 -0
- package/lib/packlets/iana/jar/jarModel.d.ts.map +1 -0
- package/lib/packlets/iana/jar/jarModel.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/converters.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/converters.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/index.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/index.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/model.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/model.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/converters.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/converters.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/index.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/index.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/model.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/registry/model.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/converters.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/converters.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/index.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/index.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/model.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/model.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/tagValidation.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/tagValidation.js.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/validate.d.ts.map +1 -0
- package/lib/packlets/iana/jar/language-subtags/tags/validate.js.map +1 -0
- package/lib/packlets/iana/jar/model.d.ts.map +1 -0
- package/lib/packlets/iana/jar/model.js.map +1 -0
- package/lib/packlets/iana/language-subtags/common.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/common.js.map +1 -0
- package/lib/packlets/iana/language-subtags/converters.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/converters.js.map +1 -0
- package/lib/packlets/iana/language-subtags/index.browser.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/index.browser.js.map +1 -0
- package/lib/packlets/iana/language-subtags/index.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/index.js.map +1 -0
- package/lib/packlets/iana/language-subtags/jarConverters.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/jarConverters.js.map +1 -0
- package/lib/packlets/iana/language-subtags/model.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/model.js.map +1 -0
- package/lib/packlets/iana/language-subtags/scope.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/scope.js.map +1 -0
- package/lib/packlets/iana/language-subtags/subtagRegistry.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/subtagRegistry.js.map +1 -0
- package/lib/packlets/iana/language-subtags/validate.d.ts.map +1 -0
- package/lib/packlets/iana/language-subtags/validate.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/converters.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/converters.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/extensionsRegistry.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/extensionsRegistry.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/extensionsScope.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/extensionsScope.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/index.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/index.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/jarConverters.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/jarConverters.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/model.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/model.js.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/validate.d.ts.map +1 -0
- package/lib/packlets/iana/language-tag-extensions/validate.js.map +1 -0
- package/lib/packlets/iana/languageRegistries.d.ts.map +1 -0
- package/lib/packlets/iana/languageRegistries.js.map +1 -0
- package/lib/packlets/iana/languageRegistriesFileLoader.d.ts.map +1 -0
- package/lib/packlets/iana/languageRegistriesFileLoader.js.map +1 -0
- package/lib/packlets/iana/languageRegistriesLoader.d.ts.map +1 -0
- package/lib/packlets/iana/languageRegistriesLoader.js.map +1 -0
- package/lib/packlets/iana/model.d.ts.map +1 -0
- package/lib/packlets/iana/model.js.map +1 -0
- package/lib/packlets/iana/validate.d.ts.map +1 -0
- package/lib/packlets/iana/validate.js.map +1 -0
- package/lib/packlets/unsd/areas.d.ts.map +1 -0
- package/lib/packlets/unsd/areas.js.map +1 -0
- package/lib/packlets/unsd/common.d.ts.map +1 -0
- package/lib/packlets/unsd/common.js.map +1 -0
- package/lib/packlets/unsd/csv/converters.d.ts.map +1 -0
- package/lib/packlets/unsd/csv/converters.js.map +1 -0
- package/lib/packlets/unsd/csv/index.d.ts.map +1 -0
- package/lib/packlets/unsd/csv/index.js.map +1 -0
- package/lib/packlets/unsd/csv/model.d.ts.map +1 -0
- package/lib/packlets/unsd/csv/model.js.map +1 -0
- package/lib/packlets/unsd/defaultRegistries.d.ts.map +1 -0
- package/lib/packlets/unsd/defaultRegistries.js.map +1 -0
- package/lib/packlets/unsd/index.d.ts.map +1 -0
- package/lib/packlets/unsd/index.js.map +1 -0
- package/lib/packlets/unsd/regionCodes.d.ts.map +1 -0
- package/lib/packlets/unsd/regionCodes.js.map +1 -0
- package/lib/packlets/unsd/regions.d.ts.map +1 -0
- package/lib/packlets/unsd/regions.js.map +1 -0
- package/lib/packlets/utils/index.d.ts.map +1 -0
- package/lib/packlets/utils/index.js.map +1 -0
- package/lib/packlets/utils/jsonHelpers.d.ts.map +1 -0
- package/lib/packlets/utils/jsonHelpers.js.map +1 -0
- package/lib/packlets/utils/public.d.ts.map +1 -0
- package/lib/packlets/utils/public.js.map +1 -0
- package/lib/packlets/utils/validationHelpers.d.ts.map +1 -0
- package/lib/packlets/utils/validationHelpers.js.map +1 -0
- package/package.json +36 -31
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import * as Iana from '../iana';
|
|
23
|
+
import { allSucceed, fail, succeed } from '@fgv/ts-utils';
|
|
24
|
+
import { Validate } from './bcp47Subtags';
|
|
25
|
+
/**
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export class LanguageTagParser {
|
|
29
|
+
/* c8 ignore next */
|
|
30
|
+
constructor() { }
|
|
31
|
+
/**
|
|
32
|
+
* Parses a string representation of a BCP-47 ({@link https://www.rfc-editor.org/rfc/rfc5646.html | RFC 5646})
|
|
33
|
+
* language tag, to produce a {@link Bcp47.Subtags | Subtags} object which
|
|
34
|
+
* breaks out each of the subtags.
|
|
35
|
+
* @param tag - The `string` language tag to be parsed.
|
|
36
|
+
* @param iana - Optional {@link Iana.LanguageRegistries | IANA language registries}
|
|
37
|
+
* to be used.
|
|
38
|
+
* @returns `Success` with the resulting {@link Bcp47.Subtags | subtags}
|
|
39
|
+
* or `Failure` with details if an error occurs.
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
static parse(tag, iana) {
|
|
43
|
+
/* c8 ignore next */
|
|
44
|
+
iana = iana !== null && iana !== void 0 ? iana : Iana.DefaultRegistries.languageRegistries;
|
|
45
|
+
const status = {
|
|
46
|
+
tag,
|
|
47
|
+
iana,
|
|
48
|
+
subtags: tag.split('-'),
|
|
49
|
+
parsedSubtags: {}
|
|
50
|
+
};
|
|
51
|
+
status.next = status.subtags.shift();
|
|
52
|
+
return allSucceed([
|
|
53
|
+
this._parseGrandfatheredTag(status),
|
|
54
|
+
this._parsePrimaryLanguage(status),
|
|
55
|
+
this._parseExtlang(status),
|
|
56
|
+
this._parseScript(status),
|
|
57
|
+
this._parseRegion(status),
|
|
58
|
+
this._parseVariants(status),
|
|
59
|
+
this._parseExtensions(status),
|
|
60
|
+
this._parsePrivateSubtags(status),
|
|
61
|
+
this._parseTagEnd(status)
|
|
62
|
+
], status).onSuccess(() => {
|
|
63
|
+
return succeed(status.parsedSubtags);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Determines if the entire tag matches a registered grandfathered tag.
|
|
68
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
69
|
+
* parse operation.
|
|
70
|
+
* @returns `Success` with the updated {@link Bcp47.Subtags | subtags}
|
|
71
|
+
* if a grandfathered tag is found, or `Success` with the supplied subtags
|
|
72
|
+
* if no matching grandfathered tag is found.
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
static _parseGrandfatheredTag(state) {
|
|
76
|
+
const grandfathered = state.iana.subtags.grandfathered.tryGet(state.tag);
|
|
77
|
+
if (grandfathered) {
|
|
78
|
+
state.parsedSubtags.grandfathered = state.tag;
|
|
79
|
+
// we consumed the whole thing
|
|
80
|
+
state.subtags.splice(0, state.subtags.length);
|
|
81
|
+
state.next = undefined;
|
|
82
|
+
}
|
|
83
|
+
return succeed(state.parsedSubtags);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parses the primary language subtag of a supplied language tag.
|
|
87
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
88
|
+
* parse operation.
|
|
89
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
90
|
+
* updated to include the primary language subtag, or `Failure` with details if an error
|
|
91
|
+
* occurs.
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
static _parsePrimaryLanguage(state) {
|
|
95
|
+
// primary language subtag is required unless the entire tag is grandfathered or consists
|
|
96
|
+
// of only private tags
|
|
97
|
+
if (state.iana.subtags.languages.isWellFormed(state.next)) {
|
|
98
|
+
state.parsedSubtags.primaryLanguage = state.next;
|
|
99
|
+
state.next = state.subtags.shift();
|
|
100
|
+
return succeed(state.parsedSubtags);
|
|
101
|
+
}
|
|
102
|
+
else if (state.parsedSubtags.grandfathered !== undefined) {
|
|
103
|
+
return succeed(state.parsedSubtags);
|
|
104
|
+
}
|
|
105
|
+
else if (Validate.privateUsePrefix.isWellFormed(state.next)) {
|
|
106
|
+
// just return with no primary language and the private tag
|
|
107
|
+
// parser will be invoked by the parent flow.
|
|
108
|
+
return succeed(state.parsedSubtags);
|
|
109
|
+
}
|
|
110
|
+
return fail(`${state.tag}: no primary language subtag`);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parses the extlang subtag(s) of a supplied language tag.
|
|
114
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
115
|
+
* parse operation.
|
|
116
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
117
|
+
* updated to include extlang subtags if present, or `Failure` with details if an error
|
|
118
|
+
* occurs.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
static _parseExtlang(state) {
|
|
122
|
+
// optional extlangs subtags
|
|
123
|
+
while (state.iana.subtags.extlangs.isWellFormed(state.next)) {
|
|
124
|
+
if (state.parsedSubtags.extlangs === undefined) {
|
|
125
|
+
state.parsedSubtags.extlangs = [state.next];
|
|
126
|
+
}
|
|
127
|
+
else if (state.parsedSubtags.extlangs.length < 3) {
|
|
128
|
+
state.parsedSubtags.extlangs.push(state.next);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
return fail(`${state.next}: too many extlang subtags`);
|
|
132
|
+
}
|
|
133
|
+
state.next = state.subtags.shift();
|
|
134
|
+
}
|
|
135
|
+
return succeed(state.parsedSubtags);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Parses the script subtag of a supplied language tag.
|
|
139
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
140
|
+
* parse operation.
|
|
141
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
142
|
+
* updated to include the script subtag if present, or `Failure` with details if an error
|
|
143
|
+
* occurs.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
static _parseScript(state) {
|
|
147
|
+
// optional script subtag
|
|
148
|
+
if (state.iana.subtags.scripts.isWellFormed(state.next)) {
|
|
149
|
+
state.parsedSubtags.script = state.next;
|
|
150
|
+
state.next = state.subtags.shift();
|
|
151
|
+
}
|
|
152
|
+
return succeed(state.parsedSubtags);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Parses the region subtag of a supplied language tag.
|
|
156
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
157
|
+
* parse operation.
|
|
158
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
159
|
+
* updated to include the region subtag if present, or `Failure` with details if an error
|
|
160
|
+
* occurs.
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
static _parseRegion(state) {
|
|
164
|
+
// optional region subtag
|
|
165
|
+
if (state.iana.subtags.regions.isWellFormed(state.next)) {
|
|
166
|
+
state.parsedSubtags.region = state.next;
|
|
167
|
+
state.next = state.subtags.shift();
|
|
168
|
+
}
|
|
169
|
+
return succeed(state.parsedSubtags);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Parses the variant subtag(s) of a supplied language tag.
|
|
173
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
174
|
+
* parse operation.
|
|
175
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
176
|
+
* updated to include the variant subtags if present, or `Failure` with details if an error
|
|
177
|
+
* occurs.
|
|
178
|
+
* @internal
|
|
179
|
+
*/
|
|
180
|
+
static _parseVariants(state) {
|
|
181
|
+
// optional variant subtags
|
|
182
|
+
while (state.iana.subtags.variants.isWellFormed(state.next)) {
|
|
183
|
+
if (state.parsedSubtags.variants === undefined) {
|
|
184
|
+
state.parsedSubtags.variants = [state.next];
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
state.parsedSubtags.variants.push(state.next);
|
|
188
|
+
}
|
|
189
|
+
state.next = state.subtags.shift();
|
|
190
|
+
}
|
|
191
|
+
return succeed(state.parsedSubtags);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Parses the extension subtag(s) of a supplied language tag.
|
|
195
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
196
|
+
* parse operation.
|
|
197
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
198
|
+
* updated to include the extension subtags if present, or `Failure` with details if an error
|
|
199
|
+
* occurs.
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
static _parseExtensions(state) {
|
|
203
|
+
// optional extension subtags
|
|
204
|
+
while (state.next !== undefined && Validate.extensionSingleton.isWellFormed(state.next)) {
|
|
205
|
+
const singleton = state.next;
|
|
206
|
+
const values = [];
|
|
207
|
+
state.next = state.subtags.shift();
|
|
208
|
+
while (Validate.extensionSubtag.isWellFormed(state.next)) {
|
|
209
|
+
values.push(state.next);
|
|
210
|
+
state.next = state.subtags.shift();
|
|
211
|
+
}
|
|
212
|
+
if (state.next !== undefined &&
|
|
213
|
+
!Validate.extensionSingleton.isWellFormed(state.next) &&
|
|
214
|
+
!Validate.privateUsePrefix.isWellFormed(state.next)) {
|
|
215
|
+
return fail(`${state.next}: malformed extension subtag`);
|
|
216
|
+
}
|
|
217
|
+
else if (values.length < 1) {
|
|
218
|
+
return fail(`${state.tag}: extension '${singleton}' must have at least one subtag.`);
|
|
219
|
+
}
|
|
220
|
+
const value = values.join('-');
|
|
221
|
+
if (state.parsedSubtags.extensions === undefined) {
|
|
222
|
+
state.parsedSubtags.extensions = [{ singleton, value }];
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
state.parsedSubtags.extensions.push({ singleton, value });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return succeed(state.parsedSubtags);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Parses the private use subtags of a supplied language tag.
|
|
232
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
233
|
+
* parse operation.
|
|
234
|
+
* @returns `Success` with supplied {@link Bcp47.Subtags | subtags}
|
|
235
|
+
* updated to include the private-use subtags if present, or `Failure` with details if an error
|
|
236
|
+
* occurs.
|
|
237
|
+
* @internal
|
|
238
|
+
*/
|
|
239
|
+
static _parsePrivateSubtags(state) {
|
|
240
|
+
// optional private use subtags
|
|
241
|
+
if (state.next !== undefined && Validate.privateUsePrefix.isWellFormed(state.next)) {
|
|
242
|
+
const values = [];
|
|
243
|
+
state.next = state.subtags.shift();
|
|
244
|
+
while (state.next &&
|
|
245
|
+
state.next.length > 1 &&
|
|
246
|
+
Iana.LanguageSubtags.Validate.extendedLanguageRange.isWellFormed(state.next)) {
|
|
247
|
+
values.push(state.next);
|
|
248
|
+
state.next = state.subtags.shift();
|
|
249
|
+
}
|
|
250
|
+
if (state.next !== undefined) {
|
|
251
|
+
return fail(`${state.next}: malformed private-use subtag`);
|
|
252
|
+
}
|
|
253
|
+
else if (values.length < 1) {
|
|
254
|
+
return fail(`${state.tag}: private-use tag must have at least one subtag.`);
|
|
255
|
+
}
|
|
256
|
+
state.parsedSubtags.privateUse = values;
|
|
257
|
+
}
|
|
258
|
+
return succeed(state.parsedSubtags);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Verifies {@link Bcp47.ParserState | parser state} at the end of a parse operation.
|
|
262
|
+
* @param state - The {@link Bcp47.ParserState | current state} of the
|
|
263
|
+
* parse operation.
|
|
264
|
+
* @returns `Success` if the tag was fully consumed, or `Failure` with details
|
|
265
|
+
* if unexpected subtags remain to be parsed.
|
|
266
|
+
* @internal
|
|
267
|
+
*/
|
|
268
|
+
static _parseTagEnd(state) {
|
|
269
|
+
if (state.next !== undefined) {
|
|
270
|
+
return fail(`${state.next}: unexpected subtag`);
|
|
271
|
+
}
|
|
272
|
+
return succeed(state.parsedSubtags);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=languageTagParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languageTagParser.js","sourceRoot":"","sources":["../../../src/packlets/bcp47/languageTagParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2022 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Iana from '../iana';\n\nimport { Result, Success, allSucceed, fail, succeed } from '@fgv/ts-utils';\n\nimport { Validate } from './bcp47Subtags';\nimport { ExtensionSingleton, ExtensionSubtag } from './bcp47Subtags/model';\nimport { ISubtags } from './common';\n\n/**\n * @internal\n */\ninterface IParserState {\n readonly iana: Iana.LanguageRegistries;\n readonly tag: string;\n readonly subtags: string[];\n readonly parsedSubtags: ISubtags;\n next?: string;\n}\n\n/**\n * @public\n */\nexport class LanguageTagParser {\n /* c8 ignore next */\n private constructor() {}\n\n /**\n * Parses a string representation of a BCP-47 ({@link https://www.rfc-editor.org/rfc/rfc5646.html | RFC 5646})\n * language tag, to produce a {@link Bcp47.Subtags | Subtags} object which\n * breaks out each of the subtags.\n * @param tag - The `string` language tag to be parsed.\n * @param iana - Optional {@link Iana.LanguageRegistries | IANA language registries}\n * to be used.\n * @returns `Success` with the resulting {@link Bcp47.Subtags | subtags}\n * or `Failure` with details if an error occurs.\n * @public\n */\n public static parse(tag: string, iana?: Iana.LanguageRegistries): Result<ISubtags> {\n /* c8 ignore next */\n iana = iana ?? Iana.DefaultRegistries.languageRegistries;\n const status: IParserState = {\n tag,\n iana,\n subtags: tag.split('-'),\n parsedSubtags: {}\n };\n status.next = status.subtags.shift();\n\n return allSucceed(\n [\n this._parseGrandfatheredTag(status),\n this._parsePrimaryLanguage(status),\n this._parseExtlang(status),\n this._parseScript(status),\n this._parseRegion(status),\n this._parseVariants(status),\n this._parseExtensions(status),\n this._parsePrivateSubtags(status),\n this._parseTagEnd(status)\n ],\n status\n ).onSuccess(() => {\n return succeed(status.parsedSubtags);\n });\n }\n\n /**\n * Determines if the entire tag matches a registered grandfathered tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with the updated {@link Bcp47.Subtags | subtags}\n * if a grandfathered tag is found, or `Success` with the supplied subtags\n * if no matching grandfathered tag is found.\n * @internal\n */\n protected static _parseGrandfatheredTag(state: IParserState): Success<ISubtags> {\n const grandfathered = state.iana.subtags.grandfathered.tryGet(state.tag);\n if (grandfathered) {\n state.parsedSubtags.grandfathered = state.tag as Iana.LanguageSubtags.GrandfatheredTag;\n // we consumed the whole thing\n state.subtags.splice(0, state.subtags.length);\n state.next = undefined;\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the primary language subtag of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the primary language subtag, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parsePrimaryLanguage(state: IParserState): Result<ISubtags> {\n // primary language subtag is required unless the entire tag is grandfathered or consists\n // of only private tags\n if (state.iana.subtags.languages.isWellFormed(state.next)) {\n state.parsedSubtags.primaryLanguage = state.next;\n state.next = state.subtags.shift();\n return succeed(state.parsedSubtags);\n } else if (state.parsedSubtags.grandfathered !== undefined) {\n return succeed(state.parsedSubtags);\n } else if (Validate.privateUsePrefix.isWellFormed(state.next)) {\n // just return with no primary language and the private tag\n // parser will be invoked by the parent flow.\n return succeed(state.parsedSubtags);\n }\n return fail(`${state.tag}: no primary language subtag`);\n }\n\n /**\n * Parses the extlang subtag(s) of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include extlang subtags if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parseExtlang(state: IParserState): Result<ISubtags> {\n // optional extlangs subtags\n while (state.iana.subtags.extlangs.isWellFormed(state.next)) {\n if (state.parsedSubtags.extlangs === undefined) {\n state.parsedSubtags.extlangs = [state.next];\n } else if (state.parsedSubtags.extlangs.length < 3) {\n state.parsedSubtags.extlangs.push(state.next);\n } else {\n return fail(`${state.next}: too many extlang subtags`);\n }\n state.next = state.subtags.shift();\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the script subtag of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the script subtag if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parseScript(state: IParserState): Result<ISubtags> {\n // optional script subtag\n if (state.iana.subtags.scripts.isWellFormed(state.next)) {\n state.parsedSubtags.script = state.next;\n state.next = state.subtags.shift();\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the region subtag of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the region subtag if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parseRegion(state: IParserState): Result<ISubtags> {\n // optional region subtag\n if (state.iana.subtags.regions.isWellFormed(state.next)) {\n state.parsedSubtags.region = state.next;\n state.next = state.subtags.shift();\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the variant subtag(s) of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the variant subtags if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parseVariants(state: IParserState): Result<ISubtags> {\n // optional variant subtags\n while (state.iana.subtags.variants.isWellFormed(state.next)) {\n if (state.parsedSubtags.variants === undefined) {\n state.parsedSubtags.variants = [state.next];\n } else {\n state.parsedSubtags.variants.push(state.next);\n }\n state.next = state.subtags.shift();\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the extension subtag(s) of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the extension subtags if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parseExtensions(state: IParserState): Result<ISubtags> {\n // optional extension subtags\n while (state.next !== undefined && Validate.extensionSingleton.isWellFormed(state.next)) {\n const singleton: ExtensionSingleton = state.next as ExtensionSingleton;\n const values: ExtensionSubtag[] = [];\n state.next = state.subtags.shift();\n\n while (Validate.extensionSubtag.isWellFormed(state.next)) {\n values.push(state.next as ExtensionSubtag);\n state.next = state.subtags.shift();\n }\n if (\n state.next !== undefined &&\n !Validate.extensionSingleton.isWellFormed(state.next) &&\n !Validate.privateUsePrefix.isWellFormed(state.next)\n ) {\n return fail(`${state.next}: malformed extension subtag`);\n } else if (values.length < 1) {\n return fail(`${state.tag}: extension '${singleton}' must have at least one subtag.`);\n }\n\n const value = values.join('-') as ExtensionSubtag;\n if (state.parsedSubtags.extensions === undefined) {\n state.parsedSubtags.extensions = [{ singleton, value }];\n } else {\n state.parsedSubtags.extensions.push({ singleton, value });\n }\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Parses the private use subtags of a supplied language tag.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` with supplied {@link Bcp47.Subtags | subtags}\n * updated to include the private-use subtags if present, or `Failure` with details if an error\n * occurs.\n * @internal\n */\n protected static _parsePrivateSubtags(state: IParserState): Result<ISubtags> {\n // optional private use subtags\n if (state.next !== undefined && Validate.privateUsePrefix.isWellFormed(state.next)) {\n const values: string[] = [];\n state.next = state.subtags.shift();\n\n while (\n state.next &&\n state.next.length > 1 &&\n Iana.LanguageSubtags.Validate.extendedLanguageRange.isWellFormed(state.next)\n ) {\n values.push(state.next);\n state.next = state.subtags.shift();\n }\n\n if (state.next !== undefined) {\n return fail(`${state.next}: malformed private-use subtag`);\n } else if (values.length < 1) {\n return fail(`${state.tag}: private-use tag must have at least one subtag.`);\n }\n\n state.parsedSubtags.privateUse = values as Iana.LanguageSubtags.ExtendedLanguageRange[];\n }\n return succeed(state.parsedSubtags);\n }\n\n /**\n * Verifies {@link Bcp47.ParserState | parser state} at the end of a parse operation.\n * @param state - The {@link Bcp47.ParserState | current state} of the\n * parse operation.\n * @returns `Success` if the tag was fully consumed, or `Failure` with details\n * if unexpected subtags remain to be parsed.\n * @internal\n */\n protected static _parseTagEnd(state: IParserState): Result<ISubtags> {\n if (state.next !== undefined) {\n return fail(`${state.next}: unexpected subtag`);\n }\n return succeed(state.parsedSubtags);\n }\n}\n"]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
import { LanguageTag } from '../languageTag';
|
|
23
|
+
import { LanguageSimilarityMatcher } from './similarity';
|
|
24
|
+
/**
|
|
25
|
+
* Default values for a{@link Bcp47.LanguageFilterOptions}.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export const defaultLanguageChooserOptions = Object.freeze({
|
|
29
|
+
use: 'availableLanguage',
|
|
30
|
+
filter: 'primaryLanguage'
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Helper to compare a list of 'desired' languages to a list of 'available' language
|
|
34
|
+
* and return the intersection in order of preference, taking tag semantics into account.
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export class LanguageChooser {
|
|
38
|
+
constructor(iana) {
|
|
39
|
+
this._matcher = new LanguageSimilarityMatcher(iana);
|
|
40
|
+
}
|
|
41
|
+
chooseLanguageTagsWithDetails(desiredLanguages, availableLanguages, options) {
|
|
42
|
+
var _a;
|
|
43
|
+
const matched = new Map();
|
|
44
|
+
const decrement = desiredLanguages.length < 10 ? 0.1 : 1.0 / desiredLanguages.length;
|
|
45
|
+
let base = 1.0;
|
|
46
|
+
// fill any missing fields from the default
|
|
47
|
+
options = Object.assign(Object.assign({}, defaultLanguageChooserOptions), options);
|
|
48
|
+
for (const want of desiredLanguages) {
|
|
49
|
+
base -= decrement;
|
|
50
|
+
for (const have of availableLanguages) {
|
|
51
|
+
const similarity = this._matcher.matchLanguageTags(want, have);
|
|
52
|
+
if (similarity > 0.0) {
|
|
53
|
+
const quality = base + similarity * decrement;
|
|
54
|
+
const languageTag = options.use === 'availableLanguage' ? have : want;
|
|
55
|
+
const tag = languageTag.tag;
|
|
56
|
+
const key = options.filter === 'primaryLanguage' ? (_a = languageTag.subtags.primaryLanguage) !== null && _a !== void 0 ? _a : tag : tag;
|
|
57
|
+
const match = {
|
|
58
|
+
quality,
|
|
59
|
+
tag,
|
|
60
|
+
languageTag
|
|
61
|
+
};
|
|
62
|
+
const existing = matched.get(key);
|
|
63
|
+
if (!existing || existing.quality < quality) {
|
|
64
|
+
matched.set(key, match);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const values = Array.from(matched.values());
|
|
70
|
+
if (values.length > 1) {
|
|
71
|
+
// want descending order
|
|
72
|
+
values.sort((m1, m2) => m2.quality - m1.quality);
|
|
73
|
+
}
|
|
74
|
+
else if (values.length === 0 && options.ultimateFallback) {
|
|
75
|
+
const languageTag = options.ultimateFallback instanceof LanguageTag
|
|
76
|
+
? options.ultimateFallback
|
|
77
|
+
: LanguageTag.create(options.ultimateFallback).orDefault();
|
|
78
|
+
if (languageTag) {
|
|
79
|
+
return [{ languageTag, tag: languageTag.tag, quality: 0 }];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return values;
|
|
83
|
+
}
|
|
84
|
+
filterLanguageTags(desiredLanguages, availableLanguages, options) {
|
|
85
|
+
return this.chooseLanguageTagsWithDetails(desiredLanguages, availableLanguages, options).map((t) => t.languageTag);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=chooser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chooser.js","sourceRoot":"","sources":["../../../../src/packlets/bcp47/match/chooser.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2022 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Iana from '../../iana';\n\nimport { ISubtags } from '../common';\nimport { LanguageTag } from '../languageTag';\nimport { LanguageSimilarityMatcher } from './similarity';\n\n/**\n * Represents a single matching filtered language.\n * @public\n */\nexport interface IMatchingLanguage {\n /**\n * Numeric indication of how well the language matches,\n * from perfect (`1.0`) to not at all (`0.0`). When\n * matching an ordered list, languages at the front of\n * the desired language list are always higher quality.\n */\n quality: number;\n /**\n * The `string` tag of the matched language.\n */\n tag: string;\n /**\n * The matched {@link Bcp47.LanguageTag | language tag}.\n */\n languageTag: LanguageTag;\n}\n\n/**\n * Options for {@link Bcp47.choose | language tag list filter} functions.\n * @public\n */\nexport interface ILanguageChooserOptions {\n /**\n * Indicates whether to return the matching language from the\n * desired list or the available list. Default is `'availableLanguage'`.\n */\n use?: 'desiredLanguage' | 'availableLanguage';\n\n /**\n * Indicates how to filter the language list - `'primaryLanguage'`\n * indicates the each primary language should appear only once in\n * the list in its most similar form. A filter value of `'none'`\n * reports all matching variants of any primary language in order\n * of similarity. Default is `'primaryLanguage'`\n */\n filter?: 'primaryLanguage' | 'none';\n\n /**\n * An optional {@link Bcp47.LanguageSpec | language specification}\n * indicating a language to be returned if the filter call would\n * otherwise return an empty list (i.e. no languages match).\n */\n ultimateFallback?: string | ISubtags | LanguageTag;\n}\n\n/**\n * Default values for a{@link Bcp47.LanguageFilterOptions}.\n * @public\n */\nexport const defaultLanguageChooserOptions: ILanguageChooserOptions = Object.freeze({\n use: 'availableLanguage',\n filter: 'primaryLanguage'\n});\n\n/**\n * Helper to compare a list of 'desired' languages to a list of 'available' language\n * and return the intersection in order of preference, taking tag semantics into account.\n * @public\n */\nexport class LanguageChooser {\n /**\n * @internal\n */\n protected readonly _matcher: LanguageSimilarityMatcher;\n\n public constructor(iana?: Iana.LanguageRegistries) {\n this._matcher = new LanguageSimilarityMatcher(iana);\n }\n\n public chooseLanguageTagsWithDetails(\n desiredLanguages: LanguageTag[],\n availableLanguages: LanguageTag[],\n options?: ILanguageChooserOptions\n ): IMatchingLanguage[] {\n const matched = new Map<string, IMatchingLanguage>();\n const decrement = desiredLanguages.length < 10 ? 0.1 : 1.0 / desiredLanguages.length;\n let base = 1.0;\n\n // fill any missing fields from the default\n options = { ...defaultLanguageChooserOptions, ...options };\n\n for (const want of desiredLanguages) {\n base -= decrement;\n for (const have of availableLanguages) {\n const similarity = this._matcher.matchLanguageTags(want, have);\n if (similarity > 0.0) {\n const quality = base + similarity * decrement;\n const languageTag = options.use === 'availableLanguage' ? have : want;\n const tag = languageTag.tag;\n const key = options.filter === 'primaryLanguage' ? languageTag.subtags.primaryLanguage ?? tag : tag;\n\n const match: IMatchingLanguage = {\n quality,\n tag,\n languageTag\n };\n\n const existing = matched.get(key);\n if (!existing || existing.quality < quality) {\n matched.set(key, match);\n }\n }\n }\n }\n\n const values = Array.from(matched.values());\n if (values.length > 1) {\n // want descending order\n values.sort((m1, m2) => m2.quality - m1.quality);\n } else if (values.length === 0 && options.ultimateFallback) {\n const languageTag =\n options.ultimateFallback instanceof LanguageTag\n ? options.ultimateFallback\n : LanguageTag.create(options.ultimateFallback).orDefault();\n if (languageTag) {\n return [{ languageTag, tag: languageTag.tag, quality: 0 }];\n }\n }\n return values;\n }\n\n public filterLanguageTags(\n desiredLanguages: LanguageTag[],\n availableLanguages: LanguageTag[],\n options?: ILanguageChooserOptions\n ): LanguageTag[] {\n return this.chooseLanguageTagsWithDetails(desiredLanguages, availableLanguages, options).map(\n (t) => t.languageTag\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
/* eslint-disable @rushstack/typedef-var */
|
|
23
|
+
/**
|
|
24
|
+
* Penalty for a mismatched value for some subtags.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export const subtagMismatchPenalty = {
|
|
28
|
+
private: 0.05,
|
|
29
|
+
extension: 0.04,
|
|
30
|
+
variant: 0.1
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Common levels of match quality for a single language match.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export const tagSimilarity = {
|
|
37
|
+
exact: 1.0,
|
|
38
|
+
variant: 0.9,
|
|
39
|
+
region: 0.8,
|
|
40
|
+
macroRegion: 0.65,
|
|
41
|
+
neutralRegion: 0.5,
|
|
42
|
+
preferredAffinity: 0.45,
|
|
43
|
+
affinity: 0.4,
|
|
44
|
+
preferredRegion: 0.35,
|
|
45
|
+
sibling: 0.3,
|
|
46
|
+
undetermined: 0.1,
|
|
47
|
+
none: 0
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/packlets/bcp47/match/common.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,2CAA2C;AAE3C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,GAAG;CACb,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;IACX,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,GAAG;IAClB,iBAAiB,EAAE,IAAI;IACvB,QAAQ,EAAE,GAAG;IACb,eAAe,EAAE,IAAI;IACrB,OAAO,EAAE,GAAG;IACZ,YAAY,EAAE,GAAG;IACjB,IAAI,EAAE,CAAC;CACR,CAAC","sourcesContent":["/*\n * Copyright (c) 2022 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n/* eslint-disable @rushstack/typedef-var */\n\n/**\n * Penalty for a mismatched value for some subtags.\n * @public\n */\nexport const subtagMismatchPenalty = {\n private: 0.05,\n extension: 0.04,\n variant: 0.1\n};\n\n/**\n * Common levels of match quality for a single language match.\n * @public\n */\nexport const tagSimilarity = {\n exact: 1.0,\n variant: 0.9,\n region: 0.8,\n macroRegion: 0.65,\n neutralRegion: 0.5,\n preferredAffinity: 0.45,\n affinity: 0.4,\n preferredRegion: 0.35,\n sibling: 0.3,\n undetermined: 0.1,\n none: 0\n};\n\n/**\n * Numeric representation of the quality of a language match.\n * Range is 0 (no match) to 1 (exact match).\n * @public\n */\nexport type TagSimilarity = keyof typeof tagSimilarity;\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
// istanbul ignore file
|
|
23
|
+
export { LanguageChooser } from './chooser';
|
|
24
|
+
export * from './common';
|
|
25
|
+
export { LanguageSimilarityMatcher } from './similarity';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/packlets/bcp47/match/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,uBAAuB;AAEvB,OAAO,EAA8C,eAAe,EAAE,MAAM,WAAW,CAAC;AACxF,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC","sourcesContent":["/*\n * Copyright (c) 2022 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// istanbul ignore file\n\nexport { ILanguageChooserOptions, IMatchingLanguage, LanguageChooser } from './chooser';\nexport * from './common';\nexport { LanguageSimilarityMatcher } from './similarity';\n"]}
|