@fgv/ts-bcp47 0.5.0

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.
Files changed (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/bcp47/bcp47Subtags/converters.d.ts +9 -0
  4. package/bcp47/bcp47Subtags/converters.d.ts.map +1 -0
  5. package/bcp47/bcp47Subtags/converters.js +57 -0
  6. package/bcp47/bcp47Subtags/index.d.ts +5 -0
  7. package/bcp47/bcp47Subtags/index.d.ts.map +1 -0
  8. package/bcp47/bcp47Subtags/index.js +54 -0
  9. package/bcp47/bcp47Subtags/model.d.ts +18 -0
  10. package/bcp47/bcp47Subtags/model.d.ts.map +1 -0
  11. package/bcp47/bcp47Subtags/model.js +24 -0
  12. package/bcp47/bcp47Subtags/validate.d.ts +16 -0
  13. package/bcp47/bcp47Subtags/validate.d.ts.map +1 -0
  14. package/bcp47/bcp47Subtags/validate.js +74 -0
  15. package/bcp47/common.d.ts +38 -0
  16. package/bcp47/common.d.ts.map +1 -0
  17. package/bcp47/common.js +59 -0
  18. package/bcp47/helpers.d.ts +66 -0
  19. package/bcp47/helpers.d.ts.map +1 -0
  20. package/bcp47/helpers.js +103 -0
  21. package/bcp47/index.d.ts +7 -0
  22. package/bcp47/index.d.ts.map +1 -0
  23. package/bcp47/index.js +27 -0
  24. package/bcp47/languageTag.d.ts +208 -0
  25. package/bcp47/languageTag.d.ts.map +1 -0
  26. package/bcp47/languageTag.js +342 -0
  27. package/bcp47/languageTagParser.d.ts +123 -0
  28. package/bcp47/languageTagParser.d.ts.map +1 -0
  29. package/bcp47/languageTagParser.js +310 -0
  30. package/bcp47/match/chooser.d.ts +70 -0
  31. package/bcp47/match/chooser.d.ts.map +1 -0
  32. package/bcp47/match/chooser.js +92 -0
  33. package/bcp47/match/common.d.ts +24 -0
  34. package/bcp47/match/common.d.ts.map +1 -0
  35. package/bcp47/match/common.js +42 -0
  36. package/bcp47/match/index.d.ts +4 -0
  37. package/bcp47/match/index.d.ts.map +1 -0
  38. package/bcp47/match/index.js +45 -0
  39. package/bcp47/match/similarity.d.ts +24 -0
  40. package/bcp47/match/similarity.d.ts.map +1 -0
  41. package/bcp47/match/similarity.js +230 -0
  42. package/bcp47/normalization/baseNormalizer.d.ts +36 -0
  43. package/bcp47/normalization/baseNormalizer.d.ts.map +1 -0
  44. package/bcp47/normalization/baseNormalizer.js +114 -0
  45. package/bcp47/normalization/canonicalNormalizer.d.ts +22 -0
  46. package/bcp47/normalization/canonicalNormalizer.d.ts.map +1 -0
  47. package/bcp47/normalization/canonicalNormalizer.js +110 -0
  48. package/bcp47/normalization/common.d.ts +23 -0
  49. package/bcp47/normalization/common.d.ts.map +1 -0
  50. package/bcp47/normalization/common.js +82 -0
  51. package/bcp47/normalization/index.d.ts +5 -0
  52. package/bcp47/normalization/index.d.ts.map +1 -0
  53. package/bcp47/normalization/index.js +47 -0
  54. package/bcp47/normalization/normalizeTag.d.ts +59 -0
  55. package/bcp47/normalization/normalizeTag.d.ts.map +1 -0
  56. package/bcp47/normalization/normalizeTag.js +105 -0
  57. package/bcp47/normalization/preferredTagNormalizer.d.ts +26 -0
  58. package/bcp47/normalization/preferredTagNormalizer.d.ts.map +1 -0
  59. package/bcp47/normalization/preferredTagNormalizer.js +178 -0
  60. package/bcp47/overrides/converters.d.ts +19 -0
  61. package/bcp47/overrides/converters.d.ts.map +1 -0
  62. package/bcp47/overrides/converters.js +75 -0
  63. package/bcp47/overrides/defaultRegistries.d.ts +12 -0
  64. package/bcp47/overrides/defaultRegistries.d.ts.map +1 -0
  65. package/bcp47/overrides/defaultRegistries.js +42 -0
  66. package/bcp47/overrides/index.d.ts +3 -0
  67. package/bcp47/overrides/index.d.ts.map +1 -0
  68. package/bcp47/overrides/index.js +30 -0
  69. package/bcp47/overrides/model.d.ts +11 -0
  70. package/bcp47/overrides/model.d.ts.map +1 -0
  71. package/bcp47/overrides/model.js +24 -0
  72. package/bcp47/overrides/overridesRegistry.d.ts +32 -0
  73. package/bcp47/overrides/overridesRegistry.d.ts.map +1 -0
  74. package/bcp47/overrides/overridesRegistry.js +101 -0
  75. package/bcp47/validation/baseValidator.d.ts +35 -0
  76. package/bcp47/validation/baseValidator.d.ts.map +1 -0
  77. package/bcp47/validation/baseValidator.js +111 -0
  78. package/bcp47/validation/common.d.ts +23 -0
  79. package/bcp47/validation/common.d.ts.map +1 -0
  80. package/bcp47/validation/common.js +84 -0
  81. package/bcp47/validation/index.d.ts +7 -0
  82. package/bcp47/validation/index.d.ts.map +1 -0
  83. package/bcp47/validation/index.js +51 -0
  84. package/bcp47/validation/isCanonical.d.ts +22 -0
  85. package/bcp47/validation/isCanonical.d.ts.map +1 -0
  86. package/bcp47/validation/isCanonical.js +101 -0
  87. package/bcp47/validation/isInPreferredForm.d.ts +15 -0
  88. package/bcp47/validation/isInPreferredForm.d.ts.map +1 -0
  89. package/bcp47/validation/isInPreferredForm.js +73 -0
  90. package/bcp47/validation/isStrictlyValid.d.ts +18 -0
  91. package/bcp47/validation/isStrictlyValid.d.ts.map +1 -0
  92. package/bcp47/validation/isStrictlyValid.js +98 -0
  93. package/bcp47/validation/isValid.d.ts +24 -0
  94. package/bcp47/validation/isValid.d.ts.map +1 -0
  95. package/bcp47/validation/isValid.js +115 -0
  96. package/bcp47/validation/isWellFormed.d.ts +22 -0
  97. package/bcp47/validation/isWellFormed.d.ts.map +1 -0
  98. package/bcp47/validation/isWellFormed.js +98 -0
  99. package/bcp47/validation/validateTag.d.ts +97 -0
  100. package/bcp47/validation/validateTag.d.ts.map +1 -0
  101. package/bcp47/validation/validateTag.js +159 -0
  102. package/data/bcp/overrides.json +21 -0
  103. package/data/iana/language-subtags.json +77295 -0
  104. package/data/iana/language-tag-extensions.json +42 -0
  105. package/data/unsd/m49.csv +250 -0
  106. package/iana/common/converters.d.ts +31 -0
  107. package/iana/common/converters.d.ts.map +1 -0
  108. package/iana/common/converters.js +84 -0
  109. package/iana/common/model.d.ts +30 -0
  110. package/iana/common/model.d.ts.map +1 -0
  111. package/iana/common/model.js +24 -0
  112. package/iana/common/registeredItems.d.ts +30 -0
  113. package/iana/common/registeredItems.d.ts.map +1 -0
  114. package/iana/common/registeredItems.js +124 -0
  115. package/iana/common/utils.d.ts +7 -0
  116. package/iana/common/utils.d.ts.map +1 -0
  117. package/iana/common/utils.js +34 -0
  118. package/iana/common/validate.d.ts +19 -0
  119. package/iana/common/validate.d.ts.map +1 -0
  120. package/iana/common/validate.js +61 -0
  121. package/iana/converters.d.ts +4 -0
  122. package/iana/converters.d.ts.map +1 -0
  123. package/iana/converters.js +54 -0
  124. package/iana/defaultRegistries.d.ts +12 -0
  125. package/iana/defaultRegistries.d.ts.map +1 -0
  126. package/iana/defaultRegistries.js +42 -0
  127. package/iana/index.d.ts +9 -0
  128. package/iana/index.d.ts.map +1 -0
  129. package/iana/index.js +64 -0
  130. package/iana/jar/converters.d.ts +4 -0
  131. package/iana/jar/converters.d.ts.map +1 -0
  132. package/iana/jar/converters.js +54 -0
  133. package/iana/jar/index.d.ts +4 -0
  134. package/iana/jar/index.d.ts.map +1 -0
  135. package/iana/jar/index.js +52 -0
  136. package/iana/jar/jarConverters.d.ts +17 -0
  137. package/iana/jar/jarConverters.d.ts.map +1 -0
  138. package/iana/jar/jarConverters.js +85 -0
  139. package/iana/jar/jarModel.d.ts +11 -0
  140. package/iana/jar/jarModel.d.ts.map +1 -0
  141. package/iana/jar/jarModel.js +24 -0
  142. package/iana/jar/language-subtags/converters.d.ts +4 -0
  143. package/iana/jar/language-subtags/converters.d.ts.map +1 -0
  144. package/iana/jar/language-subtags/converters.js +52 -0
  145. package/iana/jar/language-subtags/index.d.ts +4 -0
  146. package/iana/jar/language-subtags/index.d.ts.map +1 -0
  147. package/iana/jar/language-subtags/index.js +54 -0
  148. package/iana/jar/language-subtags/model.d.ts +4 -0
  149. package/iana/jar/language-subtags/model.d.ts.map +1 -0
  150. package/iana/jar/language-subtags/model.js +52 -0
  151. package/iana/jar/language-subtags/registry/converters.d.ts +10 -0
  152. package/iana/jar/language-subtags/registry/converters.d.ts.map +1 -0
  153. package/iana/jar/language-subtags/registry/converters.js +58 -0
  154. package/iana/jar/language-subtags/registry/index.d.ts +4 -0
  155. package/iana/jar/language-subtags/registry/index.d.ts.map +1 -0
  156. package/iana/jar/language-subtags/registry/index.js +55 -0
  157. package/iana/jar/language-subtags/registry/model.d.ts +88 -0
  158. package/iana/jar/language-subtags/registry/model.d.ts.map +1 -0
  159. package/iana/jar/language-subtags/registry/model.js +41 -0
  160. package/iana/jar/language-subtags/tags/converters.d.ts +55 -0
  161. package/iana/jar/language-subtags/tags/converters.d.ts.map +1 -0
  162. package/iana/jar/language-subtags/tags/converters.js +128 -0
  163. package/iana/jar/language-subtags/tags/index.d.ts +5 -0
  164. package/iana/jar/language-subtags/tags/index.d.ts.map +1 -0
  165. package/iana/jar/language-subtags/tags/index.js +56 -0
  166. package/iana/jar/language-subtags/tags/model.d.ts +42 -0
  167. package/iana/jar/language-subtags/tags/model.d.ts.map +1 -0
  168. package/iana/jar/language-subtags/tags/model.js +24 -0
  169. package/iana/jar/language-subtags/tags/tagValidation.d.ts +11 -0
  170. package/iana/jar/language-subtags/tags/tagValidation.d.ts.map +1 -0
  171. package/iana/jar/language-subtags/tags/tagValidation.js +70 -0
  172. package/iana/jar/language-subtags/tags/validate.d.ts +36 -0
  173. package/iana/jar/language-subtags/tags/validate.d.ts.map +1 -0
  174. package/iana/jar/language-subtags/tags/validate.js +87 -0
  175. package/iana/jar/model.d.ts +4 -0
  176. package/iana/jar/model.d.ts.map +1 -0
  177. package/iana/jar/model.js +54 -0
  178. package/iana/language-subtags/common.d.ts +5 -0
  179. package/iana/language-subtags/common.d.ts.map +1 -0
  180. package/iana/language-subtags/common.js +24 -0
  181. package/iana/language-subtags/converters.d.ts +52 -0
  182. package/iana/language-subtags/converters.d.ts.map +1 -0
  183. package/iana/language-subtags/converters.js +200 -0
  184. package/iana/language-subtags/index.d.ts +7 -0
  185. package/iana/language-subtags/index.d.ts.map +1 -0
  186. package/iana/language-subtags/index.js +60 -0
  187. package/iana/language-subtags/jarConverters.d.ts +55 -0
  188. package/iana/language-subtags/jarConverters.d.ts.map +1 -0
  189. package/iana/language-subtags/jarConverters.js +213 -0
  190. package/iana/language-subtags/model.d.ts +144 -0
  191. package/iana/language-subtags/model.d.ts.map +1 -0
  192. package/iana/language-subtags/model.js +24 -0
  193. package/iana/language-subtags/scope.d.ts +77 -0
  194. package/iana/language-subtags/scope.d.ts.map +1 -0
  195. package/iana/language-subtags/scope.js +179 -0
  196. package/iana/language-subtags/subtagRegistry.d.ts +36 -0
  197. package/iana/language-subtags/subtagRegistry.d.ts.map +1 -0
  198. package/iana/language-subtags/subtagRegistry.js +139 -0
  199. package/iana/language-subtags/validate.d.ts +2 -0
  200. package/iana/language-subtags/validate.d.ts.map +1 -0
  201. package/iana/language-subtags/validate.js +39 -0
  202. package/iana/language-tag-extensions/converters.d.ts +23 -0
  203. package/iana/language-tag-extensions/converters.d.ts.map +1 -0
  204. package/iana/language-tag-extensions/converters.js +87 -0
  205. package/iana/language-tag-extensions/extensionsRegistry.d.ts +26 -0
  206. package/iana/language-tag-extensions/extensionsRegistry.d.ts.map +1 -0
  207. package/iana/language-tag-extensions/extensionsRegistry.js +94 -0
  208. package/iana/language-tag-extensions/extensionsScope.d.ts +20 -0
  209. package/iana/language-tag-extensions/extensionsScope.d.ts.map +1 -0
  210. package/iana/language-tag-extensions/extensionsScope.js +77 -0
  211. package/iana/language-tag-extensions/index.d.ts +6 -0
  212. package/iana/language-tag-extensions/index.d.ts.map +1 -0
  213. package/iana/language-tag-extensions/index.js +56 -0
  214. package/iana/language-tag-extensions/jarConverters.d.ts +28 -0
  215. package/iana/language-tag-extensions/jarConverters.d.ts.map +1 -0
  216. package/iana/language-tag-extensions/jarConverters.js +102 -0
  217. package/iana/language-tag-extensions/model.d.ts +40 -0
  218. package/iana/language-tag-extensions/model.d.ts.map +1 -0
  219. package/iana/language-tag-extensions/model.js +24 -0
  220. package/iana/language-tag-extensions/validate.d.ts +7 -0
  221. package/iana/language-tag-extensions/validate.d.ts.map +1 -0
  222. package/iana/language-tag-extensions/validate.js +36 -0
  223. package/iana/languageRegistries.d.ts +13 -0
  224. package/iana/languageRegistries.d.ts.map +1 -0
  225. package/iana/languageRegistries.js +49 -0
  226. package/iana/model.d.ts +4 -0
  227. package/iana/model.d.ts.map +1 -0
  228. package/iana/model.js +54 -0
  229. package/iana/validate.d.ts +2 -0
  230. package/iana/validate.d.ts.map +1 -0
  231. package/iana/validate.js +39 -0
  232. package/index.d.ts +5 -0
  233. package/index.d.ts.map +1 -0
  234. package/index.js +54 -0
  235. package/package.json +64 -0
  236. package/unsd/areas.d.ts +29 -0
  237. package/unsd/areas.d.ts.map +1 -0
  238. package/unsd/areas.js +96 -0
  239. package/unsd/common.d.ts +49 -0
  240. package/unsd/common.d.ts.map +1 -0
  241. package/unsd/common.js +24 -0
  242. package/unsd/csv/converters.d.ts +21 -0
  243. package/unsd/csv/converters.d.ts.map +1 -0
  244. package/unsd/csv/converters.js +70 -0
  245. package/unsd/csv/index.d.ts +4 -0
  246. package/unsd/csv/index.d.ts.map +1 -0
  247. package/unsd/csv/index.js +52 -0
  248. package/unsd/csv/model.d.ts +22 -0
  249. package/unsd/csv/model.d.ts.map +1 -0
  250. package/unsd/csv/model.js +24 -0
  251. package/unsd/defaultRegistries.d.ts +12 -0
  252. package/unsd/defaultRegistries.d.ts.map +1 -0
  253. package/unsd/defaultRegistries.js +42 -0
  254. package/unsd/index.d.ts +4 -0
  255. package/unsd/index.d.ts.map +1 -0
  256. package/unsd/index.js +44 -0
  257. package/unsd/regionCodes.d.ts +38 -0
  258. package/unsd/regionCodes.d.ts.map +1 -0
  259. package/unsd/regionCodes.js +111 -0
  260. package/unsd/regions.d.ts +21 -0
  261. package/unsd/regions.d.ts.map +1 -0
  262. package/unsd/regions.js +77 -0
  263. package/utils/index.d.ts +3 -0
  264. package/utils/index.d.ts.map +1 -0
  265. package/utils/index.js +40 -0
  266. package/utils/jsonHelpers.d.ts +2 -0
  267. package/utils/jsonHelpers.d.ts.map +1 -0
  268. package/utils/jsonHelpers.js +29 -0
  269. package/utils/validationHelpers.d.ts +47 -0
  270. package/utils/validationHelpers.d.ts.map +1 -0
  271. package/utils/validationHelpers.js +88 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Erik Fortune
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ <div align="center">
2
+ <h1>ts-utils</h1>
3
+ Typescript Utilities for BCP-47 Language Tags
4
+ </div>
5
+
6
+ <hr/>
7
+
8
+ ## Summary
9
+
10
+ Typescript utilities for parsing, manipulating and comparing BCP-47 language tags.
11
+
12
+ ## Installation
13
+
14
+ with npm:
15
+ ```sh
16
+ npm install @fgv/ts-bcp47
17
+ ```
18
+
19
+ ## API Documentation
20
+ Extracted API documentation is [here](./docs/ts-bcp47.md)
21
+
22
+ ## Overview
23
+
24
+ Classes and functions to:
25
+ - parse and validate BCP-47 ([RFC 5646](https://www.rfc-editor.org/rfc/rfc5646)) language tags
26
+ - normalize BCP-47 language tags into [canonical](#canonical-form) or [preferred form](#preferred-form).
27
+ - compare BCP-47 language tags
28
+
29
+ ### TL; DR
30
+ For those who already understand BCP-47 language tags and just want to get started, here are a few examples:
31
+ ```ts
32
+ import { Bcp47 } from '@fgv/ts-bcp47';
33
+
34
+ // parse a tag to extract primary language and region
35
+ const {primaryLanguage, region} = Bcp47.tag('en-us').orThrow().subtags;
36
+ // primaryLanguage is 'en', region is 'us'
37
+
38
+ // parse a tag to extract primary language and region in canonical form
39
+ const {primaryLanguage, region} = Bcp47.tag('en-us', { normalization: 'canonical' }).orThrow().subtags;
40
+ // primary language is 'en', region is 'US'
41
+
42
+ // normalize a tag to fully-preferred form
43
+ const preferred = Bcp47.tag('art-lojban', { normalization: 'preferred' }).orThrow().tag;
44
+ // preferred is "jbo"
45
+
46
+ // tags match regardless of case
47
+ const match = Bcp47.similarity('es-MX', 'es-mx').orThrow(); // 1.0 (exact)
48
+
49
+ // suppressed script matches explicit script
50
+ const match = Bcp47.similarity('es-MX', 'es-latn-mx').orThrow(); // 1.0 (exact)
51
+
52
+ // macro-region matches contained region well
53
+ const match = Bcp47.similarity('es-419', 'es-MX').orThrow(); // 0.7 (macroRegion)
54
+ const match = Bcp47.similarity('es-419', 'es-ES').orThrow(); // 0.3 (sibling)
55
+
56
+ // region matches neutral fairly well
57
+ const match = Bcp47.similarity('es', 'es-MX').orThrow(); // 0.6 (neutral)
58
+
59
+ // unlike tags do not match
60
+ const match = Bcp47.similarity('en', 'es').orThrow(); // 0.0 (none)
61
+
62
+ // different scripts do not match
63
+ const match = Bcp47.similarity('zh-Hans', 'zh-Hant').orThrow(); // 0.0 (none)
64
+ ```
65
+
66
+ *Note:* This library uses the `Result` pattern, so the return value from any method that might fail is a `Result` object that must be tested for success or failure. These examples use either [orThrow](https://github.com/DidjaRedo/ts-utils/blob/master/docs/ts-utils.iresult.orthrow.md) or [orDefault](https://github.com/DidjaRedo/ts-utils/blob/master/docs/ts-utils.iresult.ordefault.md) to convert an error result to either an exception or undefined.
67
+
68
+ ### Anatomy of a BCP-47 language tag.
69
+ As specified in [RFC 5646](https://www.rfc-editor.org/rfc/rfc5646), a language tag consists of a series of `subtags` (mostly optional), each of which describes some aspect of the language being referenced.
70
+
71
+ #### Subtags
72
+ The full set of subtags that make up a language tag are:
73
+ - [primary language](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.1)
74
+ - [extlang](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.2)
75
+ - [script](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.3)
76
+ - [region](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.4)
77
+ - [variants](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.4)
78
+ - [extensions](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.6)
79
+ - [private-use](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.7)
80
+
81
+ #### Grandfathered Tags
82
+ The RFC allows for a handful of grandfathered tags which do not meet the current specification. Those tags are recognized in their entirety and are not composed of subtags, so for grandfathered tags only, even `primary language` is undefined.
83
+
84
+ ### Validation
85
+ Tag validation considers the tag in its current form and never changes the tag itself.
86
+
87
+ The specification defines two levels of [conformance](https://www.rfc-editor.org/rfc/rfc5646#section-2.2.9) for language, and this library defines a third.
88
+ #### Well-Formed Tags
89
+ A `well-formed` tag meets the basic syntactic requirements of the specification, but might not be valid in terms of content.
90
+ #### Valid Tags
91
+ A `valid` tag meets both the syntactic and semantic requirements of the specification, meaning that either all subtags or full tag (in the case of grandfathered tags) are registered in the [IANA language subtag registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry), and neither extension nor variant tags are repeated.
92
+ #### Strictly Valid Tags
93
+ A `strictly valid` tags is valid according to the specification and also meets the rules for variant and extlang prefixes defined by the specification and recorded in the language registry.
94
+ #### Examples
95
+ Some examples:
96
+ - `eng-US` is well-formed because it meets the language tag syntax but is not valid because `eng` is not a registered language subtag.
97
+ - `en-US` is both well-formed and valid, because `en` is a registered language subtag.
98
+ - `es-valencia-valencia` is well-formed but not valid, because the `valencia` extension subtag is repeated.
99
+ - `es-valencia` is well-formed and valid, but it is not strictly-valid because language subtag registry defines a `ca` prefix for the `valencia` subtag.
100
+ - `ca-valencia` is well-formed, valid, and strictly valid.
101
+
102
+ ### Normalization
103
+ Normalization transforms a tag to produce a new tag which is semantically identical, but preferred for some reason.
104
+ #### Not-normalized
105
+ A non-normalized must be [`well-formed`](#well-formed-tags) and might be [`valid`](#valid-tags) or [`strictly-valid`](#strictly-valid-tags) but it does not use the letter case conventions recommended in the spec.
106
+
107
+ #### Canonical Form
108
+ A tag in canonical form meets all of the letter case conventions recommended by the specification, in addition to being at least [`well-formed`](#well-formed-tags).
109
+
110
+ #### Preferred Form
111
+ In addition to being [`strictly-valid`](#strictly-valid-tags) and [canonical](#canonical-form), tags
112
+ in preferred form do not have any deprecated, redundant or suppressed subtags.
113
+
114
+ #### Examples
115
+ - `zh-cmn-hans` is strictly valid, but not canonical or preferred.
116
+ - `zh-cmn-Hans` is strictly valid and canonical, but not preferred, because the subtag registry lists `zh-cmn-Hans` as redundant, with the preferred value `cmn-Hans`.
117
+ - `cmn-Hans` is strictly valid, canonical and preferred.
118
+ - `en-latn-us` is strictly valid, but not canonical or preferred.
119
+ - `en-Latn-US` is strictly valid and canonical, but not preferred, because the subtag registry lists `Latn` as the suppressed script for the `en` language.
120
+ - `en-US` is strictly valid, canonical and preferred.
121
+
122
+ ### Tag Matching
123
+ The [`match`](docs/ts-bcp47.bcp47.match.md) function matches language tags, using semantic similarity, unlike [RFC 4647](https://www.rfc-editor.org/rfc/rfc4647.html), which relies on purely syntactic rules. This semantic match yields much better results in many cases.
124
+
125
+ For any given language tag pair, the `match` function returns a similarity score in the range `0.0` (no similarity) to `1.0` (exact match).
126
+
127
+ The degrees of similarity are (from most to least similar):
128
+ - `exact` (`1.0`) - The two language tags are semantically identical.
129
+ - `variant` (`0.9`) - The tags vary only in extension or private subtags.
130
+ - `region` (`0.8`) - The tags match on language, script and region but vary in variant, extension or private-use subtags.
131
+ - `macroRegion` (`0.7`) - The tags match on language and script, and one of the region subtags is a macro-region (e.g. `419` for Latin America) which encompasses the second region tag.
132
+ - `neutralRegion` (`0.6`) - The tags match on language and script, and only one of the tags contains a region subtag.
133
+ - `affinity` (`0.5`) - The tags match on language and script, and two region subtags have an orthographic affinity. Orthographic affinity is defined in this package in the [`overrides.json`](./data/bcp/overrides.json) file.
134
+ - `preferredRegion` (`0.4`) - The tags match on language and script, and one of the tags is the preferred region subtag for the language. Preferred region is also defined in this package in [`overrides.json`](./data/bcp/overrides.json).
135
+ - `sibling` (`0.3`) - The tags match on language and script but both have region tags that are otherwise unrelated.
136
+ - `undetermined` (`0.2`) - One of the languages is the special language `und`.
137
+ - `none` (`0.0`) - The tags do not match at all.
138
+
139
+ ## See Also
140
+ [RFC 5646 - Tags for Identifying Languages](https://www.rfc-editor.org/rfc/rfc5646)
141
+ [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export declare const extensionSubtag: import("@fgv/ts-utils").Converter<import("./model").ExtensionSubtag, unknown>;
5
+ /**
6
+ * @internal
7
+ */
8
+ export declare const privateUsePrefix: import("@fgv/ts-utils").Converter<import("./model").PrivateUsePrefix, unknown>;
9
+ //# sourceMappingURL=converters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/bcp47/bcp47Subtags/converters.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,eAAO,MAAM,eAAe,+EAAqC,CAAC;AAClE;;GAEG;AACH,eAAO,MAAM,gBAAgB,gFAAsC,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2022 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.privateUsePrefix = exports.extensionSubtag = void 0;
48
+ const Validate = __importStar(require("./validate"));
49
+ /**
50
+ * @internal
51
+ */
52
+ exports.extensionSubtag = Validate.extensionSubtag.converter;
53
+ /**
54
+ * @internal
55
+ */
56
+ exports.privateUsePrefix = Validate.privateUsePrefix.converter;
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iY3A0Ny9iY3A0N1N1YnRhZ3MvY29udmVydGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILHFEQUF1QztBQUV2Qzs7R0FFRztBQUNVLFFBQUEsZUFBZSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDO0FBQ2xFOztHQUVHO0FBQ1UsUUFBQSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAyMiBFcmlrIEZvcnR1bmVcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiAqIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCAqIGFzIFZhbGlkYXRlIGZyb20gJy4vdmFsaWRhdGUnO1xuXG4vKipcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgZXh0ZW5zaW9uU3VidGFnID0gVmFsaWRhdGUuZXh0ZW5zaW9uU3VidGFnLmNvbnZlcnRlcjtcbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBwcml2YXRlVXNlUHJlZml4ID0gVmFsaWRhdGUucHJpdmF0ZVVzZVByZWZpeC5jb252ZXJ0ZXI7XG4iXX0=
@@ -0,0 +1,5 @@
1
+ import * as Converters from './converters';
2
+ import * as Model from './model';
3
+ import * as Validate from './validate';
4
+ export { Converters, Model, Validate };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bcp47/bcp47Subtags/index.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2022 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.Validate = exports.Model = exports.Converters = void 0;
48
+ const Converters = __importStar(require("./converters"));
49
+ exports.Converters = Converters;
50
+ const Model = __importStar(require("./model"));
51
+ exports.Model = Model;
52
+ const Validate = __importStar(require("./validate"));
53
+ exports.Validate = Validate;
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmNwNDcvYmNwNDdTdWJ0YWdzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgseURBQTJDO0FBSWxDLGdDQUFVO0FBSG5CLCtDQUFpQztBQUdaLHNCQUFLO0FBRjFCLHFEQUF1QztBQUVYLDRCQUFRIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAyMiBFcmlrIEZvcnR1bmVcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiAqIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCAqIGFzIENvbnZlcnRlcnMgZnJvbSAnLi9jb252ZXJ0ZXJzJztcbmltcG9ydCAqIGFzIE1vZGVsIGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0ICogYXMgVmFsaWRhdGUgZnJvbSAnLi92YWxpZGF0ZSc7XG5cbmV4cG9ydCB7IENvbnZlcnRlcnMsIE1vZGVsLCBWYWxpZGF0ZSB9O1xuIl19
@@ -0,0 +1,18 @@
1
+ import { Brand } from '@fgv/ts-utils';
2
+ /**
3
+ * @internal
4
+ */
5
+ export type ExtensionSubtag = Brand<string, 'ExtensionSubtag'>;
6
+ /**
7
+ * @internal
8
+ */
9
+ export type PrivateUseSubtag = Brand<string, 'PrivateUseSubtag'>;
10
+ /**
11
+ * @internal
12
+ */
13
+ export type PrivateUsePrefix = Brand<string, 'PrivateUsePrefix'>;
14
+ /**
15
+ * @internal
16
+ */
17
+ export { ExtensionSingleton } from '../../iana/language-tag-extensions/model';
18
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/bcp47/bcp47Subtags/model.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEjE;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2022 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmNwNDcvYmNwNDdTdWJ0YWdzL21vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkciLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDIyIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IHsgQnJhbmQgfSBmcm9tICdAZmd2L3RzLXV0aWxzJztcblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IHR5cGUgRXh0ZW5zaW9uU3VidGFnID0gQnJhbmQ8c3RyaW5nLCAnRXh0ZW5zaW9uU3VidGFnJz47XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCB0eXBlIFByaXZhdGVVc2VTdWJ0YWcgPSBCcmFuZDxzdHJpbmcsICdQcml2YXRlVXNlU3VidGFnJz47XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCB0eXBlIFByaXZhdGVVc2VQcmVmaXggPSBCcmFuZDxzdHJpbmcsICdQcml2YXRlVXNlUHJlZml4Jz47XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCB7IEV4dGVuc2lvblNpbmdsZXRvbiB9IGZyb20gJy4uLy4uL2lhbmEvbGFuZ3VhZ2UtdGFnLWV4dGVuc2lvbnMvbW9kZWwnO1xuIl19
@@ -0,0 +1,16 @@
1
+ import * as ExtensionRegistry from '../../iana/language-tag-extensions';
2
+ import * as Subtags from './model';
3
+ import { RegExpValidationHelpers } from '../../utils';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare const extensionSingleton: RegExpValidationHelpers<ExtensionRegistry.Model.ExtensionSingleton, unknown>;
8
+ /**
9
+ * @public
10
+ */
11
+ export declare const extensionSubtag: RegExpValidationHelpers<Subtags.ExtensionSubtag, unknown>;
12
+ /**
13
+ * @public
14
+ */
15
+ export declare const privateUsePrefix: RegExpValidationHelpers<Subtags.PrivateUsePrefix, unknown>;
16
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/bcp47/bcp47Subtags/validate.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,iBAAiB,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAKtD;;GAEG;AACH,eAAO,MAAM,kBAAkB,8EAAgD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,eAAe,2DAK1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,4DAK3B,CAAC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2021 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.privateUsePrefix = exports.extensionSubtag = exports.extensionSingleton = void 0;
48
+ const ExtensionRegistry = __importStar(require("../../iana/language-tag-extensions"));
49
+ const utils_1 = require("../../utils");
50
+ const tagValidation_1 = require("../../iana/jar/language-subtags/tags/tagValidation");
51
+ const ts_utils_1 = require("@fgv/ts-utils");
52
+ /**
53
+ * @public
54
+ */
55
+ exports.extensionSingleton = ExtensionRegistry.Validate.extensionSingleton;
56
+ /**
57
+ * @public
58
+ */
59
+ exports.extensionSubtag = new utils_1.RegExpValidationHelpers({
60
+ description: 'language tag extension subtag',
61
+ wellFormed: /^([a-zA-Z0-9]{2,8})(-[a-zA-Z0-9]{2,8})*$/,
62
+ canonical: /^([a-z0-9]{2,8})(-[a-z0-9]{2,8})*$/,
63
+ toCanonical: (from) => tagValidation_1.TagValidationHelpers.toCanonicalTag(from),
64
+ });
65
+ /**
66
+ * @public
67
+ */
68
+ exports.privateUsePrefix = new utils_1.RegExpValidationHelpers({
69
+ description: 'language tag private-use prefix',
70
+ wellFormed: /^[xX]$/,
71
+ canonical: /^x$/,
72
+ toCanonical: (from) => (0, ts_utils_1.succeed)(from.toLowerCase()),
73
+ });
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmNwNDcvYmNwNDdTdWJ0YWdzL3ZhbGlkYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsc0ZBQXdFO0FBR3hFLHVDQUFzRDtBQUN0RCxzRkFBMEY7QUFFMUYsNENBQXdDO0FBRXhDOztHQUVHO0FBQ1UsUUFBQSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUM7QUFFaEY7O0dBRUc7QUFDVSxRQUFBLGVBQWUsR0FBRyxJQUFJLCtCQUF1QixDQUEwQjtJQUNoRixXQUFXLEVBQUUsK0JBQStCO0lBQzVDLFVBQVUsRUFBRSwwQ0FBMEM7SUFDdEQsU0FBUyxFQUFFLG9DQUFvQztJQUMvQyxXQUFXLEVBQUUsQ0FBQyxJQUE2QixFQUFFLEVBQUUsQ0FBQyxvQ0FBb0IsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDO0NBQzVGLENBQUMsQ0FBQztBQUVIOztHQUVHO0FBQ1UsUUFBQSxnQkFBZ0IsR0FBRyxJQUFJLCtCQUF1QixDQUEyQjtJQUNsRixXQUFXLEVBQUUsaUNBQWlDO0lBQzlDLFVBQVUsRUFBRSxRQUFRO0lBQ3BCLFNBQVMsRUFBRSxLQUFLO0lBQ2hCLFdBQVcsRUFBRSxDQUFDLElBQThCLEVBQUUsRUFBRSxDQUFDLElBQUEsa0JBQU8sRUFBQyxJQUFJLENBQUMsV0FBVyxFQUE4QixDQUFDO0NBQzNHLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEgRXJpayBGb3J0dW5lXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICogY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gKiBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBFeHRlbnNpb25SZWdpc3RyeSBmcm9tICcuLi8uLi9pYW5hL2xhbmd1YWdlLXRhZy1leHRlbnNpb25zJztcbmltcG9ydCAqIGFzIFN1YnRhZ3MgZnJvbSAnLi9tb2RlbCc7XG5cbmltcG9ydCB7IFJlZ0V4cFZhbGlkYXRpb25IZWxwZXJzIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgVGFnVmFsaWRhdGlvbkhlbHBlcnMgfSBmcm9tICcuLi8uLi9pYW5hL2phci9sYW5ndWFnZS1zdWJ0YWdzL3RhZ3MvdGFnVmFsaWRhdGlvbic7XG5cbmltcG9ydCB7IHN1Y2NlZWQgfSBmcm9tICdAZmd2L3RzLXV0aWxzJztcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBleHRlbnNpb25TaW5nbGV0b24gPSBFeHRlbnNpb25SZWdpc3RyeS5WYWxpZGF0ZS5leHRlbnNpb25TaW5nbGV0b247XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgZXh0ZW5zaW9uU3VidGFnID0gbmV3IFJlZ0V4cFZhbGlkYXRpb25IZWxwZXJzPFN1YnRhZ3MuRXh0ZW5zaW9uU3VidGFnPih7XG4gICAgZGVzY3JpcHRpb246ICdsYW5ndWFnZSB0YWcgZXh0ZW5zaW9uIHN1YnRhZycsXG4gICAgd2VsbEZvcm1lZDogL14oW2EtekEtWjAtOV17Miw4fSkoLVthLXpBLVowLTldezIsOH0pKiQvLFxuICAgIGNhbm9uaWNhbDogL14oW2EtejAtOV17Miw4fSkoLVthLXowLTldezIsOH0pKiQvLFxuICAgIHRvQ2Fub25pY2FsOiAoZnJvbTogU3VidGFncy5FeHRlbnNpb25TdWJ0YWcpID0+IFRhZ1ZhbGlkYXRpb25IZWxwZXJzLnRvQ2Fub25pY2FsVGFnKGZyb20pLFxufSk7XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcHJpdmF0ZVVzZVByZWZpeCA9IG5ldyBSZWdFeHBWYWxpZGF0aW9uSGVscGVyczxTdWJ0YWdzLlByaXZhdGVVc2VQcmVmaXg+KHtcbiAgICBkZXNjcmlwdGlvbjogJ2xhbmd1YWdlIHRhZyBwcml2YXRlLXVzZSBwcmVmaXgnLFxuICAgIHdlbGxGb3JtZWQ6IC9eW3hYXSQvLFxuICAgIGNhbm9uaWNhbDogL154JC8sXG4gICAgdG9DYW5vbmljYWw6IChmcm9tOiBTdWJ0YWdzLlByaXZhdGVVc2VQcmVmaXgpID0+IHN1Y2NlZWQoZnJvbS50b0xvd2VyQ2FzZSgpIGFzIFN1YnRhZ3MuUHJpdmF0ZVVzZVByZWZpeCksXG59KTtcbiJdfQ==
@@ -0,0 +1,38 @@
1
+ import * as Iana from '../iana';
2
+ import { Model } from './bcp47Subtags';
3
+ /**
4
+ * @public
5
+ */
6
+ export interface ExtensionSubtagValue {
7
+ readonly singleton: Model.ExtensionSingleton;
8
+ readonly value: Model.ExtensionSubtag;
9
+ }
10
+ /**
11
+ * @public
12
+ */
13
+ export interface Subtags {
14
+ primaryLanguage?: Iana.LanguageSubtags.LanguageSubtag;
15
+ extlangs?: Iana.LanguageSubtags.ExtLangSubtag[];
16
+ script?: Iana.LanguageSubtags.ScriptSubtag;
17
+ region?: Iana.LanguageSubtags.RegionSubtag;
18
+ variants?: Iana.LanguageSubtags.VariantSubtag[];
19
+ extensions?: ExtensionSubtagValue[];
20
+ privateUse?: Iana.LanguageSubtags.ExtendedLanguageRange[];
21
+ grandfathered?: Iana.LanguageSubtags.GrandfatheredTag;
22
+ }
23
+ /**
24
+ * Converts {@link Bcp47.Subtags | subtags} to a string.
25
+ * @param subtags - The {@link Bcp47.Subtags | subtags} to be converted.
26
+ * @returns A string representing the supplied {@link Bcp47.Subtags | subtags}.
27
+ * @public
28
+ */
29
+ export declare function subtagsToString(subtags: Subtags): string;
30
+ /**
31
+ * @public
32
+ */
33
+ export declare const UndeterminedLanguage: Iana.LanguageSubtags.LanguageSubtag;
34
+ /**
35
+ * @public
36
+ */
37
+ export declare const GlobalRegion: Iana.LanguageSubtags.RegionSubtag;
38
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/bcp47/common.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,kBAAkB,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,eAAe,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC;IACtD,QAAQ,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;IAChD,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC;IAC3C,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC;IAC3C,QAAQ,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;IAChD,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,CAAC;IAE1D,aAAa,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAexD;AAED;;GAEG;AAEH,eAAO,MAAM,oBAAoB,qCAA+C,CAAC;AAEjF;;GAEG;AAEH,eAAO,MAAM,YAAY,mCAA6C,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2022 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.GlobalRegion = exports.UndeterminedLanguage = exports.subtagsToString = void 0;
25
+ /**
26
+ * Converts {@link Bcp47.Subtags | subtags} to a string.
27
+ * @param subtags - The {@link Bcp47.Subtags | subtags} to be converted.
28
+ * @returns A string representing the supplied {@link Bcp47.Subtags | subtags}.
29
+ * @public
30
+ */
31
+ function subtagsToString(subtags) {
32
+ var _a, _b, _c, _d;
33
+ if (subtags.grandfathered) {
34
+ return subtags.grandfathered;
35
+ }
36
+ return [
37
+ subtags.primaryLanguage,
38
+ ...((_a = subtags.extlangs) !== null && _a !== void 0 ? _a : []),
39
+ subtags.script,
40
+ subtags.region,
41
+ ...((_b = subtags.variants) !== null && _b !== void 0 ? _b : []),
42
+ ...((_c = subtags.extensions) !== null && _c !== void 0 ? _c : []).map((e) => `${e.singleton}-${e.value}`),
43
+ ...((_d = subtags.privateUse) !== null && _d !== void 0 ? _d : []).map((p) => `x-${p}`),
44
+ ]
45
+ .filter((s) => s !== undefined)
46
+ .join('-');
47
+ }
48
+ exports.subtagsToString = subtagsToString;
49
+ /**
50
+ * @public
51
+ */
52
+ // eslint-disable-next-line @typescript-eslint/naming-convention
53
+ exports.UndeterminedLanguage = 'und';
54
+ /**
55
+ * @public
56
+ */
57
+ // eslint-disable-next-line @typescript-eslint/naming-convention
58
+ exports.GlobalRegion = '001';
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2JjcDQ3L2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7QUE2Qkg7Ozs7O0dBS0c7QUFDSCxTQUFnQixlQUFlLENBQUMsT0FBZ0I7O0lBQzVDLElBQUksT0FBTyxDQUFDLGFBQWEsRUFBRTtRQUN2QixPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUM7S0FDaEM7SUFDRCxPQUFPO1FBQ0gsT0FBTyxDQUFDLGVBQWU7UUFDdkIsR0FBRyxDQUFDLE1BQUEsT0FBTyxDQUFDLFFBQVEsbUNBQUksRUFBRSxDQUFDO1FBQzNCLE9BQU8sQ0FBQyxNQUFNO1FBQ2QsT0FBTyxDQUFDLE1BQU07UUFDZCxHQUFHLENBQUMsTUFBQSxPQUFPLENBQUMsUUFBUSxtQ0FBSSxFQUFFLENBQUM7UUFDM0IsR0FBRyxDQUFDLE1BQUEsT0FBTyxDQUFDLFVBQVUsbUNBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JFLEdBQUcsQ0FBQyxNQUFBLE9BQU8sQ0FBQyxVQUFVLG1DQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztLQUNyRDtTQUNJLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQztTQUMzQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQWZELDBDQWVDO0FBRUQ7O0dBRUc7QUFDSCxnRUFBZ0U7QUFDbkQsUUFBQSxvQkFBb0IsR0FBRyxLQUE0QyxDQUFDO0FBRWpGOztHQUVHO0FBQ0gsZ0VBQWdFO0FBQ25ELFFBQUEsWUFBWSxHQUFHLEtBQTBDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDIyIEVyaWsgRm9ydHVuZVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0ICogYXMgSWFuYSBmcm9tICcuLi9pYW5hJztcblxuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICcuL2JjcDQ3U3VidGFncyc7XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuc2lvblN1YnRhZ1ZhbHVlIHtcbiAgICByZWFkb25seSBzaW5nbGV0b246IE1vZGVsLkV4dGVuc2lvblNpbmdsZXRvbjtcbiAgICByZWFkb25seSB2YWx1ZTogTW9kZWwuRXh0ZW5zaW9uU3VidGFnO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdWJ0YWdzIHtcbiAgICBwcmltYXJ5TGFuZ3VhZ2U/OiBJYW5hLkxhbmd1YWdlU3VidGFncy5MYW5ndWFnZVN1YnRhZztcbiAgICBleHRsYW5ncz86IElhbmEuTGFuZ3VhZ2VTdWJ0YWdzLkV4dExhbmdTdWJ0YWdbXTtcbiAgICBzY3JpcHQ/OiBJYW5hLkxhbmd1YWdlU3VidGFncy5TY3JpcHRTdWJ0YWc7XG4gICAgcmVnaW9uPzogSWFuYS5MYW5ndWFnZVN1YnRhZ3MuUmVnaW9uU3VidGFnO1xuICAgIHZhcmlhbnRzPzogSWFuYS5MYW5ndWFnZVN1YnRhZ3MuVmFyaWFudFN1YnRhZ1tdO1xuICAgIGV4dGVuc2lvbnM/OiBFeHRlbnNpb25TdWJ0YWdWYWx1ZVtdO1xuICAgIHByaXZhdGVVc2U/OiBJYW5hLkxhbmd1YWdlU3VidGFncy5FeHRlbmRlZExhbmd1YWdlUmFuZ2VbXTtcblxuICAgIGdyYW5kZmF0aGVyZWQ/OiBJYW5hLkxhbmd1YWdlU3VidGFncy5HcmFuZGZhdGhlcmVkVGFnO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHtAbGluayBCY3A0Ny5TdWJ0YWdzIHwgc3VidGFnc30gdG8gYSBzdHJpbmcuXG4gKiBAcGFyYW0gc3VidGFncyAtIFRoZSB7QGxpbmsgQmNwNDcuU3VidGFncyB8IHN1YnRhZ3N9IHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm5zIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgc3VwcGxpZWQge0BsaW5rIEJjcDQ3LlN1YnRhZ3MgfCBzdWJ0YWdzfS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnRhZ3NUb1N0cmluZyhzdWJ0YWdzOiBTdWJ0YWdzKTogc3RyaW5nIHtcbiAgICBpZiAoc3VidGFncy5ncmFuZGZhdGhlcmVkKSB7XG4gICAgICAgIHJldHVybiBzdWJ0YWdzLmdyYW5kZmF0aGVyZWQ7XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICAgIHN1YnRhZ3MucHJpbWFyeUxhbmd1YWdlLFxuICAgICAgICAuLi4oc3VidGFncy5leHRsYW5ncyA/PyBbXSksXG4gICAgICAgIHN1YnRhZ3Muc2NyaXB0LFxuICAgICAgICBzdWJ0YWdzLnJlZ2lvbixcbiAgICAgICAgLi4uKHN1YnRhZ3MudmFyaWFudHMgPz8gW10pLFxuICAgICAgICAuLi4oc3VidGFncy5leHRlbnNpb25zID8/IFtdKS5tYXAoKGUpID0+IGAke2Uuc2luZ2xldG9ufS0ke2UudmFsdWV9YCksXG4gICAgICAgIC4uLihzdWJ0YWdzLnByaXZhdGVVc2UgPz8gW10pLm1hcCgocCkgPT4gYHgtJHtwfWApLFxuICAgIF1cbiAgICAgICAgLmZpbHRlcigocyk6IHMgaXMgc3RyaW5nID0+IHMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgLmpvaW4oJy0nKTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBVbmRldGVybWluZWRMYW5ndWFnZSA9ICd1bmQnIGFzIElhbmEuTGFuZ3VhZ2VTdWJ0YWdzLkxhbmd1YWdlU3VidGFnO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IEdsb2JhbFJlZ2lvbiA9ICcwMDEnIGFzIElhbmEuTGFuZ3VhZ2VTdWJ0YWdzLlJlZ2lvblN1YnRhZztcbiJdfQ==
@@ -0,0 +1,66 @@
1
+ import { LanguageChooserOptions } from './match/chooser';
2
+ import { LanguageTag, LanguageTagInitOptions } from './languageTag';
3
+ import { Result } from '@fgv/ts-utils';
4
+ import { Subtags } from './common';
5
+ /**
6
+ * Any of the possible ways to represent a language - as a `string`,
7
+ * parsed {@link Bcp47.Subtags | subtags} or an instantiated
8
+ * {@link Bcp47.LanguageTag | language tag}.
9
+ * @public
10
+ */
11
+ export type LanguageSpec = string | Subtags | LanguageTag;
12
+ /**
13
+ * Creates a new {@link Bcp47.LanguageTag | language tag} from a {@link Bcp47.LanguageSpec | language specifier}
14
+ *
15
+ * The supplied initializer must be at least
16
+ * {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.9 | well-formed according to RFC 5646}.
17
+ * Higher degrees of validation along with any normalizations may be optionally specified.
18
+ *
19
+ * @param from - The {@link Bcp47.LanguageSpec | language specifier} from which the tag is to
20
+ * be created.
21
+ * @param options - (optional) The {@link Bcp47.LanguageTagInitOptions | options} used to construct
22
+ * and validate the tag.
23
+ * @returns `Success` with a valid {@link Bcp47.LanguageTag | language tag} or `Failure` with details
24
+ * if an error occurs.
25
+ * @public
26
+ */
27
+ export declare function tag(from: LanguageSpec, options?: LanguageTagInitOptions): Result<LanguageTag>;
28
+ /**
29
+ * Creates an array of {@link Bcp47.LanguageTag | language tags} from an incoming array of
30
+ * {@link Bcp47.LanguageSpec | language specifiers}.
31
+ * @param from - The array of {@link Bcp47.LanguageSpec} to be converted.
32
+ * @param options - (optional) The {@link Bcp47.LanguageTagInitOptions | options} used to construct
33
+ * and validate any created tags.
34
+ * @returns `Success` with an array of {@link Bcp47.LanguageTag | language tags}, or `Failure`
35
+ * with details if an error occurs.
36
+ * @public
37
+ */
38
+ export declare function tags(from: LanguageSpec[], options?: LanguageTagInitOptions): Result<LanguageTag[]>;
39
+ /**
40
+ * Determine how similar two language tags are to each other.
41
+ *
42
+ * @param t1 - First tag to match, supplied as one of `string`, individual
43
+ * {@link Bcp47.Subtags | subtags}, or constructed
44
+ * {@link Bcp47.LanguageTag | language tag}.
45
+ * @param t2 - Second tag to match, supplied as one of `string`, individual
46
+ * {@link Bcp47.Subtags | subtags}, or constructed
47
+ * {@link Bcp47.LanguageTag | language tag}.
48
+ * @param options - (optional) A set of {@link Bcp47.LanguageTagInitOptions | language tag options}
49
+ * which control any necessary conversion or parsing.
50
+ * @returns A numeric value in the range 1.0 (exact match) to 0.0 (no match).
51
+ * @see For a set of common levels of similarity, see {@link Bcp47.tagSimilarity | similarity}.
52
+ * @public
53
+ */
54
+ export declare function similarity(t1: LanguageSpec, t2: LanguageSpec, options?: LanguageTagInitOptions): Result<number>;
55
+ /**
56
+ * Matches a list of desired {@link Bcp47.LanguageSpec | languages} to a list of available {@link Bcp47.LanguageSpec | languages},
57
+ * return a list of matching languages ordered from best to worst.
58
+ * @param desired - An array of {@link Bcp47.LanguageSpec | language specifications} containing an ordered list of preferred languages.
59
+ * @param available - An array of {@link Bcp47.LanguageSpec | language specifications} containing an unordered list of available languages.
60
+ * @param options - (optional) Parameters to control language tag conversion or comparison
61
+ * @returns `Success` with an ordered list of matching {@link Bcp47.LanguageTag | languages}, or `Failure` with details if
62
+ * an error occurs.
63
+ * @public
64
+ */
65
+ export declare function choose(desired: LanguageSpec[], available: LanguageSpec[], options?: LanguageTagInitOptions & LanguageChooserOptions): Result<LanguageTag[]>;
66
+ //# sourceMappingURL=helpers.d.ts.map