n2words 1.24.0 → 3.0.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 (280) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +183 -156
  3. package/dist/languages/am-Latn.js +3 -0
  4. package/dist/languages/am-Latn.js.map +1 -0
  5. package/dist/languages/am.js +3 -0
  6. package/dist/languages/am.js.map +1 -0
  7. package/dist/languages/ar.js +3 -2
  8. package/dist/languages/ar.js.map +1 -1
  9. package/dist/languages/az.js +3 -2
  10. package/dist/languages/az.js.map +1 -1
  11. package/dist/languages/bn.js +3 -2
  12. package/dist/languages/bn.js.map +1 -1
  13. package/dist/languages/cs.js +3 -2
  14. package/dist/languages/cs.js.map +1 -1
  15. package/dist/languages/da.js +3 -2
  16. package/dist/languages/da.js.map +1 -1
  17. package/dist/languages/de.js +3 -2
  18. package/dist/languages/de.js.map +1 -1
  19. package/dist/languages/el.js +3 -2
  20. package/dist/languages/el.js.map +1 -1
  21. package/dist/languages/en.js +3 -2
  22. package/dist/languages/en.js.map +1 -1
  23. package/dist/languages/es.js +3 -2
  24. package/dist/languages/es.js.map +1 -1
  25. package/dist/languages/fa.js +3 -2
  26. package/dist/languages/fa.js.map +1 -1
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -2
  30. package/dist/languages/fil.js.map +1 -1
  31. package/dist/languages/fr-BE.js +3 -2
  32. package/dist/languages/fr-BE.js.map +1 -1
  33. package/dist/languages/fr.js +3 -2
  34. package/dist/languages/fr.js.map +1 -1
  35. package/dist/languages/gu.js +3 -2
  36. package/dist/languages/gu.js.map +1 -1
  37. package/dist/languages/ha.js +3 -0
  38. package/dist/languages/ha.js.map +1 -0
  39. package/dist/languages/hbo.js +3 -0
  40. package/dist/languages/hbo.js.map +1 -0
  41. package/dist/languages/he.js +3 -2
  42. package/dist/languages/he.js.map +1 -1
  43. package/dist/languages/hi.js +3 -2
  44. package/dist/languages/hi.js.map +1 -1
  45. package/dist/languages/hr.js +3 -2
  46. package/dist/languages/hr.js.map +1 -1
  47. package/dist/languages/hu.js +3 -2
  48. package/dist/languages/hu.js.map +1 -1
  49. package/dist/languages/id.js +3 -2
  50. package/dist/languages/id.js.map +1 -1
  51. package/dist/languages/it.js +3 -2
  52. package/dist/languages/it.js.map +1 -1
  53. package/dist/languages/ja.js +3 -2
  54. package/dist/languages/ja.js.map +1 -1
  55. package/dist/languages/kn.js +3 -2
  56. package/dist/languages/kn.js.map +1 -1
  57. package/dist/languages/ko.js +3 -2
  58. package/dist/languages/ko.js.map +1 -1
  59. package/dist/languages/lt.js +3 -2
  60. package/dist/languages/lt.js.map +1 -1
  61. package/dist/languages/lv.js +3 -2
  62. package/dist/languages/lv.js.map +1 -1
  63. package/dist/languages/mr.js +3 -2
  64. package/dist/languages/mr.js.map +1 -1
  65. package/dist/languages/ms.js +3 -2
  66. package/dist/languages/ms.js.map +1 -1
  67. package/dist/languages/nb.js +3 -2
  68. package/dist/languages/nb.js.map +1 -1
  69. package/dist/languages/nl.js +3 -2
  70. package/dist/languages/nl.js.map +1 -1
  71. package/dist/languages/pa.js +3 -0
  72. package/dist/languages/pa.js.map +1 -0
  73. package/dist/languages/pl.js +3 -2
  74. package/dist/languages/pl.js.map +1 -1
  75. package/dist/languages/pt.js +3 -2
  76. package/dist/languages/pt.js.map +1 -1
  77. package/dist/languages/ro.js +3 -2
  78. package/dist/languages/ro.js.map +1 -1
  79. package/dist/languages/ru.js +3 -2
  80. package/dist/languages/ru.js.map +1 -1
  81. package/dist/languages/sr-Cyrl.js +3 -0
  82. package/dist/languages/sr-Cyrl.js.map +1 -0
  83. package/dist/languages/sr-Latn.js +3 -2
  84. package/dist/languages/sr-Latn.js.map +1 -1
  85. package/dist/languages/sv.js +3 -2
  86. package/dist/languages/sv.js.map +1 -1
  87. package/dist/languages/sw.js +3 -2
  88. package/dist/languages/sw.js.map +1 -1
  89. package/dist/languages/ta.js +3 -2
  90. package/dist/languages/ta.js.map +1 -1
  91. package/dist/languages/te.js +3 -2
  92. package/dist/languages/te.js.map +1 -1
  93. package/dist/languages/th.js +3 -2
  94. package/dist/languages/th.js.map +1 -1
  95. package/dist/languages/tr.js +3 -2
  96. package/dist/languages/tr.js.map +1 -1
  97. package/dist/languages/uk.js +3 -2
  98. package/dist/languages/uk.js.map +1 -1
  99. package/dist/languages/ur.js +3 -2
  100. package/dist/languages/ur.js.map +1 -1
  101. package/dist/languages/vi.js +3 -2
  102. package/dist/languages/vi.js.map +1 -1
  103. package/dist/languages/zh-Hans.js +3 -2
  104. package/dist/languages/zh-Hans.js.map +1 -1
  105. package/dist/languages/zh-Hant.js +3 -0
  106. package/dist/languages/zh-Hant.js.map +1 -0
  107. package/dist/n2words.js +3 -2
  108. package/dist/n2words.js.map +1 -1
  109. package/lib/languages/am-Latn.d.ts +7 -0
  110. package/lib/languages/am-Latn.js +164 -0
  111. package/lib/languages/am.d.ts +7 -0
  112. package/lib/languages/am.js +164 -0
  113. package/lib/languages/ar.d.ts +17 -0
  114. package/lib/languages/ar.js +171 -209
  115. package/lib/languages/az.d.ts +7 -0
  116. package/lib/languages/az.js +167 -49
  117. package/lib/languages/bn.d.ts +7 -0
  118. package/lib/languages/bn.js +142 -123
  119. package/lib/languages/cs.d.ts +18 -0
  120. package/lib/languages/cs.js +303 -176
  121. package/lib/languages/da.d.ts +14 -0
  122. package/lib/languages/da.js +267 -139
  123. package/lib/languages/de.d.ts +17 -0
  124. package/lib/languages/de.js +310 -113
  125. package/lib/languages/el.d.ts +14 -0
  126. package/lib/languages/el.js +225 -98
  127. package/lib/languages/en.d.ts +17 -0
  128. package/lib/languages/en.js +235 -102
  129. package/lib/languages/es.d.ts +21 -0
  130. package/lib/languages/es.js +307 -125
  131. package/lib/languages/fa.d.ts +7 -0
  132. package/lib/languages/fa.js +115 -108
  133. package/lib/languages/fi.d.ts +14 -0
  134. package/lib/languages/fi.js +245 -0
  135. package/lib/languages/fil.d.ts +7 -0
  136. package/lib/languages/fil.js +199 -139
  137. package/lib/languages/fr-BE.d.ts +11 -0
  138. package/lib/languages/fr-BE.js +287 -48
  139. package/lib/languages/fr.d.ts +21 -0
  140. package/lib/languages/fr.js +343 -119
  141. package/lib/languages/gu.d.ts +7 -0
  142. package/lib/languages/gu.js +125 -144
  143. package/lib/languages/ha.d.ts +7 -0
  144. package/lib/languages/ha.js +230 -0
  145. package/lib/languages/hbo.d.ts +13 -0
  146. package/lib/languages/hbo.js +300 -0
  147. package/lib/languages/he.d.ts +13 -0
  148. package/lib/languages/he.js +230 -283
  149. package/lib/languages/hi.d.ts +7 -0
  150. package/lib/languages/hi.js +142 -123
  151. package/lib/languages/hr.d.ts +11 -0
  152. package/lib/languages/hr.js +190 -129
  153. package/lib/languages/hu.d.ts +7 -0
  154. package/lib/languages/hu.js +194 -133
  155. package/lib/languages/id.d.ts +7 -0
  156. package/lib/languages/id.js +167 -140
  157. package/lib/languages/it.d.ts +19 -0
  158. package/lib/languages/it.js +337 -108
  159. package/lib/languages/ja.d.ts +17 -0
  160. package/lib/languages/ja.js +224 -155
  161. package/lib/languages/kn.d.ts +7 -0
  162. package/lib/languages/kn.js +128 -62
  163. package/lib/languages/ko.d.ts +14 -0
  164. package/lib/languages/ko.js +250 -70
  165. package/lib/languages/lt.d.ts +18 -0
  166. package/lib/languages/lt.js +287 -148
  167. package/lib/languages/lv.d.ts +18 -0
  168. package/lib/languages/lv.js +291 -123
  169. package/lib/languages/mr.d.ts +7 -0
  170. package/lib/languages/mr.js +125 -144
  171. package/lib/languages/ms.d.ts +7 -0
  172. package/lib/languages/ms.js +171 -112
  173. package/lib/languages/nb.d.ts +14 -0
  174. package/lib/languages/nb.js +275 -100
  175. package/lib/languages/nl.d.ts +26 -0
  176. package/lib/languages/nl.js +307 -174
  177. package/lib/languages/pa.d.ts +7 -0
  178. package/lib/languages/pa.js +163 -0
  179. package/lib/languages/pl.d.ts +22 -0
  180. package/lib/languages/pl.js +299 -158
  181. package/lib/languages/pt.d.ts +17 -0
  182. package/lib/languages/pt.js +279 -120
  183. package/lib/languages/ro.d.ts +18 -0
  184. package/lib/languages/ro.js +214 -337
  185. package/lib/languages/ru.d.ts +11 -0
  186. package/lib/languages/ru.js +219 -95
  187. package/lib/languages/sr-Cyrl.d.ts +11 -0
  188. package/lib/languages/sr-Cyrl.js +215 -0
  189. package/lib/languages/sr-Latn.d.ts +11 -0
  190. package/lib/languages/sr-Latn.js +190 -132
  191. package/lib/languages/sv.d.ts +14 -0
  192. package/lib/languages/sv.js +280 -103
  193. package/lib/languages/sw.d.ts +7 -0
  194. package/lib/languages/sw.js +135 -103
  195. package/lib/languages/ta.d.ts +7 -0
  196. package/lib/languages/ta.js +133 -205
  197. package/lib/languages/te.d.ts +7 -0
  198. package/lib/languages/te.js +148 -213
  199. package/lib/languages/th.d.ts +7 -0
  200. package/lib/languages/th.js +139 -101
  201. package/lib/languages/tr.d.ts +18 -0
  202. package/lib/languages/tr.js +246 -66
  203. package/lib/languages/uk.d.ts +11 -0
  204. package/lib/languages/uk.js +197 -101
  205. package/lib/languages/ur.d.ts +7 -0
  206. package/lib/languages/ur.js +160 -123
  207. package/lib/languages/vi.d.ts +17 -0
  208. package/lib/languages/vi.js +287 -164
  209. package/lib/languages/zh-Hans.d.ts +11 -0
  210. package/lib/languages/zh-Hans.js +159 -142
  211. package/lib/languages/zh-Hant.d.ts +11 -0
  212. package/lib/languages/zh-Hant.js +202 -0
  213. package/lib/n2words.d.ts +53 -0
  214. package/lib/n2words.js +91 -227
  215. package/lib/utils/is-plain-object.d.ts +13 -0
  216. package/lib/utils/is-plain-object.js +17 -0
  217. package/lib/utils/parse-numeric.d.ts +17 -0
  218. package/lib/utils/parse-numeric.js +108 -0
  219. package/lib/utils/validate-options.d.ts +8 -0
  220. package/lib/utils/validate-options.js +16 -0
  221. package/package.json +118 -67
  222. package/dist/languages/pa-Guru.js +0 -2
  223. package/dist/languages/pa-Guru.js.map +0 -1
  224. package/lib/classes/abstract-language.js +0 -261
  225. package/lib/classes/greedy-scale-language.js +0 -195
  226. package/lib/classes/slavic-language.js +0 -251
  227. package/lib/classes/south-asian-language.js +0 -161
  228. package/lib/classes/turkic-language.js +0 -63
  229. package/lib/languages/pa-Guru.js +0 -126
  230. package/typings/classes/abstract-language.d.ts +0 -144
  231. package/typings/classes/greedy-scale-language.d.ts +0 -148
  232. package/typings/classes/slavic-language.d.ts +0 -145
  233. package/typings/classes/south-asian-language.d.ts +0 -101
  234. package/typings/classes/turkic-language.d.ts +0 -42
  235. package/typings/languages/ar.d.ts +0 -93
  236. package/typings/languages/az.d.ts +0 -25
  237. package/typings/languages/bn.d.ts +0 -1
  238. package/typings/languages/cs.d.ts +0 -120
  239. package/typings/languages/da.d.ts +0 -53
  240. package/typings/languages/de.d.ts +0 -26
  241. package/typings/languages/el.d.ts +0 -11
  242. package/typings/languages/en.d.ts +0 -30
  243. package/typings/languages/es.d.ts +0 -43
  244. package/typings/languages/fa.d.ts +0 -81
  245. package/typings/languages/fil.d.ts +0 -12
  246. package/typings/languages/fr-BE.d.ts +0 -41
  247. package/typings/languages/fr.d.ts +0 -43
  248. package/typings/languages/gu.d.ts +0 -12
  249. package/typings/languages/he.d.ts +0 -197
  250. package/typings/languages/hi.d.ts +0 -1
  251. package/typings/languages/hr.d.ts +0 -110
  252. package/typings/languages/hu.d.ts +0 -37
  253. package/typings/languages/id.d.ts +0 -69
  254. package/typings/languages/it.d.ts +0 -51
  255. package/typings/languages/ja.d.ts +0 -58
  256. package/typings/languages/kn.d.ts +0 -11
  257. package/typings/languages/ko.d.ts +0 -25
  258. package/typings/languages/lt.d.ts +0 -110
  259. package/typings/languages/lv.d.ts +0 -99
  260. package/typings/languages/mr.d.ts +0 -12
  261. package/typings/languages/ms.d.ts +0 -37
  262. package/typings/languages/nb.d.ts +0 -27
  263. package/typings/languages/nl.d.ts +0 -65
  264. package/typings/languages/pa-Guru.d.ts +0 -1
  265. package/typings/languages/pl.d.ts +0 -116
  266. package/typings/languages/pt.d.ts +0 -39
  267. package/typings/languages/ro.d.ts +0 -229
  268. package/typings/languages/ru.d.ts +0 -108
  269. package/typings/languages/sr-Latn.d.ts +0 -98
  270. package/typings/languages/sv.d.ts +0 -30
  271. package/typings/languages/sw.d.ts +0 -1
  272. package/typings/languages/ta.d.ts +0 -1
  273. package/typings/languages/te.d.ts +0 -1
  274. package/typings/languages/th.d.ts +0 -1
  275. package/typings/languages/tr.d.ts +0 -46
  276. package/typings/languages/uk.d.ts +0 -117
  277. package/typings/languages/ur.d.ts +0 -1
  278. package/typings/languages/vi.d.ts +0 -116
  279. package/typings/languages/zh-Hans.d.ts +0 -57
  280. package/typings/n2words.d.ts +0 -177
