n2words 1.23.1 → 2.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 (322) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +317 -59
  3. package/dist/ArabicConverter.js +3 -0
  4. package/dist/ArabicConverter.js.map +1 -0
  5. package/dist/AzerbaijaniConverter.js +3 -0
  6. package/dist/AzerbaijaniConverter.js.map +1 -0
  7. package/dist/BanglaConverter.js +3 -0
  8. package/dist/BanglaConverter.js.map +1 -0
  9. package/dist/BiblicalHebrewConverter.js +3 -0
  10. package/dist/BiblicalHebrewConverter.js.map +1 -0
  11. package/dist/CroatianConverter.js +3 -0
  12. package/dist/CroatianConverter.js.map +1 -0
  13. package/dist/CzechConverter.js +3 -0
  14. package/dist/CzechConverter.js.map +1 -0
  15. package/dist/DanishConverter.js +3 -0
  16. package/dist/DanishConverter.js.map +1 -0
  17. package/dist/DutchConverter.js +3 -0
  18. package/dist/DutchConverter.js.map +1 -0
  19. package/dist/EnglishConverter.js +3 -0
  20. package/dist/EnglishConverter.js.map +1 -0
  21. package/dist/FilipinoConverter.js +3 -0
  22. package/dist/FilipinoConverter.js.map +1 -0
  23. package/dist/FrenchBelgiumConverter.js +3 -0
  24. package/dist/FrenchBelgiumConverter.js.map +1 -0
  25. package/dist/FrenchConverter.js +3 -0
  26. package/dist/FrenchConverter.js.map +1 -0
  27. package/dist/GermanConverter.js +3 -0
  28. package/dist/GermanConverter.js.map +1 -0
  29. package/dist/GreekConverter.js +3 -0
  30. package/dist/GreekConverter.js.map +1 -0
  31. package/dist/GujaratiConverter.js +3 -0
  32. package/dist/GujaratiConverter.js.map +1 -0
  33. package/dist/HebrewConverter.js +3 -0
  34. package/dist/HebrewConverter.js.map +1 -0
  35. package/dist/HindiConverter.js +3 -0
  36. package/dist/HindiConverter.js.map +1 -0
  37. package/dist/HungarianConverter.js +3 -0
  38. package/dist/HungarianConverter.js.map +1 -0
  39. package/dist/IndonesianConverter.js +3 -0
  40. package/dist/IndonesianConverter.js.map +1 -0
  41. package/dist/ItalianConverter.js +3 -0
  42. package/dist/ItalianConverter.js.map +1 -0
  43. package/dist/JapaneseConverter.js +3 -0
  44. package/dist/JapaneseConverter.js.map +1 -0
  45. package/dist/KannadaConverter.js +3 -0
  46. package/dist/KannadaConverter.js.map +1 -0
  47. package/dist/KoreanConverter.js +3 -0
  48. package/dist/KoreanConverter.js.map +1 -0
  49. package/dist/LatvianConverter.js +3 -0
  50. package/dist/LatvianConverter.js.map +1 -0
  51. package/dist/LithuanianConverter.js +3 -0
  52. package/dist/LithuanianConverter.js.map +1 -0
  53. package/dist/MalayConverter.js +3 -0
  54. package/dist/MalayConverter.js.map +1 -0
  55. package/dist/MarathiConverter.js +3 -0
  56. package/dist/MarathiConverter.js.map +1 -0
  57. package/dist/NorwegianBokmalConverter.js +3 -0
  58. package/dist/NorwegianBokmalConverter.js.map +1 -0
  59. package/dist/PersianConverter.js +3 -0
  60. package/dist/PersianConverter.js.map +1 -0
  61. package/dist/PolishConverter.js +3 -0
  62. package/dist/PolishConverter.js.map +1 -0
  63. package/dist/PortugueseConverter.js +3 -0
  64. package/dist/PortugueseConverter.js.map +1 -0
  65. package/dist/PunjabiConverter.js +3 -0
  66. package/dist/PunjabiConverter.js.map +1 -0
  67. package/dist/RomanianConverter.js +3 -0
  68. package/dist/RomanianConverter.js.map +1 -0
  69. package/dist/RussianConverter.js +3 -0
  70. package/dist/RussianConverter.js.map +1 -0
  71. package/dist/SerbianCyrillicConverter.js +3 -0
  72. package/dist/SerbianCyrillicConverter.js.map +1 -0
  73. package/dist/SerbianLatinConverter.js +3 -0
  74. package/dist/SerbianLatinConverter.js.map +1 -0
  75. package/dist/SimplifiedChineseConverter.js +3 -0
  76. package/dist/SimplifiedChineseConverter.js.map +1 -0
  77. package/dist/SpanishConverter.js +3 -0
  78. package/dist/SpanishConverter.js.map +1 -0
  79. package/dist/SwahiliConverter.js +3 -0
  80. package/dist/SwahiliConverter.js.map +1 -0
  81. package/dist/SwedishConverter.js +3 -0
  82. package/dist/SwedishConverter.js.map +1 -0
  83. package/dist/TamilConverter.js +3 -0
  84. package/dist/TamilConverter.js.map +1 -0
  85. package/dist/TeluguConverter.js +3 -0
  86. package/dist/TeluguConverter.js.map +1 -0
  87. package/dist/ThaiConverter.js +3 -0
  88. package/dist/ThaiConverter.js.map +1 -0
  89. package/dist/TraditionalChineseConverter.js +3 -0
  90. package/dist/TraditionalChineseConverter.js.map +1 -0
  91. package/dist/TurkishConverter.js +3 -0
  92. package/dist/TurkishConverter.js.map +1 -0
  93. package/dist/UkrainianConverter.js +3 -0
  94. package/dist/UkrainianConverter.js.map +1 -0
  95. package/dist/UrduConverter.js +3 -0
  96. package/dist/UrduConverter.js.map +1 -0
  97. package/dist/VietnameseConverter.js +3 -0
  98. package/dist/VietnameseConverter.js.map +1 -0
  99. package/dist/n2words.js +3 -2
  100. package/dist/n2words.js.map +1 -1
  101. package/lib/classes/abstract-language.d.ts +158 -34
  102. package/lib/classes/abstract-language.js +223 -115
  103. package/lib/classes/greedy-scale-language.d.ts +109 -0
  104. package/lib/classes/greedy-scale-language.js +201 -0
  105. package/lib/classes/slavic-language.d.ts +148 -0
  106. package/lib/classes/slavic-language.js +281 -0
  107. package/lib/classes/south-asian-language.d.ts +70 -0
  108. package/lib/classes/south-asian-language.js +154 -0
  109. package/lib/classes/turkic-language.d.ts +26 -0
  110. package/lib/classes/turkic-language.js +59 -0
  111. package/lib/languages/ar.d.ts +30 -0
  112. package/lib/languages/ar.js +159 -0
  113. package/lib/languages/az.d.ts +12 -0
  114. package/lib/languages/az.js +42 -0
  115. package/lib/languages/bn.d.ts +11 -0
  116. package/lib/languages/bn.js +131 -0
  117. package/lib/languages/cs.d.ts +88 -0
  118. package/lib/languages/cs.js +143 -0
  119. package/lib/languages/da.d.ts +15 -0
  120. package/lib/languages/da.js +120 -0
  121. package/lib/languages/de.d.ts +14 -0
  122. package/lib/languages/de.js +101 -0
  123. package/lib/languages/el.d.ts +14 -0
  124. package/lib/languages/el.js +90 -0
  125. package/lib/languages/en.d.ts +16 -0
  126. package/lib/languages/en.js +86 -0
  127. package/lib/languages/es.d.ts +15 -0
  128. package/lib/languages/es.js +121 -0
  129. package/lib/languages/fa.d.ts +47 -0
  130. package/lib/languages/fa.js +144 -0
  131. package/lib/languages/fil.d.ts +16 -0
  132. package/lib/languages/fil.js +121 -0
  133. package/lib/languages/fr-BE.d.ts +11 -0
  134. package/lib/languages/fr-BE.js +25 -0
  135. package/lib/languages/fr.d.ts +15 -0
  136. package/lib/languages/fr.js +106 -0
  137. package/lib/languages/gu.d.ts +11 -0
  138. package/lib/languages/gu.js +132 -0
  139. package/lib/languages/hbo.d.ts +113 -0
  140. package/lib/languages/hbo.js +251 -0
  141. package/lib/languages/he.d.ts +80 -0
  142. package/lib/languages/he.js +206 -0
  143. package/lib/languages/hi.d.ts +11 -0
  144. package/lib/languages/hi.js +131 -0
  145. package/lib/languages/hr.d.ts +80 -0
  146. package/lib/languages/hr.js +113 -0
  147. package/lib/languages/hu.d.ts +22 -0
  148. package/lib/languages/hu.js +137 -0
  149. package/lib/languages/id.d.ts +37 -0
  150. package/lib/languages/id.js +159 -0
  151. package/lib/languages/it.d.ts +37 -0
  152. package/lib/languages/it.js +132 -0
  153. package/lib/languages/ja.d.ts +17 -0
  154. package/lib/languages/ja.js +137 -0
  155. package/lib/languages/kn.d.ts +11 -0
  156. package/lib/languages/kn.js +42 -0
  157. package/lib/languages/ko.d.ts +14 -0
  158. package/lib/languages/ko.js +55 -0
  159. package/lib/{i18n/pl.d.ts → languages/lt.d.ts} +18 -15
  160. package/lib/languages/lt.js +136 -0
  161. package/lib/{i18n/lt.d.ts → languages/lv.d.ts} +16 -14
  162. package/lib/languages/lv.js +130 -0
  163. package/lib/languages/mr.d.ts +11 -0
  164. package/lib/languages/mr.js +132 -0
  165. package/lib/languages/ms.d.ts +31 -0
  166. package/lib/languages/ms.js +150 -0
  167. package/lib/languages/nb.d.ts +12 -0
  168. package/lib/languages/nb.js +100 -0
  169. package/lib/languages/nl.d.ts +16 -0
  170. package/lib/languages/nl.js +155 -0
  171. package/lib/languages/pa.d.ts +11 -0
  172. package/lib/languages/pa.js +131 -0
  173. package/lib/{i18n/uk.d.ts → languages/pl.d.ts} +16 -14
  174. package/lib/languages/pl.js +110 -0
  175. package/lib/languages/pt.d.ts +29 -0
  176. package/lib/languages/pt.js +112 -0
  177. package/lib/languages/ro.d.ts +158 -0
  178. package/lib/languages/ro.js +273 -0
  179. package/lib/languages/ru.d.ts +85 -0
  180. package/lib/languages/ru.js +96 -0
  181. package/lib/languages/sr-Cyrl.d.ts +80 -0
  182. package/lib/languages/sr-Cyrl.js +113 -0
  183. package/lib/{i18n/cz.d.ts → languages/sr-Latn.d.ts} +26 -14
  184. package/lib/languages/sr-Latn.js +113 -0
  185. package/lib/languages/sv.d.ts +14 -0
  186. package/lib/languages/sv.js +90 -0
  187. package/lib/languages/sw.d.ts +39 -0
  188. package/lib/languages/sw.js +126 -0
  189. package/lib/languages/ta.d.ts +20 -0
  190. package/lib/languages/ta.js +226 -0
  191. package/lib/languages/te.d.ts +22 -0
  192. package/lib/languages/te.js +219 -0
  193. package/lib/languages/th.d.ts +17 -0
  194. package/lib/languages/th.js +117 -0
  195. package/lib/languages/tr.d.ts +12 -0
  196. package/lib/languages/tr.js +56 -0
  197. package/lib/languages/uk.d.ts +85 -0
  198. package/lib/{i18n → languages}/uk.js +33 -32
  199. package/lib/languages/ur.d.ts +11 -0
  200. package/lib/languages/ur.js +131 -0
  201. package/lib/{i18n → languages}/vi.d.ts +15 -13
  202. package/lib/languages/vi.js +147 -0
  203. package/lib/languages/zh-Hans.d.ts +21 -0
  204. package/lib/languages/zh-Hans.js +111 -0
  205. package/lib/languages/zh-Hant.d.ts +21 -0
  206. package/lib/languages/zh-Hant.js +111 -0
  207. package/lib/n2words.d.ts +207 -7
  208. package/lib/n2words.js +535 -81
  209. package/package.json +126 -79
  210. package/dist/ar.js +0 -2
  211. package/dist/ar.js.map +0 -1
  212. package/dist/az.js +0 -2
  213. package/dist/az.js.map +0 -1
  214. package/dist/cz.js +0 -2
  215. package/dist/cz.js.map +0 -1
  216. package/dist/de.js +0 -2
  217. package/dist/de.js.map +0 -1
  218. package/dist/dk.js +0 -2
  219. package/dist/dk.js.map +0 -1
  220. package/dist/en.js +0 -2
  221. package/dist/en.js.map +0 -1
  222. package/dist/es.js +0 -2
  223. package/dist/es.js.map +0 -1
  224. package/dist/fa.js +0 -2
  225. package/dist/fa.js.map +0 -1
  226. package/dist/fr-BE.js +0 -2
  227. package/dist/fr-BE.js.map +0 -1
  228. package/dist/fr.js +0 -2
  229. package/dist/fr.js.map +0 -1
  230. package/dist/he.js +0 -2
  231. package/dist/he.js.map +0 -1
  232. package/dist/hr.js +0 -2
  233. package/dist/hr.js.map +0 -1
  234. package/dist/hu.js +0 -2
  235. package/dist/hu.js.map +0 -1
  236. package/dist/id.js +0 -2
  237. package/dist/id.js.map +0 -1
  238. package/dist/it.js +0 -2
  239. package/dist/it.js.map +0 -1
  240. package/dist/ko.js +0 -2
  241. package/dist/ko.js.map +0 -1
  242. package/dist/lt.js +0 -2
  243. package/dist/lt.js.map +0 -1
  244. package/dist/lv.js +0 -2
  245. package/dist/lv.js.map +0 -1
  246. package/dist/n2words.d.ts +0 -2
  247. package/dist/nl.js +0 -2
  248. package/dist/nl.js.map +0 -1
  249. package/dist/no.js +0 -2
  250. package/dist/no.js.map +0 -1
  251. package/dist/pl.js +0 -2
  252. package/dist/pl.js.map +0 -1
  253. package/dist/pt.js +0 -2
  254. package/dist/pt.js.map +0 -1
  255. package/dist/ro.js +0 -2
  256. package/dist/ro.js.map +0 -1
  257. package/dist/ru.js +0 -2
  258. package/dist/ru.js.map +0 -1
  259. package/dist/sr.js +0 -2
  260. package/dist/sr.js.map +0 -1
  261. package/dist/tr.js +0 -2
  262. package/dist/tr.js.map +0 -1
  263. package/dist/uk.js +0 -2
  264. package/dist/uk.js.map +0 -1
  265. package/dist/vi.js +0 -2
  266. package/dist/vi.js.map +0 -1
  267. package/dist/zh.js +0 -2
  268. package/dist/zh.js.map +0 -1
  269. package/lib/classes/base-language.d.ts +0 -58
  270. package/lib/classes/base-language.js +0 -172
  271. package/lib/i18n/ar.d.ts +0 -41
  272. package/lib/i18n/ar.js +0 -209
  273. package/lib/i18n/az.d.ts +0 -15
  274. package/lib/i18n/az.js +0 -66
  275. package/lib/i18n/cz.js +0 -135
  276. package/lib/i18n/de.d.ts +0 -17
  277. package/lib/i18n/de.js +0 -103
  278. package/lib/i18n/dk.d.ts +0 -14
  279. package/lib/i18n/dk.js +0 -110
  280. package/lib/i18n/en.d.ts +0 -22
  281. package/lib/i18n/en.js +0 -86
  282. package/lib/i18n/es.d.ts +0 -16
  283. package/lib/i18n/es.js +0 -110
  284. package/lib/i18n/fa.d.ts +0 -54
  285. package/lib/i18n/fa.js +0 -106
  286. package/lib/i18n/fr-BE.d.ts +0 -11
  287. package/lib/i18n/fr-BE.js +0 -20
  288. package/lib/i18n/fr.d.ts +0 -15
  289. package/lib/i18n/fr.js +0 -99
  290. package/lib/i18n/he.d.ts +0 -61
  291. package/lib/i18n/he.js +0 -132
  292. package/lib/i18n/hr.d.ts +0 -68
  293. package/lib/i18n/hr.js +0 -129
  294. package/lib/i18n/hu.d.ts +0 -17
  295. package/lib/i18n/hu.js +0 -135
  296. package/lib/i18n/id.d.ts +0 -43
  297. package/lib/i18n/id.js +0 -156
  298. package/lib/i18n/it.d.ts +0 -29
  299. package/lib/i18n/it.js +0 -137
  300. package/lib/i18n/ko.d.ts +0 -15
  301. package/lib/i18n/ko.js +0 -56
  302. package/lib/i18n/lt.js +0 -138
  303. package/lib/i18n/lv.d.ts +0 -57
  304. package/lib/i18n/lv.js +0 -120
  305. package/lib/i18n/nl.d.ts +0 -20
  306. package/lib/i18n/nl.js +0 -125
  307. package/lib/i18n/no.d.ts +0 -15
  308. package/lib/i18n/no.js +0 -77
  309. package/lib/i18n/pl.js +0 -126
  310. package/lib/i18n/pt.d.ts +0 -26
  311. package/lib/i18n/pt.js +0 -118
  312. package/lib/i18n/ro.d.ts +0 -109
  313. package/lib/i18n/ro.js +0 -360
  314. package/lib/i18n/ru.d.ts +0 -30
  315. package/lib/i18n/ru.js +0 -198
  316. package/lib/i18n/sr.d.ts +0 -56
  317. package/lib/i18n/sr.js +0 -127
  318. package/lib/i18n/tr.d.ts +0 -15
  319. package/lib/i18n/tr.js +0 -64
  320. package/lib/i18n/vi.js +0 -151
  321. package/lib/i18n/zh.d.ts +0 -18
  322. package/lib/i18n/zh.js +0 -78
