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
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Converts a value to cardinal (written) form.
3
- * @param {number|string|bigint} value Number to be convert.
4
- * @param {object} [options] Options for class.
5
- * @returns {string} Value in cardinal (written) format.
6
- * @throws {Error} Value cannot be invalid.
2
+ * Latvian language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Latvian diacritical marks (ī, ā, ē, ū)
7
+ * - Compound number formation (divdesmit, trīsdesmit)
7
8
  */
8
- export default function floatToCardinal(value: number | string | bigint, options?: object): string;
9
- export class N2WordsLT extends N2WordsRU {
10
- ones: {
9
+ export class Latvian extends SlavicLanguage {
10
+ onesWords: {
11
11
  1: string;
12
12
  2: string;
13
13
  3: string;
@@ -18,7 +18,7 @@ export class N2WordsLT extends N2WordsRU {
18
18
  8: string;
19
19
  9: string;
20
20
  };
21
- onesFeminine: {
21
+ onesFeminineWords: {
22
22
  1: string;
23
23
  2: string;
24
24
  3: string;
@@ -29,7 +29,7 @@ export class N2WordsLT extends N2WordsRU {
29
29
  8: string;
30
30
  9: string;
31
31
  };
32
- tens: {
32
+ teensWords: {
33
33
  0: string;
34
34
  1: string;
35
35
  2: string;
@@ -41,7 +41,7 @@ export class N2WordsLT extends N2WordsRU {
41
41
  8: string;
42
42
  9: string;
43
43
  };
44
- twenties: {
44
+ twentiesWords: {
45
45
  2: string;
46
46
  3: string;
47
47
  4: string;
@@ -51,8 +51,8 @@ export class N2WordsLT extends N2WordsRU {
51
51
  8: string;
52
52
  9: string;
53
53
  };
54
- hundreds: string[];
55
- thousands: {
54
+ hundredsWords: string[];
55
+ pluralForms: {
56
56
  1: string[];
57
57
  2: string[];
58
58
  3: string[];
@@ -64,5 +64,7 @@ export class N2WordsLT extends N2WordsRU {
64
64
  9: string[];
65
65
  10: string[];
66
66
  };
67
+ pluralize(n: any, forms: any): any;
68
+ integerToWords(integerPart: any): string;
67
69
  }
68
- import { N2WordsRU } from './ru.js';
70
+ import { SlavicLanguage } from '../classes/slavic-language.js';
@@ -0,0 +1,130 @@
1
+ import { SlavicLanguage } from '../classes/slavic-language.js'
2
+
3
+ /**
4
+ * Latvian language converter.
5
+ *
6
+ * Supports:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Latvian diacritical marks (ī, ā, ē, ū)
9
+ * - Compound number formation (divdesmit, trīsdesmit)
10
+ */
11
+ export class Latvian extends SlavicLanguage {
12
+ negativeWord = 'mīnus'
13
+ decimalSeparatorWord = 'komats'
14
+ zeroWord = 'nulle'
15
+
16
+ onesWords = {
17
+ 1: 'viens',
18
+ 2: 'divi',
19
+ 3: 'trīs',
20
+ 4: 'četri',
21
+ 5: 'pieci',
22
+ 6: 'seši',
23
+ 7: 'septiņi',
24
+ 8: 'astoņi',
25
+ 9: 'deviņi'
26
+ }
27
+
28
+ onesFeminineWords = {
29
+ 1: 'viena',
30
+ 2: 'divas',
31
+ 3: 'trīs',
32
+ 4: 'četras',
33
+ 5: 'piecas',
34
+ 6: 'sešas',
35
+ 7: 'septiņas',
36
+ 8: 'astoņas',
37
+ 9: 'deviņas'
38
+ }
39
+
40
+ teensWords = {
41
+ 0: 'desmit',
42
+ 1: 'vienpadsmit',
43
+ 2: 'divpadsmit',
44
+ 3: 'trīspadsmit',
45
+ 4: 'četrpadsmit',
46
+ 5: 'piecpadsmit',
47
+ 6: 'sešpadsmit',
48
+ 7: 'septiņpadsmit',
49
+ 8: 'astoņpadsmit',
50
+ 9: 'deviņpadsmit'
51
+ }
52
+
53
+ twentiesWords = {
54
+ 2: 'divdesmit',
55
+ 3: 'trīsdesmit',
56
+ 4: 'četrdesmit',
57
+ 5: 'piecdesmit',
58
+ 6: 'sešdesmit',
59
+ 7: 'septiņdesmit',
60
+ 8: 'astoņdesmit',
61
+ 9: 'deviņdesmit'
62
+ }
63
+
64
+ hundredsWords = ['simts', 'simti', 'simtu']
65
+
66
+ pluralForms = {
67
+ 1: ['tūkstotis', 'tūkstoši', 'tūkstošu'],
68
+ 2: ['miljons', 'miljoni', 'miljonu'],
69
+ 3: ['miljards', 'miljardi', 'miljardu'],
70
+ 4: ['triljons', 'triljoni', 'triljonu'],
71
+ 5: ['kvadriljons', 'kvadriljoni', 'kvadriljonu'],
72
+ 6: ['kvintiljons', 'kvintiljoni', 'kvintiljonu'],
73
+ 7: ['sikstiljons', 'sikstiljoni', 'sikstiljonu'],
74
+ 8: ['septiljons', 'septiljoni', 'septiljonu'],
75
+ 9: ['oktiljons', 'oktiljoni', 'oktiljonu'],
76
+ 10: ['nontiljons', 'nontiljoni', 'nontiljonu']
77
+ }
78
+
79
+ pluralize (n, forms) {
80
+ if (n === 0n) {
81
+ return forms[2]
82
+ }
83
+
84
+ const lastDigit = n % 10n
85
+ const lastTwoDigits = n % 100n
86
+
87
+ if (lastDigit === 1n && lastTwoDigits !== 11n) {
88
+ return forms[0]
89
+ }
90
+
91
+ return forms[1]
92
+ }
93
+
94
+ integerToWords (integerPart) {
95
+ if (integerPart === 0n) {
96
+ return this.zeroWord
97
+ }
98
+ const words = []
99
+ const segments = this.splitToSegments(integerPart.toString(), 3)
100
+ let index = segments.length
101
+ for (const x of segments) {
102
+ index = index - 1
103
+ if (x === 0n) {
104
+ continue
105
+ }
106
+ const [n1, n2, n3] = this.extractDigits(x)
107
+ if (n3 > 0n) {
108
+ if (n3 === 1n && n2 === 0n && n1 > 0n) {
109
+ words.push(this.hundredsWords[2])
110
+ } else if (n3 > 1n) {
111
+ words.push(this.onesWords[n3], this.hundredsWords[1])
112
+ } else {
113
+ words.push(this.hundredsWords[0])
114
+ }
115
+ }
116
+ if (n2 > 1n) {
117
+ words.push(this.twentiesWords[n2])
118
+ }
119
+ if (n2 === 1n) {
120
+ words.push(this.teensWords[n1])
121
+ } else if (n1 > 0n && !(index > 0 && x === 1n)) {
122
+ words.push(this.onesWords[n1])
123
+ }
124
+ if (index > 0) {
125
+ words.push(this.pluralize(x, this.pluralForms[index]))
126
+ }
127
+ }
128
+ return words.join(' ')
129
+ }
130
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Marathi language converter.
3
+ *
4
+ * Supports:
5
+ * - Indian numbering system (हजार, लाख, कोटी)
6
+ * - Devanagari script
7
+ * - Complete word forms for 0-99
8
+ */
9
+ export class Marathi 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
+ * Marathi language converter.
5
+ *
6
+ * Supports:
7
+ * - Indian numbering system (हजार, लाख, कोटी)
8
+ * - Devanagari script
9
+ * - Complete word forms for 0-99
10
+ */
11
+ export class Marathi 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,31 @@
1
+ /**
2
+ * Malay (Bahasa Melayu) language converter.
3
+ *
4
+ * Supports:
5
+ * - "Se-" prefix for singular units (seratus, seribu, sejuta)
6
+ * - Regular patterns (puluh for tens, ratus for hundreds)
7
+ * - Space-separated number components
8
+ */
9
+ export class Malay extends AbstractLanguage {
10
+ /**
11
+ * Word forms for digits 0-9.
12
+ * @type {Object.<number, string[]>}
13
+ */
14
+ digitWords: {
15
+ [x: number]: string[];
16
+ };
17
+ /**
18
+ * Scale magnitude words keyed by exponent (10^n).
19
+ * @type {Object.<number, string>}
20
+ */
21
+ scaleWords: {
22
+ [x: number]: string;
23
+ };
24
+ splitBy3(number: any): any[][];
25
+ spell(blocks: any): any[];
26
+ getHundreds(number: any): string[];
27
+ getTens(number: any): string[];
28
+ join(wordBlocks: any): string;
29
+ integerToWords(integerPart: any): string;
30
+ }
31
+ import { AbstractLanguage } from '../classes/abstract-language.js';
@@ -0,0 +1,150 @@
1
+ import { AbstractLanguage } from '../classes/abstract-language.js'
2
+
3
+ /**
4
+ * Malay (Bahasa Melayu) language converter.
5
+ *
6
+ * Supports:
7
+ * - "Se-" prefix for singular units (seratus, seribu, sejuta)
8
+ * - Regular patterns (puluh for tens, ratus for hundreds)
9
+ * - Space-separated number components
10
+ */
11
+ export class Malay extends AbstractLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'perpuluhan'
14
+ zeroWord = 'sifar'
15
+
16
+ /**
17
+ * Word forms for digits 0-9.
18
+ * @type {Object.<number, string[]>}
19
+ */
20
+ digitWords = {
21
+ 0: [],
22
+ 1: ['satu'],
23
+ 2: ['dua'],
24
+ 3: ['tiga'],
25
+ 4: ['empat'],
26
+ 5: ['lima'],
27
+ 6: ['enam'],
28
+ 7: ['tujuh'],
29
+ 8: ['lapan'],
30
+ 9: ['sembilan']
31
+ }
32
+
33
+ /**
34
+ * Scale magnitude words keyed by exponent (10^n).
35
+ * @type {Object.<number, string>}
36
+ */
37
+ scaleWords = {
38
+ 3: 'ribu',
39
+ 6: 'juta',
40
+ 9: 'bilion',
41
+ 12: 'trilion'
42
+ }
43
+
44
+ splitBy3 (number) {
45
+ const blocks = []
46
+ const stringNumber = number.toString()
47
+ const length = stringNumber.length
48
+ let firstBlock
49
+
50
+ if (length < 3) {
51
+ blocks.push([stringNumber])
52
+ } else {
53
+ const firstBlockLength = length % 3
54
+
55
+ if (firstBlockLength > 0) {
56
+ firstBlock = [stringNumber.slice(0, firstBlockLength)]
57
+ blocks.push(firstBlock)
58
+ }
59
+
60
+ for (let index = firstBlockLength; index < length; index += 3) {
61
+ const nextBlock = [stringNumber.slice(index, index + 3)]
62
+ blocks.push(nextBlock)
63
+ }
64
+ }
65
+ return blocks
66
+ }
67
+
68
+ spell (blocks) {
69
+ let wordBlocks = []
70
+ let spelling
71
+ const firstBlock = blocks[0]
72
+ if (firstBlock[0].length === 1) {
73
+ spelling = firstBlock[0] === '0' ? ['sifar'] : this.digitWords[Math.trunc(firstBlock[0])]
74
+ } else if (firstBlock[0].length === 2) {
75
+ spelling = this.getTens(firstBlock[0])
76
+ } else {
77
+ spelling = [...this.getHundreds(firstBlock[0][0]), ...this.getTens(firstBlock[0].slice(1, 3))]
78
+ }
79
+ wordBlocks = [...wordBlocks, [firstBlock[0], spelling]]
80
+ for (let index = 1; index < blocks.length; index++) {
81
+ let block = blocks[index]
82
+ spelling = [...this.getHundreds(block[0][0]), ...this.getTens(block[0].slice(1, 3))]
83
+ block = [...block, spelling]
84
+ wordBlocks = [...wordBlocks, block]
85
+ }
86
+ return wordBlocks
87
+ }
88
+
89
+ getHundreds (number) { // 'ratus'
90
+ if (number === '1') {
91
+ return ['seratus']
92
+ } else if (number === '0') {
93
+ return []
94
+ } else {
95
+ return [...this.digitWords[Math.trunc(number)], 'ratus']
96
+ }
97
+ }
98
+
99
+ getTens (number) { // 'puluh' and 'belas'
100
+ if (number[0] === '1') {
101
+ if (number[1] === '0') {
102
+ return ['sepuluh']
103
+ } else if (number[1] === '1') {
104
+ return ['sebelas']
105
+ }
106
+ return [...this.digitWords[Math.trunc(number[1])], 'belas']
107
+ }
108
+
109
+ if (number[0] === '0') {
110
+ return this.digitWords[Math.trunc(number[1])]
111
+ }
112
+
113
+ return [...this.digitWords[Math.trunc(number[0])], 'puluh', ...this.digitWords[Math.trunc(number[1])]]
114
+ }
115
+
116
+ join (wordBlocks) {
117
+ const wordList = []
118
+ const length = wordBlocks.length - 1
119
+
120
+ for (let index = 0; index <= length; index++) {
121
+ const words = wordBlocks[index][1]
122
+ const isLast = index === length
123
+ const scaleWord = isLast ? null : this.scaleWords[(length - index) * 3]
124
+
125
+ if (!isLast && words.length === 1 && words[0] === 'satu') {
126
+ // Use se- prefix for singular scale units: seribu, sejuta, sebilion, setrilion
127
+ wordList.push('se' + scaleWord)
128
+ continue
129
+ }
130
+
131
+ // Add current block words
132
+ for (const w of words) wordList.push(w)
133
+
134
+ // Append scale word if applicable and current block contributed words
135
+ if (!isLast && words.length > 0) {
136
+ wordList.push(scaleWord)
137
+ }
138
+ }
139
+
140
+ return wordList.join(' ')
141
+ }
142
+
143
+ integerToWords (integerPart) {
144
+ return this.join(
145
+ this.spell(
146
+ this.splitBy3(integerPart)
147
+ )
148
+ ).trim()
149
+ }
150
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Norwegian Bokmål language converter.
3
+ *
4
+ * Supports:
5
+ * - Hyphenation for compound numbers (tjue-en)
6
+ * - "og" (and) for hundreds combinations
7
+ * - Implicit '1' omission before tens and magnitudes
8
+ */
9
+ export class NorwegianBokmal extends GreedyScaleLanguage {
10
+ scaleWords: (string | bigint)[][];
11
+ }
12
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -0,0 +1,100 @@
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
+
3
+ /**
4
+ * Norwegian Bokmål language converter.
5
+ *
6
+ * Supports:
7
+ * - Hyphenation for compound numbers (tjue-en)
8
+ * - "og" (and) for hundreds combinations
9
+ * - Implicit '1' omission before tens and magnitudes
10
+ */
11
+ export class NorwegianBokmal extends GreedyScaleLanguage {
12
+ negativeWord = 'minus'
13
+ decimalSeparatorWord = 'komma'
14
+ zeroWord = 'null'
15
+
16
+ scaleWords = [
17
+ [1_000_000_000_000_000_000_000_000_000n, 'oktillion'],
18
+ [1_000_000_000_000_000_000_000_000n, 'septillion'],
19
+ [1_000_000_000_000_000_000_000n, 'sekstillion'],
20
+ [1_000_000_000_000_000_000n, 'kvintillion'],
21
+ [1_000_000_000_000_000n, 'kvadrillion'],
22
+ [1_000_000_000_000n, 'billion'],
23
+ [1_000_000_000n, 'milliard'],
24
+ [1_000_000n, 'million'],
25
+ [1000n, 'tusen'],
26
+ [100n, 'hundre'],
27
+ [90n, 'nitti'],
28
+ [80n, 'åtti'],
29
+ [70n, 'sytti'],
30
+ [60n, 'seksti'],
31
+ [50n, 'femti'],
32
+ [40n, 'førti'],
33
+ [30n, 'tretti'],
34
+ [20n, 'tjue'],
35
+ [19n, 'nitten'],
36
+ [18n, 'atten'],
37
+ [17n, 'sytten'],
38
+ [16n, 'seksten'],
39
+ [15n, 'femten'],
40
+ [14n, 'fjorten'],
41
+ [13n, 'tretten'],
42
+ [12n, 'tolv'],
43
+ [11n, 'elleve'],
44
+ [10n, 'ti'],
45
+ [9n, 'ni'],
46
+ [8n, 'åtte'],
47
+ [7n, 'syv'],
48
+ [6n, 'seks'],
49
+ [5n, 'fem'],
50
+ [4n, 'fire'],
51
+ [3n, 'tre'],
52
+ [2n, 'to'],
53
+ [1n, 'en'],
54
+ [0n, 'null']
55
+ ]
56
+
57
+ /**
58
+ * Merges two adjacent word-sets according to Norwegian grammar rules.
59
+ *
60
+ * Norwegian-specific rules:
61
+ * - Implicit "en": `combineWordSets({ 'en': 1n }, { 'hundre': 100n })` → `{ 'hundre': 100n }`
62
+ * - Hyphenation for compound tens: `combineWordSets({ 'tjue': 20n }, { 'en': 1n })` → `{ 'tjue-en': 21n }`
63
+ * - "og" (and) after hundreds: `combineWordSets({ 'hundre': 100n }, { 'en': 1n })` → `{ 'hundre og en': 101n }`
64
+ * - Space-separated for large numbers (thousands+)
65
+ * - Comma separator for non-magnitude additions (e.g., \"tusen, en\")
66
+ *
67
+ * @param {Object} preceding The preceding word-set as `{ word: BigInt }`.
68
+ * @param {Object} following The following word-set as `{ word: BigInt }`.
69
+ * @returns {Object} Merged pair with combined word and resulting numeric value.
70
+ *
71
+ * @example
72
+ * combineWordSets({ 'en': 1n }, { 'hundre': 100n }); // { 'hundre': 100n }
73
+ * combineWordSets({ 'tjue': 20n }, { 'tre': 3n }); // { 'tjue-tre': 23n }
74
+ */
75
+ // Norwegian merge rules mirror the former Scandinavian base logic
76
+ combineWordSets (preceding, following) {
77
+ const precedingWord = Object.keys(preceding)[0]
78
+ const followingWord = Object.keys(following)[0]
79
+ const precedingValue = Object.values(preceding)[0]
80
+ const followingValue = Object.values(following)[0]
81
+
82
+ if (precedingValue === 1n && followingValue < 100n) {
83
+ return following
84
+ }
85
+
86
+ if (precedingValue < 100n && precedingValue > followingValue) {
87
+ return { [`${precedingWord}-${followingWord}`]: precedingValue + followingValue }
88
+ }
89
+
90
+ if (precedingValue >= 100n && followingValue < 100n) {
91
+ return { [`${precedingWord} og ${followingWord}`]: precedingValue + followingValue }
92
+ }
93
+
94
+ if (followingValue > precedingValue) {
95
+ return { [`${precedingWord} ${followingWord}`]: precedingValue * followingValue }
96
+ }
97
+
98
+ return { [`${precedingWord}, ${followingWord}`]: precedingValue + followingValue }
99
+ }
100
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Dutch language converter.
3
+ *
4
+ * Supports:
5
+ * - Optional "en" (and) separator for tens
6
+ * - Optional comma before hundreds
7
+ * - Compound word formation without hyphenation
8
+ */
9
+ export class Dutch extends GreedyScaleLanguage {
10
+ constructor(options?: {});
11
+ scaleWords: (string | bigint)[][];
12
+ /** Combines two word-sets according to Dutch grammar rules. */
13
+ combineWordSets(preceding: any, following: any): any;
14
+ integerToWords(integerPart: any): string;
15
+ }
16
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';