@@ -1,161 +0,0 @@
1
- import AbstractLanguage from './abstract-language.js'
2
-
3
- /**
4
- * @typedef {Array<string>} SouthAsianScaleWords
5
- * Array of scale words for the Indian numbering system, in ascending order.
6
- * - Index 0: Usually empty/unused (ones place)
7
- * - Index 1: Thousands (hazaar/হাজার/हजार)
8
- * - Index 2: Lakhs (lakh/লাখ/लाख)
9
- * - Index 3: Crores (crore/কোটি/करोड़)
10
- * - Index 4: Arabs (arab/আরব/अरब)
11
- * Each index i represents the scale word for groups at position i in the Indian system.
12
- */
13
-
14
- /**
15
- * @typedef {Array<string>} SouthAsianBelowHundred
16
- * Array of words for numbers 0-99, indexed directly.
17
- * belowHundred[0] = word for 0, belowHundred[42] = word for 42, etc.
18
- */
19
-
20
- /**
21
- * Base class for South Asian languages with shared grouping patterns.
22
- *
23
- * This class provides a reusable implementation for South Asian languages that share:
24
- * - Indian-style number grouping: last 3 digits, then 2-2 (1,23,45,67,89)
25
- * - Lakh (100,000), Crore (10,000,000), Arab (1,000,000,000) scale words
26
- * - Standard negative and decimal handling (inherits AbstractLanguage decimal logic,
27
- * including `convertDecimalsPerDigit` support when set by subclasses)
28
- *
29
- * Used by: Hindi (hi), Bengali (bn), Urdu (ur), Punjabi (pa), Marathi (mr), Gujarati (gu), Kannada (kn)
30
- *
31
- * Subclasses MUST define language-specific vocabulary via class properties:
32
- * - `belowHundred` array with digit and teen words (0-99)
33
- * - `hundredWord` string used inside `convertBelowThousand`
34
- * - `scaleWords` array with grouping words (hazaar, lakh, crore, etc.) indexed by grouping level
35
- * - `negativeWord`, `decimalSeparatorWord`, `zeroWord`, `wordSeparator`
36
- *
37
- * @abstract
38
- * @extends AbstractLanguage
39
- */
40
- class SouthAsianLanguage extends AbstractLanguage {
41
- /**
42
- * Array of words for numbers 0-99 (digits and teens).
43
- * Index directly: belowHundred[0] through belowHundred[99].
44
- * @type {Array<string>}
45
- */
46
- belowHundred
47
-
48
- /**
49
- * Word for "hundred" in the language (e.g., 'सौ' in Hindi, 'শত' in Bengali).
50
- * Used to construct hundreds (e.g., "1 hundred", "2 hundred").
51
- * @type {string}
52
- */
53
- hundredWord
54
-
55
- /**
56
- * Array of scale words for Indian-style grouping (hazaar, lakh, crore, arab, etc.).
57
- * Index 0 is typically unused (ones place, no scale word).
58
- * Index 1 is for thousands, Index 2 for lakhs, Index 3 for crores, etc.
59
- * @type {Array<string>}
60
- */
61
- scaleWords
62
-
63
- /**
64
- * Split a number into Indian numbering system groups.
65
- *
66
- * The Indian system groups differently than Western (3-3-3) systems:
67
- * - First group (rightmost): Up to 3 digits (ones, tens, hundreds)
68
- * - Subsequent groups: Exactly 2 digits each (thousands, lakhs, crores, etc.)
69
- *
70
- * This creates the familiar Indian comma pattern: 1,23,45,67,890
71
- *
72
- * @protected
73
- * @param {bigint} number The number to split into groups
74
- * @returns {Array<number>} Array of groups from most significant to least significant
75
- *
76
- * @example
77
- * // splitToGroups(1234567n) → [12, 34, 567]
78
- * // Reads as: 12 lakhs, 34 thousands, 567 units
79
- * // splitToGroups(98765432n) → [9, 87, 65, 432]
80
- * // Reads as: 9 crores, 87 lakhs, 65 thousands, 432 units
81
- */
82
- splitToGroups (number) {
83
- const numStr = number.toString()
84
-
85
- if (numStr.length <= 3) {
86
- return [Number(numStr)]
87
- }
88
-
89
- const groups = []
90
- const last3 = numStr.slice(-3)
91
- groups.unshift(Number(last3))
92
-
93
- let remaining = numStr.slice(0, -3)
94
- while (remaining.length > 0) {
95
- const group = remaining.slice(-2)
96
- groups.unshift(Number(group))
97
- remaining = remaining.slice(0, -2)
98
- }
99
-
100
- return groups
101
- }
102
-
103
- /**
104
- * Convert a number below 1000 to words (0-999).
105
- *
106
- * @protected
107
- * @param {number} number Value between 0 and 999
108
- * @returns {string} Language-specific word representation
109
- */
110
- convertBelowThousand (number) {
111
- if (number === 0) return ''
112
- if (number < 100) return this.belowHundred[number]
113
-
114
- const hundreds = Math.trunc(number / 100)
115
- const remainder = number % 100
116
- const parts = []
117
-
118
- if (hundreds === 1) {
119
- parts.push(this.belowHundred[1] + ' ' + this.hundredWord)
120
- } else {
121
- parts.push(this.belowHundred[hundreds] + ' ' + this.hundredWord)
122
- }
123
-
124
- if (remainder > 0) {
125
- parts.push(this.belowHundred[remainder])
126
- }
127
-
128
- return parts.join(' ')
129
- }
130
-
131
- /**
132
- * Convert whole number to cardinal words using South Asian grouping.
133
- *
134
- * @param {bigint} number Number to convert
135
- * @returns {string} Cardinal representation
136
- */
137
- convertWholePart (number) {
138
- if (number === 0n) {
139
- return this.zeroWord
140
- }
141
-
142
- const groups = this.splitToGroups(number)
143
- const groupCount = groups.length
144
- const words = []
145
-
146
- for (let i = 0; i < groupCount; i++) {
147
- const groupValue = groups[i]
148
- if (groupValue === 0) continue
149
-
150
- const scaleIndex = groupCount - i - 1
151
- words.push(this.convertBelowThousand(groupValue))
152
- if (scaleIndex > 0 && this.scaleWords[scaleIndex]) {
153
- words.push(this.scaleWords[scaleIndex])
154
- }
155
- }
156
-
157
- return words.join(' ').trim()
158
- }
159
- }
160
-
161
- export default SouthAsianLanguage
@@ -1,63 +0,0 @@
1
- import GreedyScaleLanguage from './greedy-scale-language.js'
2
-
3
- /**
4
- * @typedef {Object} TurkicWordPair
5
- * @property {string} word - The Turkic word or phrase
6
- * @property {bigint} value - The numeric value represented by the word
7
- */
8
-
9
- /**
10
- * Base class for Turkic languages with shared grammar patterns.
11
- *
12
- * This class provides a reusable implementation for Turkic languages that share:
13
- * - Space-separated number combinations
14
- * - Implicit 'bir' (one) before hundreds and thousands
15
- * - Simple multiplication/addition logic
16
- * - Consistent magnitude handling
17
- * - Inherits decimal handling from AbstractLanguage via GreedyScaleLanguage
18
- * (supports both grouped and per-digit modes via the `convertDecimalsPerDigit` class property).
19
- *
20
- * Used by: Turkish (TR), Azerbaijani (AZ)
21
- *
22
- * Subclasses MUST define (from GreedyScaleLanguage requirements):
23
- * - `scaleWordPairs` array of [value, word] pairs as a class property (ordered descending by value).
24
- * Optionally, language-specific class properties (e.g., `negativeWord`, `zeroWord`, `decimalSeparatorWord`, `wordSeparator`).
25
- *
26
- * TurkicLanguage provides a default `mergeScales()` implementation; subclasses may override
27
- * if specialized merge logic is needed (unlikely for Turkic languages).
28
- *
29
- * @abstract
30
- * @extends GreedyScaleLanguage
31
- */
32
- class TurkicLanguage extends GreedyScaleLanguage {
33
- /**
34
- * Merges two adjacent word-number pairs according to Turkic grammar rules.
35
- *
36
- * Shared Turkic patterns:
37
- * - Implicit 'bir' (one) before hundreds and thousands
38
- * - Space separator (wordSeparator property) for all combinations
39
- * - Multiplies when right > left (crossing magnitude boundary)
40
- * - Adds otherwise (combining same-magnitude components)
41
- *
42
- * @param {Object} leftPair The left operand as `{ word: bigint }`.
43
- * @param {Object} rightPair The right operand as `{ word: bigint }`.
44
- * @returns {Object} Merged pair with combined word and resulting number (bigint).
45
- */
46
- mergeScales (leftPair, rightPair) {
47
- const [[leftWord, leftNumber]] = Object.entries(leftPair)
48
- const [[rightWord, rightNumber]] = Object.entries(rightPair)
49
-
50
- // Implicit 'bir' (one) before certain magnitudes:
51
- // Omit '1' before hundreds (100n) and thousands (1000n) to form natural combinations
52
- if (leftNumber === 1n && (rightNumber <= 100n || rightNumber === 1000n)) {
53
- return rightPair // Return just the magnitude word (e.g., "yüz", not "bir yüz")
54
- }
55
-
56
- // Combine numbers with space separator (wordSeparator from GreedyScaleLanguage):
57
- // Multiply when crossing magnitude boundary, add otherwise
58
- const mergedNumber = rightNumber > leftNumber ? leftNumber * rightNumber : leftNumber + rightNumber
59
- return { [`${leftWord}${this.wordSeparator}${rightWord}`]: mergedNumber }
60
- }
61
- }
62
-
63
- export default TurkicLanguage
@@ -1,126 +0,0 @@
1
- import SouthAsianLanguage from '../classes/south-asian-language.js'
2
-
3
- class Punjabi extends SouthAsianLanguage {
4
- negativeWord = 'ਮਾਇਨਸ'
5
- decimalSeparatorWord = 'ਦਸ਼ਮਲਵ'
6
- zeroWord = 'ਸਿਫ਼ਰ'
7
- hundredWord = 'ਸੌ'
8
- belowHundred = [
9
- 'ਸਿਫ਼ਰ',
10
- 'ਇੱਕ',
11
- 'ਦੋ',
12
- 'ਤਿੰਨ',
13
- 'ਚਾਰ',
14
- 'ਪੰਜ',
15
- 'ਛੇ',
16
- 'ਸੱਤ',
17
- 'ਅੱਠ',
18
- 'ਨੌਂ',
19
- 'ਦੱਸ',
20
- 'ਗਿਆਰਾਂ',
21
- 'ਬਾਰਾਂ',
22
- 'ਤੇਰਾਂ',
23
- 'ਚੌਦਾਂ',
24
- 'ਪੰਦਰਾਂ',
25
- 'ਸੋਲਾਂ',
26
- 'ਸਤਾਰਾਂ',
27
- 'ਅਠਾਰਾਂ',
28
- 'ਉੱਨੀ',
29
- 'ਵੀਹ',
30
- 'ਇੱਕੀ',
31
- 'ਬਾਈ',
32
- 'ਤੇਈ',
33
- 'ਚੌਬੀ',
34
- 'ਪੱਚੀ',
35
- 'ਛੱਬੀ',
36
- 'ਸਤਾਈ',
37
- 'ਅਠਾਈ',
38
- 'ਉਨੱਤੀ',
39
- 'ਤੀਹ',
40
- 'ਇਕੱਤੀ',
41
- 'ਬੱਤੀ',
42
- 'ਤੇਤੀ',
43
- 'ਚੌਂਤੀ',
44
- 'ਪੈਂਤੀ',
45
- 'ਛੱਤੀ',
46
- 'ਸੈਂਤੀ',
47
- 'ਅਠੱਤੀ',
48
- 'ਉਨਤਾਲੀ',
49
- 'ਚਾਲੀ',
50
- 'ਇਕਤਾਲੀ',
51
- 'ਬਿਆਲੀ',
52
- 'ਤਿਰਤਾਲੀ',
53
- 'ਚੁਵਾਲੀ',
54
- 'ਪੰਤਾਲੀ',
55
- 'ਛਿਆਲੀ',
56
- 'ਸੈਂਤਾਲੀ',
57
- 'ਅਠਤਾਲੀ',
58
- 'ਉਨੰਜਾ',
59
- 'ਪੰਜਾਹ',
60
- 'ਇਕਵੰਜਾ',
61
- 'ਬਵੰਜਾ',
62
- 'ਤਰਵੰਜਾ',
63
- 'ਚੁਰਵੰਜਾ',
64
- 'ਪੰਜਵੰਜਾ',
65
- 'ਛਪੰਜਾ',
66
- 'ਸੱਤਵੰਜਾ',
67
- 'ਅਠਵੰਜਾ',
68
- 'ਉਨਾਹਠ',
69
- 'ਸੱਠ',
70
- 'ਇਕਾਹਠ',
71
- 'ਬਾਹਠ',
72
- 'ਤਰਸਠ',
73
- 'ਚੌਂਸਠ',
74
- 'ਪੈਂਸਠ',
75
- 'ਛਿਆਸਠ',
76
- 'ਸੜਸਠ',
77
- 'ਅੜਸਠ',
78
- 'ਉਣਹੱਤਰ',
79
- 'ਸਤੱਰ',
80
- 'ਇਕਹੱਤਰ',
81
- 'ਬਹੱਤਰ',
82
- 'ਤਹੱਤਰ',
83
- 'ਚੌਹੱਤਰ',
84
- 'ਪੰਝਹੱਤਰ',
85
- 'ਛਿਹੱਤਰ',
86
- 'ਸਤੱਤਰ',
87
- 'ਅਠੱਤਰ',
88
- 'ਉਨਾਸੀ',
89
- 'ਅੱਸੀ',
90
- 'ਇਕਿਆਸੀ',
91
- 'ਬਿਆਸੀ',
92
- 'ਤਰਿਆਸੀ',
93
- 'ਚੌਰਿਆਸੀ',
94
- 'ਪਚਾਸੀ',
95
- 'ਛਿਆਸੀ',
96
- 'ਸੱਤਾਸੀ',
97
- 'ਅਠਾਸੀ',
98
- 'ਨਵਾਸੀ',
99
- 'ਨੱਬੇ',
100
- 'ਇਕਾਨਵੇਂ',
101
- 'ਬਾਨਵੇਂ',
102
- 'ਤਰਾਨਵੇਂ',
103
- 'ਚੁਰਾਨਵੇਂ',
104
- 'ਪੰਚਾਨਵੇਂ',
105
- 'ਛਿਆਨਵੇਂ',
106
- 'ਸਤਾਨਵੇਂ',
107
- 'ਅਠਾਨਵੇਂ',
108
- 'ਨਿਨਾਨਵੇਂ'
109
- ]
110
-
111
- scaleWords = [
112
- '',
113
- 'ਹਜ਼ਾਰ',
114
- 'ਲੱਖ',
115
- 'ਕਰੋੜ',
116
- 'ਅਰਬ',
117
- 'ਖਰਬ',
118
- 'ਨੀਲ',
119
- 'ਪਦਮ',
120
- 'ਸ਼ੰਖ'
121
- ]
122
- }
123
-
124
- export default function convertToWords (value, options = {}) {
125
- return new Punjabi(options).convertToWords(value)
126
- }
@@ -1,144 +0,0 @@
1
- export default AbstractLanguage;
2
- /**
3
- * Abstract base class for language converters.
4
- *
5
- * What this class handles:
6
- * - Validates and normalizes caller input (`number | string | bigint`), rejecting NaN/invalid strings.
7
- * - Splits sign, whole, and decimal parts, caching the whole part for languages that need it.
8
- * - Delegates whole-number wording to `convertWholePart(wholeNumber)` implemented by subclasses.
9
- * - Converts decimals via `decimalDigitsToWords()`, preserving leading zeros and supporting per-digit mode when `convertDecimalsPerDigit` is true.
10
- *
11
- * What subclasses must provide:
12
- * - `convertWholePart(wholeNumber)` method implementation (required; abstract).
13
- * - `negativeWord` class property (word preceding negative numbers, e.g., "minus").
14
- * - `zeroWord` class property (word for digit 0, e.g., "zero").
15
- * - `decimalSeparatorWord` class property (word between whole and decimal, e.g., "point").
16
- * - `wordSeparator` class property (word separator in output, typically a space).
17
- * Optional: override `convertDecimalsPerDigit`, `digits`, or `convertDigitToWord()` for custom behavior.
18
- *
19
- * This class stays minimal; language grammar lives in subclasses.
20
- *
21
- * @abstract
22
- */
23
- declare class AbstractLanguage {
24
- /**
25
- * Word that precedes negative numbers (e.g., "minus", "negative", "moins").
26
- * @type {string}
27
- */
28
- negativeWord: string;
29
- /**
30
- * Word that separates whole and decimal parts (e.g., "point", "virgule", "comma").
31
- * @type {string}
32
- */
33
- decimalSeparatorWord: string;
34
- /**
35
- * Word representation for the digit 0 (e.g., "zero", "zéro", "null").
36
- * @type {string}
37
- */
38
- zeroWord: string;
39
- /**
40
- * Character(s) used to separate words in the output (typically a space).
41
- * @type {string}
42
- */
43
- wordSeparator: string;
44
- /**
45
- * Cached whole number portion from the most recent conversion.
46
- * Some languages need access to this value during conversion for
47
- * pluralization rules or special cases (e.g., Czech, Hebrew).
48
- * @type {bigint}
49
- */
50
- cachedWholeNumber: bigint;
51
- /**
52
- * Whether to convert decimal digits individually rather than grouped.
53
- * - `true`: Each digit converted separately (e.g., "05" → "zero five")
54
- * - `false`: Leading zeros preserved, remaining grouped (e.g., "14" → "fourteen")
55
- * Used by languages like Japanese, Thai, Tamil, Telugu.
56
- * @type {boolean}
57
- */
58
- convertDecimalsPerDigit: boolean;
59
- /**
60
- * Optional array of digit words for direct lookup in `convertDigitToWord()`.
61
- * - Length 10: indices 0–9 map directly to digit words
62
- * - Length 9: indices 0–8 map to words for digits 1–9
63
- * - `null`: Falls back to `convertWholePart()` for digit conversion
64
- * @type {string[]|null}
65
- */
66
- digits: string[] | null;
67
- /**
68
- * Convert a single decimal digit (0-9) to its word representation.
69
- *
70
- * Default behavior:
71
- * - 0 returns the language's `zeroWord`
72
- * - If a `digits` array is present, use it for direct lookup
73
- * - Length 10: indices 0–9 map directly
74
- * - Length 9: indices 1–9 map via `idx - 1`
75
- * - Otherwise delegate to `convertWholePart(digit)`
76
- *
77
- * Subclasses may override this for custom logic.
78
- *
79
- * @protected
80
- * @param {bigint} digit A single digit value (0-9) as BigInt
81
- * @returns {string} The word representation of the digit
82
- */
83
- protected convertDigitToWord(digit: bigint): string;
84
- /**
85
- * Convert the decimal fractional digits into words.
86
- *
87
- * Behavior depends on the `convertDecimalsPerDigit` class property:
88
- *
89
- * **Per-digit mode** (`convertDecimalsPerDigit: true`):
90
- * - Each decimal digit is converted individually using `convertDigitToWord()`
91
- * - Example: "05" -> [zero, 'five'], "14" -> ['one', 'four']
92
- * - Used by: Japanese, Thai, Tamil, Telugu
93
- *
94
- * **Grouped mode** (default, `convertDecimalsPerDigit: false`):
95
- * - Leading zeros are preserved as individual `zeroWord` entries
96
- * - Remaining digits are grouped and converted as a number
97
- * - Example: "05" -> [zero, 'five'], "14" -> ['fourteen']
98
- * - Used by: Most languages (English, Spanish, French, etc.)
99
- *
100
- * @protected
101
- * @param {string} decimalString The decimal digits as a string (e.g. `'05'` for 3.05).
102
- * @returns {Array<string>} Array of word tokens representing the fractional part.
103
- *
104
- * @example
105
- * // Per-digit mode
106
- * decimalDigitsToWords('05'); // -> [this.zeroWord, 'five']
107
- * decimalDigitsToWords('14'); // -> ['one', 'four']
108
- *
109
- * // Grouped mode
110
- * decimalDigitsToWords('05'); // -> [this.zeroWord, 'five']
111
- * decimalDigitsToWords('14'); // -> ['fourteen']
112
- */
113
- protected decimalDigitsToWords(decimalString: string): Array<string>;
114
- /**
115
- * Convert a numeric input into its language cardinal representation.
116
- *
117
- * This is the public entry point used by consumers. It normalizes the input
118
- * (accepting `number | string | bigint`), validates it, splits sign and
119
- * fractional parts, and delegates whole-number conversion to
120
- * `convertWholePart(BigInt)` and fractional conversion to `decimalDigitsToWords()`.
121
- *
122
- * Errors and validation:
123
- * - Passing `NaN` (as `number`) throws `TypeError`.
124
- * - Passing a non-numeric `string` throws `Error`.
125
- * - Passing an unsupported type throws `TypeError`.
126
- *
127
- * @public
128
- * @param {number|string|bigint} value Numeric input to convert. Strings may include a single `.` decimal marker.
129
- * @returns {string} The localized cardinal string.
130
- * @throws {TypeError|Error} For invalid input as described above.
131
- */
132
- public convertToWords(value: number | string | bigint): string;
133
- /**
134
- * Convert a BigInt whole number to its cardinal word representation.
135
- *
136
- * This is a template method that subclasses MUST implement to provide
137
- * language-specific number conversion logic.
138
- *
139
- * @abstract
140
- * @param {bigint} wholeNumber The whole number part to convert
141
- * @returns {string} The cardinal representation in the target language
142
- */
143
- convertWholePart(wholeNumber: bigint): string;
144
- }
@@ -1,148 +0,0 @@
1
- export default GreedyScaleLanguage;
2
- export type WordSet = {
3
- /**
4
- * - The language word or phrase
5
- */
6
- word: string;
7
- /**
8
- * - The numeric value represented by the word
9
- */
10
- value: bigint;
11
- };
12
- /**
13
- * Array of scale word pairs in descending order. Each pair contains:
14
- * - [0]: BigInt numeric value
15
- * - [1]: String word representation
16
- * Must be ordered largest to smallest for the greedy algorithm.
17
- */
18
- export type ScaleWordPairs = Array<Array<(bigint | string)>>;
19
- /**
20
- * @typedef {Object} WordSet
21
- * @property {string} word - The language word or phrase
22
- * @property {bigint} value - The numeric value represented by the word
23
- */
24
- /**
25
- * @typedef {Array.<Array.<(bigint|string)>>} ScaleWordPairs
26
- * Array of scale word pairs in descending order. Each pair contains:
27
- * - [0]: BigInt numeric value
28
- * - [1]: String word representation
29
- * Must be ordered largest to smallest for the greedy algorithm.
30
- */
31
- /**
32
- * Greedy scale language converter implementing the "highest-matching scale word" algorithm.
33
- *
34
- * Responsibilities:
35
- * - Decompose a whole-number value into a sequence of scale word-sets.
36
- * - Provide helpers to merge and post-process matched word-sets.
37
- * - Inherits decimal handling from AbstractLanguage (supports grouped and per-digit
38
- * modes via the `convertDecimalsPerDigit` class property).
39
- *
40
- * Subclass requirements:
41
- * - Define `scaleWordPairs` (ordered descending) as `[BigInt, string]` tuples.
42
- * - Implement `mergeScales(leftWordSet, rightWordSet)` to combine adjacent word-sets
43
- * per language grammar.
44
- *
45
- * Scale words specification:
46
- * - `scaleWordPairs` is an Array of 2-tuples: `[BigInt, string]` where the first element
47
- * is the numeric value (BigInt) and the second is the word used for that value.
48
- * - Scale words MUST be ordered from largest to smallest (descending) for the algorithm
49
- * to function correctly.
50
- *
51
- * @abstract
52
- * @extends AbstractLanguage
53
- * @example
54
- * // Example `scaleWordPairs` for English (descending order):
55
- * // [[1000000000n, 'billion'], [1000000n, 'million'], [1000n, 'thousand'], [100n, 'hundred'], ..., [1n, 'one']]
56
- */
57
- declare class GreedyScaleLanguage extends AbstractLanguage {
58
- /**
59
- * Array of scale word pairs mapping numeric values to their word representations.
60
- *
61
- * Each element is a 2-tuple: `[BigInt, string]` where the first element is the
62
- * numeric value and the second is the word for that value. The array MUST be
63
- * ordered from largest to smallest (descending) for the greedy algorithm to work correctly.
64
- *
65
- * @type {Array.<Array.<(bigint|string)>>}
66
- * @example
67
- * // English scale words (descending order):
68
- * // [[1000000000n, 'billion'], [1000000n, 'million'], [1000n, 'thousand'], [100n, 'hundred'], ..., [1n, 'one']]
69
- */
70
- scaleWordPairs: Array<Array<(bigint | string)>>;
71
- /**
72
- * Return the word associated with an exact scale word-set numeric value.
73
- *
74
- * @param {bigint|number} scaleValue Numeric word-set object key (prefer BigInt for exact matching).
75
- * @returns {string|undefined} The word for the provided scale value, or `undefined`.
76
- */
77
- getScaleWord(scaleValue: bigint | number): string | undefined;
78
- /**
79
- * Decompose a whole-number into a sequence of scale word-sets.
80
- *
81
- * This internal helper returns a nested structure that represents quantities and
82
- * their matching scale words (e.g. `[{ 'one': 1n }, { 'hundred': 100n }, ...]`).
83
- * The result is designed to be reduced by `mergeWordSets()` using language-specific `mergeScales()`.
84
- *
85
- * For quantities > 1, the multiplier is recursively decomposed. For quantity = 1,
86
- * the implicit "one" is represented with `{ 'one': 1n }` and typically omitted during mergeScales().
87
- *
88
- * @protected
89
- * @param {bigint} wholeNumber The integer value to decompose (BigInt preferred).
90
- * @returns {Array<Object|Array>} An array of word-set objects and possibly nested arrays.
91
- */
92
- protected decomposeToScales(wholeNumber: bigint): Array<any | any[]>;
93
- /**
94
- * Reduce a nested array of word-sets into a single merged word-set object.
95
- *
96
- * This method repeatedly applies the subclass `mergeScales()` operation until a single
97
- * object remains. It normalizes nested arrays by recursively merging them.
98
- *
99
- * @protected
100
- * @param {Array<Object|Array>} mergeWordSetsList Array of word-set objects and nested arrays.
101
- * @returns {Object} Merged word-set where the single object key is the language string
102
- * and its value is the numeric BigInt result for that string.
103
- */
104
- protected mergeWordSets(mergeWordSetsList: Array<any | any[]>): any;
105
- /**
106
- * Combine two adjacent word-sets into a single merged word-set.
107
- *
108
- * This is the core language-specific method that must be implemented by subclasses
109
- * to define how adjacent word-sets are combined according to the language's grammar.
110
- * For example, English combines "twenty" + "three" → "twenty-three", while
111
- * French might combine "quatre-vingts" + "dix" → "quatre-vingt-dix".
112
- *
113
- * @abstract
114
- * @protected
115
- * @param {Object} leftWordSet Left operand as `{ word: bigint }` pair.
116
- * @param {Object} rightWordSet Right operand as `{ word: bigint }` pair.
117
- * @returns {Object} Single merged word-set object with combined text and numeric value.
118
- *
119
- * @example
120
- * // English implementation might handle:
121
- * // mergeScales({ 'twenty': 20n }, { 'three': 3n }) → { 'twenty-three': 23n }
122
- * // mergeScales({ 'one': 1n }, { 'hundred': 100n }) → { 'one hundred': 100n }
123
- */
124
- protected mergeScales(leftWordSet: any, rightWordSet: any): any;
125
- /**
126
- * Final string post-processing hook.
127
- *
128
- * Subclasses may override to apply language-specific whitespace, punctuation or
129
- * orthographic corrections.
130
- *
131
- * @protected
132
- * @param {string} output Merged language string produced by `convertWholePart` flow.
133
- * @returns {string} Final formatted string.
134
- */
135
- protected finalizeWords(output: string): string;
136
- /**
137
- * Convert an integer value to its language-specific cardinal words.
138
- *
139
- * This method orchestrates decomposition, merging and final formatting. It does
140
- * not handle decimals or sign; those concerns are implemented in
141
- * `AbstractLanguage.convertToWords` which calls this helper for the whole-number part.
142
- *
143
- * @param {bigint|number} wholeNumber Whole-number value to convert (BigInt is preferred).
144
- * @returns {string} The cardinal representation for `value` in the language.
145
- */
146
- convertWholePart(wholeNumber: bigint | number): string;
147
- }
148
- import AbstractLanguage from './abstract-language.js';