@@ -0,0 +1,144 @@
1
+ import { AbstractLanguage } from '../classes/abstract-language.js'
2
+
3
+ /**
4
+ * Persian language converter.
5
+ *
6
+ * Supports:
7
+ * - "و" (and) conjunction for compound numbers
8
+ * - Recursive conversion for larger numbers
9
+ */
10
+ export class Persian extends AbstractLanguage {
11
+ negativeWord = 'منفى'
12
+ decimalSeparatorWord = 'ممیّز'
13
+ zeroWord = 'صفر'
14
+
15
+ /**
16
+ * Words for digits 1-9.
17
+ * @type {Object.<number, string>}
18
+ */
19
+ onesWords = {
20
+ 1: 'یک',
21
+ 2: 'دو',
22
+ 3: 'سه',
23
+ 4: 'چهار',
24
+ 5: 'پنج',
25
+ 6: 'شش',
26
+ 7: 'هفت',
27
+ 8: 'هشت',
28
+ 9: 'نه'
29
+ }
30
+
31
+ /**
32
+ * Words for teen numbers (10-19).
33
+ * @type {Object.<number, string>}
34
+ */
35
+ teensWords = {
36
+ 10: 'ده',
37
+ 11: 'یازده',
38
+ 12: 'دوازده',
39
+ 13: 'سیزده',
40
+ 14: 'چهارده',
41
+ 15: 'پانزده',
42
+ 16: 'شانزده',
43
+ 17: 'هفده',
44
+ 18: 'هجده',
45
+ 19: 'نوزده'
46
+ }
47
+
48
+ /**
49
+ * Words for multiples of ten (20-90).
50
+ * @type {Object.<number, string>}
51
+ */
52
+ tensWords = {
53
+ 20: 'بیست',
54
+ 30: 'سی',
55
+ 40: 'چهل',
56
+ 50: 'پنجاه',
57
+ 60: 'شصت',
58
+ 70: 'هفتاد',
59
+ 80: 'هشتاد',
60
+ 90: 'نود'
61
+ }
62
+
63
+ /**
64
+ * Words for hundreds (100-900).
65
+ * @type {Object.<number, string>}
66
+ */
67
+ hundredsWords = {
68
+ 100: 'صد',
69
+ 200: 'دویست',
70
+ 300: 'سيصد',
71
+ 400: 'چهار صد',
72
+ 500: 'پانصد',
73
+ 600: 'ششصد',
74
+ 700: 'هفتصد',
75
+ 800: 'هشتصد',
76
+ 900: 'نهصد'
77
+ }
78
+
79
+ /**
80
+ * Scale magnitude words.
81
+ * @type {Object.<number, string>}
82
+ */
83
+ scaleWords = {
84
+ 1000: 'هزار',
85
+ 1_000_000: 'میلیون'
86
+ }
87
+
88
+ /** Converts integer part using categorized word tables. */
89
+ integerToWords (integerPart) {
90
+ // Zero
91
+ if (integerPart === 0n) {
92
+ return this.zeroWord
93
+ }
94
+
95
+ // 1-9
96
+ if (integerPart <= 9n) {
97
+ return this.onesWords[integerPart]
98
+ }
99
+
100
+ // 10-19
101
+ if (integerPart <= 19n) {
102
+ return this.teensWords[integerPart]
103
+ }
104
+
105
+ // 20-99
106
+ if (integerPart < 100n) {
107
+ const ones = integerPart % 10n
108
+ const tens = integerPart - ones
109
+ if (ones === 0n) {
110
+ return this.tensWords[tens]
111
+ }
112
+ return `${this.tensWords[tens]} و ${this.onesWords[ones]}`
113
+ }
114
+
115
+ // 100-999
116
+ if (integerPart < 1000n) {
117
+ const hundreds = 100n * (integerPart / 100n)
118
+ const remainder = integerPart - hundreds
119
+ if (remainder === 0n) {
120
+ return this.hundredsWords[hundreds]
121
+ }
122
+ return `${this.hundredsWords[hundreds]} و ${this.integerToWords(remainder)}`
123
+ }
124
+
125
+ // 1000-999999
126
+ if (integerPart < 1_000_000n) {
127
+ const thousandMultiplier = integerPart / 1000n
128
+ // Persian omits "one" before thousand: 1000 is just "هزار", not "یک هزار"
129
+ const thousandPrefix = thousandMultiplier === 1n
130
+ ? ''
131
+ : this.integerToWords(thousandMultiplier) + ' '
132
+ const remainder = integerPart % 1000n
133
+ const suffix = remainder === 0n ? '' : ' ' + this.integerToWords(remainder)
134
+ return `${thousandPrefix}${this.scaleWords[1000]}${suffix}`
135
+ }
136
+
137
+ // 1000000+
138
+ const millionMultiplier = integerPart / 1_000_000n
139
+ const millionPrefix = this.integerToWords(millionMultiplier) + ' ' + this.scaleWords[1_000_000]
140
+ const remainder = integerPart % 1_000_000n
141
+ const suffix = remainder === 0n ? '' : ' و ' + this.integerToWords(remainder)
142
+ return `${millionPrefix}${suffix}`
143
+ }
144
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Filipino language converter.
3
+ *
4
+ * Supports:
5
+ * - "ng" connectors between words
6
+ * - Implicit "one" omission
7
+ * - Special linkers for certain tens (e.g., "limampung")
8
+ */
9
+ export class Filipino extends GreedyScaleLanguage {
10
+ scaleWords: (string | bigint)[][];
11
+ /** Converts integer part with explicit zero handling. */
12
+ integerToWords(integerPart: any): string;
13
+ /** Combines two word-sets with Filipino connector and linker rules. */
14
+ combineWordSets(preceding: any, following: any): any;
15
+ }
16
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -0,0 +1,121 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * Filipino language converter.
5
+ *
6
+ * Supports:
7
+ * - "ng" connectors between words
8
+ * - Implicit "one" omission
9
+ * - Special linkers for certain tens (e.g., "limampung")
10
+ */
11
+ export class Filipino extends GreedyScaleLanguage {
12
+ negativeWord = 'negatibo'
13
+ decimalSeparatorWord = 'punto'
14
+ zeroWord = 'zero'
15
+ usePerDigitDecimals = true // Read decimals digit-by-digit
16
+
17
+ scaleWords = [
18
+ [1000000000000n, 'trilyong'],
19
+ [1000000000n, 'milyong'],
20
+ [1000000n, 'milyong'],
21
+ [1000n, 'libong'],
22
+ [100n, 'daang'],
23
+
24
+ // Tens
25
+ [90n, 'siyamnapu'],
26
+ [80n, 'walumpu'],
27
+ [70n, 'pitumpu'],
28
+ [60n, 'animnapu'],
29
+ [50n, 'limampu'],
30
+ [40n, 'apatnapu'],
31
+ [30n, 'tatlumpu'],
32
+ [20n, 'dalawampu'],
33
+
34
+ // Teens (must come before 10 to be matched first)
35
+ [19n, 'labinsiyam'],
36
+ [18n, 'labingwalo'],
37
+ [17n, 'labimpito'],
38
+ [16n, 'labinanum'],
39
+ [15n, 'labinlima'],
40
+ [14n, 'labinapat'],
41
+ [13n, 'labintatlo'],
42
+ [12n, 'labindalawa'],
43
+ [11n, 'labinisa'],
44
+ [10n, 'sampu'],
45
+
46
+ // Ones
47
+ [9n, 'siyam'],
48
+ [8n, 'walo'],
49
+ [7n, 'pito'],
50
+ [6n, 'anim'],
51
+ [5n, 'lima'],
52
+ [4n, 'apat'],
53
+ [3n, 'tatlo'],
54
+ [2n, 'dalawa'],
55
+ [1n, 'isa'],
56
+ [0n, 'zero']
57
+ ]
58
+
59
+ /** Converts integer part with explicit zero handling. */
60
+ integerToWords (integerPart) {
61
+ // Handle zero explicitly
62
+ if (integerPart === 0n) {
63
+ return this.zeroWord
64
+ }
65
+ return super.integerToWords(integerPart)
66
+ }
67
+
68
+ /** Combines two word-sets with Filipino connector and linker rules. */
69
+ combineWordSets (preceding, following) {
70
+ const precedingWord = Object.keys(preceding)[0]
71
+ const followingWord = Object.keys(following)[0]
72
+ const precedingValue = Object.values(preceding)[0]
73
+ const followingValue = Object.values(following)[0]
74
+
75
+ // Don't merge zero with anything - just return the non-zero value
76
+ if (precedingValue === 0n) {
77
+ return following
78
+ }
79
+ if (followingValue === 0n) {
80
+ return preceding
81
+ }
82
+
83
+ // Implicit "one" - omit when adding with values < 100
84
+ if (precedingValue === 1n && followingValue < 100n) {
85
+ return following
86
+ }
87
+
88
+ // Multiply when following is a scale word AND following > preceding
89
+ // Use "ng" connector for Filipino, but consonant-ending words use " na "
90
+ if (followingValue > precedingValue && followingValue >= 100n) {
91
+ // Words ending in consonants (not vowels) use " na " instead of "ng"
92
+ const vowels = ['a', 'e', 'i', 'o', 'u']
93
+ const lastChar = precedingWord[precedingWord.length - 1]
94
+ if (!vowels.includes(lastChar)) {
95
+ return {
96
+ [`${precedingWord} na ${followingWord}`]: precedingValue * followingValue
97
+ }
98
+ }
99
+ // Vowel-ending words add "ng"
100
+ return {
101
+ [`${precedingWord}ng ${followingWord}`]: precedingValue * followingValue
102
+ }
103
+ }
104
+
105
+ // Special Filipino rule: certain tens words take "-ng" linker when followed by ones
106
+ // Only limampu (50) confirmed to use this pattern
107
+ if (precedingValue >= 10n && precedingValue < 100n && followingValue >= 1n && followingValue < 10n) {
108
+ const tensWithNg = ['limampu']
109
+ if (tensWithNg.includes(precedingWord)) {
110
+ return {
111
+ [`${precedingWord}ng ${followingWord}`]: precedingValue + followingValue
112
+ }
113
+ }
114
+ }
115
+
116
+ // Default: space for addition
117
+ return {
118
+ [`${precedingWord} ${followingWord}`]: precedingValue + followingValue
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * French (Belgium) language converter.
3
+ *
4
+ * Supports:
5
+ * - Belgian regional variants: "septante" (70) and "nonante" (90)
6
+ * - Simplified tens naming (no complex arithmetic)
7
+ * - Inherits all other French grammar rules
8
+ */
9
+ export class FrenchBelgium extends French {
10
+ }
11
+ import { French } from './fr.js';
@@ -0,0 +1,25 @@
1
+ import { French } from './fr.js'
2
+
3
+ /**
4
+ * French (Belgium) language converter.
5
+ *
6
+ * Supports:
7
+ * - Belgian regional variants: "septante" (70) and "nonante" (90)
8
+ * - Simplified tens naming (no complex arithmetic)
9
+ * - Inherits all other French grammar rules
10
+ */
11
+ export class FrenchBelgium extends French {
12
+ constructor (options = {}) {
13
+ super(options)
14
+
15
+ // Insert 90n ('nonante') after 80n and 70n ('septante') after 60n
16
+ const tuples = [...this.scaleWords]
17
+ // Find index of 80n and insert 90n after it
18
+ const idx80 = tuples.findIndex(tuple => tuple[0] === 80n)
19
+ if (idx80 !== -1) tuples.splice(idx80, 0, [90n, 'nonante'])
20
+ // Find index of 60n and insert 70n after it
21
+ const idx60 = tuples.findIndex(tuple => tuple[0] === 60n)
22
+ if (idx60 !== -1) tuples.splice(idx60, 0, [70n, 'septante'])
23
+ this.scaleWords = tuples
24
+ }
25
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * French language converter.
3
+ *
4
+ * Supports:
5
+ * - Pluralization of "cent" (hundred) and other words
6
+ * - "et" (and) before odd numbers in tens place
7
+ * - Optional hyphenation for compound numbers
8
+ */
9
+ export class French extends GreedyScaleLanguage {
10
+ constructor(options?: {});
11
+ scaleWords: (string | bigint)[][];
12
+ /** Combines two word-sets with French pluralization and hyphenation rules. */
13
+ combineWordSets(preceding: any, following: any): any;
14
+ }
15
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -0,0 +1,106 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * French language converter.
5
+ *
6
+ * Supports:
7
+ * - Pluralization of "cent" (hundred) and other words
8
+ * - "et" (and) before odd numbers in tens place
9
+ * - Optional hyphenation for compound numbers
10
+ */
11
+ export class French extends GreedyScaleLanguage {
12
+ negativeWord = 'moins'
13
+ decimalSeparatorWord = 'virgule'
14
+ zeroWord = 'zéro'
15
+
16
+ scaleWords = [
17
+ [1_000_000_000_000_000_000_000_000_000n, 'quadrilliard'],
18
+ [1_000_000_000_000_000_000_000_000n, 'quadrillion'],
19
+ [1_000_000_000_000_000_000_000n, 'trilliard'],
20
+ [1_000_000_000_000_000_000n, 'trillion'],
21
+ [1_000_000_000_000_000n, 'billiard'],
22
+ [1_000_000_000_000n, 'billion'],
23
+ [1_000_000_000n, 'milliard'],
24
+ [1_000_000n, 'million'],
25
+ [1000n, 'mille'],
26
+ [100n, 'cent'],
27
+ [80n, 'quatre-vingts'],
28
+ [60n, 'soixante'],
29
+ [50n, 'cinquante'],
30
+ [40n, 'quarante'],
31
+ [30n, 'trente'],
32
+ [20n, 'vingt'],
33
+ [19n, 'dix-neuf'],
34
+ [18n, 'dix-huit'],
35
+ [17n, 'dix-sept'],
36
+ [16n, 'seize'],
37
+ [15n, 'quinze'],
38
+ [14n, 'quatorze'],
39
+ [13n, 'treize'],
40
+ [12n, 'douze'],
41
+ [11n, 'onze'],
42
+ [10n, 'dix'],
43
+ [9n, 'neuf'],
44
+ [8n, 'huit'],
45
+ [7n, 'sept'],
46
+ [6n, 'six'],
47
+ [5n, 'cinq'],
48
+ [4n, 'quatre'],
49
+ [3n, 'trois'],
50
+ [2n, 'deux'],
51
+ [1n, 'un'],
52
+ [0n, 'zéro']
53
+ ]
54
+
55
+ constructor (options = {}) {
56
+ super()
57
+
58
+ this.setOptions({
59
+ withHyphenSeparator: false
60
+ }, options)
61
+
62
+ if (options.withHyphenSeparator) {
63
+ this.wordSeparator = '-'
64
+ }
65
+ }
66
+
67
+ /** Combines two word-sets with French pluralization and hyphenation rules. */
68
+ combineWordSets (preceding, following) {
69
+ let precedingWord = Object.keys(preceding)[0]
70
+ let followingWord = Object.keys(following)[0]
71
+ const precedingValue = Object.values(preceding)[0]
72
+ const followingValue = Object.values(following)[0]
73
+
74
+ if (precedingValue === 1n) {
75
+ if (followingValue < 1_000_000n) {
76
+ return following
77
+ }
78
+ } else {
79
+ if (
80
+ ((precedingValue - 80n) % 100n === 0n || (precedingValue % 100n === 0n && precedingValue < 1000n)) &&
81
+ followingValue < 1_000_000n &&
82
+ precedingWord.at(-1) === 's'
83
+ ) {
84
+ precedingWord = precedingWord.slice(0, -1)
85
+ }
86
+
87
+ if (
88
+ precedingValue < 1000n && followingValue !== 1000n &&
89
+ followingWord.at(-1) !== 's' &&
90
+ followingValue % 100n === 0n
91
+ ) {
92
+ followingWord += 's'
93
+ }
94
+ }
95
+
96
+ if (followingValue < precedingValue && precedingValue < 100n) {
97
+ if (followingValue % 10n === 1n && precedingValue !== 80n) {
98
+ return { [`${precedingWord}${this.wordSeparator}et${this.wordSeparator}${followingWord}`]: precedingValue + followingValue }
99
+ }
100
+ return { [`${precedingWord}-${followingWord}`]: precedingValue + followingValue }
101
+ }
102
+
103
+ if (followingValue > precedingValue) return { [`${precedingWord}${this.wordSeparator}${followingWord}`]: precedingValue * followingValue }
104
+ return { [`${precedingWord}${this.wordSeparator}${followingWord}`]: precedingValue + followingValue }
105
+ }
106
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Gujarati language converter.
3
+ *
4
+ * Supports:
5
+ * - Indian numbering system (હજાર, લાખ, કરોડ)
6
+ * - Gujarati script
7
+ * - Complete word forms for 0-99
8
+ */
9
+ export class Gujarati extends SouthAsianLanguage {
10
+ }
11
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js';
@@ -0,0 +1,132 @@
1
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js'
2
+
3
+ /**
4
+ * Gujarati language converter.
5
+ *
6
+ * Supports:
7
+ * - Indian numbering system (હજાર, લાખ, કરોડ)
8
+ * - Gujarati script
9
+ * - Complete word forms for 0-99
10
+ */
11
+ export class Gujarati extends SouthAsianLanguage {
12
+ negativeWord = 'ઋણ'
13
+ decimalSeparatorWord = 'દશાંશ'
14
+ zeroWord = 'શૂન્ય'
15
+ hundredWord = 'સો'
16
+ usePerDigitDecimals = true
17
+
18
+ belowHundredWords = [
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
+ 'બાણું',
112
+ 'ત્રાણું',
113
+ 'ચોરાણું',
114
+ 'પંચાણું',
115
+ 'છન્નું',
116
+ 'સત્તાણું',
117
+ 'અઠ્ઠાણું',
118
+ 'નવ્વાણું'
119
+ ]
120
+
121
+ scaleWords = [
122
+ '',
123
+ 'હજાર',
124
+ 'લાખ',
125
+ 'કરોડ',
126
+ 'અબજ',
127
+ 'ખરબ',
128
+ 'નીલ',
129
+ 'પદ્મ',
130
+ 'શંખ'
131
+ ]
132
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Biblical Hebrew language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Gender agreement (masculine/feminine)
7
+ * - Optional "ו" (and) conjunction control
8
+ */
9
+ export class BiblicalHebrew extends SlavicLanguage {
10
+ constructor(options?: {});
11
+ onesWords: {
12
+ 1: string;
13
+ 2: string;
14
+ 3: string;
15
+ 4: string;
16
+ 5: string;
17
+ 6: string;
18
+ 7: string;
19
+ 8: string;
20
+ 9: string;
21
+ };
22
+ teensWords: {
23
+ 0: string;
24
+ 1: string;
25
+ 2: string;
26
+ 3: string;
27
+ 4: string;
28
+ 5: string;
29
+ 6: string;
30
+ 7: string;
31
+ 8: string;
32
+ 9: string;
33
+ };
34
+ twentiesWords: {
35
+ 2: string;
36
+ 3: string;
37
+ 4: string;
38
+ 5: string;
39
+ 6: string;
40
+ 7: string;
41
+ 8: string;
42
+ 9: string;
43
+ };
44
+ hundredsWords: {
45
+ 1: string;
46
+ 2: string;
47
+ 3: string;
48
+ };
49
+ pluralForms: {
50
+ 1: string;
51
+ 2: string;
52
+ 3: string;
53
+ 4: string;
54
+ 5: string;
55
+ 6: string;
56
+ 7: string;
57
+ 8: string;
58
+ 9: string;
59
+ };
60
+ femininePluralForms: {
61
+ 1: string;
62
+ 2: string;
63
+ 3: string;
64
+ 4: string;
65
+ 5: string;
66
+ 6: string;
67
+ 7: string;
68
+ 8: string;
69
+ 9: string;
70
+ };
71
+ scale: {
72
+ 1: string;
73
+ 2: string;
74
+ 3: string;
75
+ 4: string;
76
+ 5: string;
77
+ 6: string;
78
+ };
79
+ scalePlural: {
80
+ 1: string;
81
+ 2: string;
82
+ 3: string;
83
+ 4: string;
84
+ 5: string;
85
+ 6: string;
86
+ };
87
+ onesFeminineWords: {
88
+ 1: string;
89
+ 2: string;
90
+ 3: string;
91
+ 4: string;
92
+ 5: string;
93
+ 6: string;
94
+ 7: string;
95
+ 8: string;
96
+ 9: string;
97
+ };
98
+ teensFeminineWords: {
99
+ 0: string;
100
+ 1: string;
101
+ 2: string;
102
+ 3: string;
103
+ 4: string;
104
+ 5: string;
105
+ 6: string;
106
+ 7: string;
107
+ 8: string;
108
+ 9: string;
109
+ };
110
+ /** Converts integer part with Biblical Hebrew three-form pluralization. */
111
+ integerToWords(integerPart: any): string;
112
+ }
113
+ import { SlavicLanguage } from '../classes/slavic-language.js';