n2words 2.0.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 (327) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +86 -188
  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 -0
  8. package/dist/languages/ar.js.map +1 -0
  9. package/dist/languages/az.js +3 -0
  10. package/dist/languages/az.js.map +1 -0
  11. package/dist/languages/bn.js +3 -0
  12. package/dist/languages/bn.js.map +1 -0
  13. package/dist/languages/cs.js +3 -0
  14. package/dist/languages/cs.js.map +1 -0
  15. package/dist/languages/da.js +3 -0
  16. package/dist/languages/da.js.map +1 -0
  17. package/dist/languages/de.js +3 -0
  18. package/dist/languages/de.js.map +1 -0
  19. package/dist/languages/el.js +3 -0
  20. package/dist/languages/el.js.map +1 -0
  21. package/dist/languages/en.js +3 -0
  22. package/dist/languages/en.js.map +1 -0
  23. package/dist/languages/es.js +3 -0
  24. package/dist/languages/es.js.map +1 -0
  25. package/dist/languages/fa.js +3 -0
  26. package/dist/languages/fa.js.map +1 -0
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -0
  30. package/dist/languages/fil.js.map +1 -0
  31. package/dist/languages/fr-BE.js +3 -0
  32. package/dist/languages/fr-BE.js.map +1 -0
  33. package/dist/languages/fr.js +3 -0
  34. package/dist/languages/fr.js.map +1 -0
  35. package/dist/languages/gu.js +3 -0
  36. package/dist/languages/gu.js.map +1 -0
  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 -0
  42. package/dist/languages/he.js.map +1 -0
  43. package/dist/languages/hi.js +3 -0
  44. package/dist/languages/hi.js.map +1 -0
  45. package/dist/languages/hr.js +3 -0
  46. package/dist/languages/hr.js.map +1 -0
  47. package/dist/languages/hu.js +3 -0
  48. package/dist/languages/hu.js.map +1 -0
  49. package/dist/languages/id.js +3 -0
  50. package/dist/languages/id.js.map +1 -0
  51. package/dist/languages/it.js +3 -0
  52. package/dist/languages/it.js.map +1 -0
  53. package/dist/languages/ja.js +3 -0
  54. package/dist/languages/ja.js.map +1 -0
  55. package/dist/languages/kn.js +3 -0
  56. package/dist/languages/kn.js.map +1 -0
  57. package/dist/languages/ko.js +3 -0
  58. package/dist/languages/ko.js.map +1 -0
  59. package/dist/languages/lt.js +3 -0
  60. package/dist/languages/lt.js.map +1 -0
  61. package/dist/languages/lv.js +3 -0
  62. package/dist/languages/lv.js.map +1 -0
  63. package/dist/languages/mr.js +3 -0
  64. package/dist/languages/mr.js.map +1 -0
  65. package/dist/languages/ms.js +3 -0
  66. package/dist/languages/ms.js.map +1 -0
  67. package/dist/languages/nb.js +3 -0
  68. package/dist/languages/nb.js.map +1 -0
  69. package/dist/languages/nl.js +3 -0
  70. package/dist/languages/nl.js.map +1 -0
  71. package/dist/languages/pa.js +3 -0
  72. package/dist/languages/pa.js.map +1 -0
  73. package/dist/languages/pl.js +3 -0
  74. package/dist/languages/pl.js.map +1 -0
  75. package/dist/languages/pt.js +3 -0
  76. package/dist/languages/pt.js.map +1 -0
  77. package/dist/languages/ro.js +3 -0
  78. package/dist/languages/ro.js.map +1 -0
  79. package/dist/languages/ru.js +3 -0
  80. package/dist/languages/ru.js.map +1 -0
  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 -0
  84. package/dist/languages/sr-Latn.js.map +1 -0
  85. package/dist/languages/sv.js +3 -0
  86. package/dist/languages/sv.js.map +1 -0
  87. package/dist/languages/sw.js +3 -0
  88. package/dist/languages/sw.js.map +1 -0
  89. package/dist/languages/ta.js +3 -0
  90. package/dist/languages/ta.js.map +1 -0
  91. package/dist/languages/te.js +3 -0
  92. package/dist/languages/te.js.map +1 -0
  93. package/dist/languages/th.js +3 -0
  94. package/dist/languages/th.js.map +1 -0
  95. package/dist/languages/tr.js +3 -0
  96. package/dist/languages/tr.js.map +1 -0
  97. package/dist/languages/uk.js +3 -0
  98. package/dist/languages/uk.js.map +1 -0
  99. package/dist/languages/ur.js +3 -0
  100. package/dist/languages/ur.js.map +1 -0
  101. package/dist/languages/vi.js +3 -0
  102. package/dist/languages/vi.js.map +1 -0
  103. package/dist/languages/zh-Hans.js +3 -0
  104. package/dist/languages/zh-Hans.js.map +1 -0
  105. package/dist/languages/zh-Hant.js +3 -0
  106. package/dist/languages/zh-Hant.js.map +1 -0
  107. package/dist/n2words.js +2 -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 +14 -27
  114. package/lib/languages/ar.js +175 -129
  115. package/lib/languages/az.d.ts +4 -9
  116. package/lib/languages/az.js +171 -37
  117. package/lib/languages/bn.d.ts +4 -8
  118. package/lib/languages/bn.js +138 -124
  119. package/lib/languages/cs.d.ts +15 -85
  120. package/lib/languages/cs.js +310 -114
  121. package/lib/languages/da.d.ts +11 -12
  122. package/lib/languages/da.js +276 -101
  123. package/lib/languages/de.d.ts +14 -11
  124. package/lib/languages/de.js +317 -86
  125. package/lib/languages/el.d.ts +11 -11
  126. package/lib/languages/el.js +231 -78
  127. package/lib/languages/en.d.ts +14 -13
  128. package/lib/languages/en.js +242 -72
  129. package/lib/languages/es.d.ts +18 -12
  130. package/lib/languages/es.js +317 -103
  131. package/lib/languages/fa.d.ts +4 -44
  132. package/lib/languages/fa.js +112 -122
  133. package/lib/languages/fi.d.ts +14 -0
  134. package/lib/languages/fi.js +245 -0
  135. package/lib/languages/fil.d.ts +4 -13
  136. package/lib/languages/fil.js +207 -106
  137. package/lib/languages/fr-BE.d.ts +8 -8
  138. package/lib/languages/fr-BE.js +294 -19
  139. package/lib/languages/fr.d.ts +18 -12
  140. package/lib/languages/fr.js +352 -89
  141. package/lib/languages/gu.d.ts +4 -8
  142. package/lib/languages/gu.js +130 -125
  143. package/lib/languages/ha.d.ts +7 -0
  144. package/lib/languages/ha.js +230 -0
  145. package/lib/languages/hbo.d.ts +10 -110
  146. package/lib/languages/hbo.js +263 -214
  147. package/lib/languages/he.d.ts +10 -77
  148. package/lib/languages/he.js +242 -172
  149. package/lib/languages/hi.d.ts +4 -8
  150. package/lib/languages/hi.js +138 -124
  151. package/lib/languages/hr.d.ts +8 -77
  152. package/lib/languages/hr.js +194 -89
  153. package/lib/languages/hu.d.ts +4 -19
  154. package/lib/languages/hu.js +198 -119
  155. package/lib/languages/id.d.ts +4 -34
  156. package/lib/languages/id.js +171 -129
  157. package/lib/languages/it.d.ts +16 -34
  158. package/lib/languages/it.js +339 -94
  159. package/lib/languages/ja.d.ts +14 -14
  160. package/lib/languages/ja.js +233 -111
  161. package/lib/languages/kn.d.ts +4 -8
  162. package/lib/languages/kn.js +130 -35
  163. package/lib/languages/ko.d.ts +11 -11
  164. package/lib/languages/ko.js +257 -49
  165. package/lib/languages/lt.d.ts +15 -67
  166. package/lib/languages/lt.js +296 -122
  167. package/lib/languages/lv.d.ts +15 -67
  168. package/lib/languages/lv.js +297 -106
  169. package/lib/languages/mr.d.ts +4 -8
  170. package/lib/languages/mr.js +130 -125
  171. package/lib/languages/ms.d.ts +4 -28
  172. package/lib/languages/ms.js +171 -116
  173. package/lib/languages/nb.d.ts +11 -9
  174. package/lib/languages/nb.js +282 -87
  175. package/lib/languages/nl.d.ts +23 -13
  176. package/lib/languages/nl.js +317 -133
  177. package/lib/languages/pa.d.ts +4 -8
  178. package/lib/languages/pa.js +156 -124
  179. package/lib/languages/pl.d.ts +19 -77
  180. package/lib/languages/pl.js +307 -87
  181. package/lib/languages/pt.d.ts +14 -26
  182. package/lib/languages/pt.js +286 -92
  183. package/lib/languages/ro.d.ts +15 -155
  184. package/lib/languages/ro.js +219 -235
  185. package/lib/languages/ru.d.ts +8 -82
  186. package/lib/languages/ru.js +222 -78
  187. package/lib/languages/sr-Cyrl.d.ts +8 -77
  188. package/lib/languages/sr-Cyrl.js +191 -89
  189. package/lib/languages/sr-Latn.d.ts +8 -77
  190. package/lib/languages/sr-Latn.js +191 -89
  191. package/lib/languages/sv.d.ts +11 -11
  192. package/lib/languages/sv.js +288 -74
  193. package/lib/languages/sw.d.ts +4 -36
  194. package/lib/languages/sw.js +133 -106
  195. package/lib/languages/ta.d.ts +4 -17
  196. package/lib/languages/ta.js +129 -201
  197. package/lib/languages/te.d.ts +4 -19
  198. package/lib/languages/te.js +141 -196
  199. package/lib/languages/th.d.ts +4 -14
  200. package/lib/languages/th.js +135 -91
  201. package/lib/languages/tr.d.ts +15 -9
  202. package/lib/languages/tr.js +256 -49
  203. package/lib/languages/uk.d.ts +8 -82
  204. package/lib/languages/uk.js +200 -78
  205. package/lib/languages/ur.d.ts +4 -8
  206. package/lib/languages/ur.js +156 -124
  207. package/lib/languages/vi.d.ts +14 -69
  208. package/lib/languages/vi.js +294 -125
  209. package/lib/languages/zh-Hans.d.ts +8 -18
  210. package/lib/languages/zh-Hans.js +163 -92
  211. package/lib/languages/zh-Hant.d.ts +8 -18
  212. package/lib/languages/zh-Hant.js +181 -90
  213. package/lib/n2words.d.ts +53 -209
  214. package/lib/n2words.js +111 -530
  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 +26 -14
  222. package/dist/ArabicConverter.js +0 -3
  223. package/dist/ArabicConverter.js.map +0 -1
  224. package/dist/AzerbaijaniConverter.js +0 -3
  225. package/dist/AzerbaijaniConverter.js.map +0 -1
  226. package/dist/BanglaConverter.js +0 -3
  227. package/dist/BanglaConverter.js.map +0 -1
  228. package/dist/BiblicalHebrewConverter.js +0 -3
  229. package/dist/BiblicalHebrewConverter.js.map +0 -1
  230. package/dist/CroatianConverter.js +0 -3
  231. package/dist/CroatianConverter.js.map +0 -1
  232. package/dist/CzechConverter.js +0 -3
  233. package/dist/CzechConverter.js.map +0 -1
  234. package/dist/DanishConverter.js +0 -3
  235. package/dist/DanishConverter.js.map +0 -1
  236. package/dist/DutchConverter.js +0 -3
  237. package/dist/DutchConverter.js.map +0 -1
  238. package/dist/EnglishConverter.js +0 -3
  239. package/dist/EnglishConverter.js.map +0 -1
  240. package/dist/FilipinoConverter.js +0 -3
  241. package/dist/FilipinoConverter.js.map +0 -1
  242. package/dist/FrenchBelgiumConverter.js +0 -3
  243. package/dist/FrenchBelgiumConverter.js.map +0 -1
  244. package/dist/FrenchConverter.js +0 -3
  245. package/dist/FrenchConverter.js.map +0 -1
  246. package/dist/GermanConverter.js +0 -3
  247. package/dist/GermanConverter.js.map +0 -1
  248. package/dist/GreekConverter.js +0 -3
  249. package/dist/GreekConverter.js.map +0 -1
  250. package/dist/GujaratiConverter.js +0 -3
  251. package/dist/GujaratiConverter.js.map +0 -1
  252. package/dist/HebrewConverter.js +0 -3
  253. package/dist/HebrewConverter.js.map +0 -1
  254. package/dist/HindiConverter.js +0 -3
  255. package/dist/HindiConverter.js.map +0 -1
  256. package/dist/HungarianConverter.js +0 -3
  257. package/dist/HungarianConverter.js.map +0 -1
  258. package/dist/IndonesianConverter.js +0 -3
  259. package/dist/IndonesianConverter.js.map +0 -1
  260. package/dist/ItalianConverter.js +0 -3
  261. package/dist/ItalianConverter.js.map +0 -1
  262. package/dist/JapaneseConverter.js +0 -3
  263. package/dist/JapaneseConverter.js.map +0 -1
  264. package/dist/KannadaConverter.js +0 -3
  265. package/dist/KannadaConverter.js.map +0 -1
  266. package/dist/KoreanConverter.js +0 -3
  267. package/dist/KoreanConverter.js.map +0 -1
  268. package/dist/LatvianConverter.js +0 -3
  269. package/dist/LatvianConverter.js.map +0 -1
  270. package/dist/LithuanianConverter.js +0 -3
  271. package/dist/LithuanianConverter.js.map +0 -1
  272. package/dist/MalayConverter.js +0 -3
  273. package/dist/MalayConverter.js.map +0 -1
  274. package/dist/MarathiConverter.js +0 -3
  275. package/dist/MarathiConverter.js.map +0 -1
  276. package/dist/NorwegianBokmalConverter.js +0 -3
  277. package/dist/NorwegianBokmalConverter.js.map +0 -1
  278. package/dist/PersianConverter.js +0 -3
  279. package/dist/PersianConverter.js.map +0 -1
  280. package/dist/PolishConverter.js +0 -3
  281. package/dist/PolishConverter.js.map +0 -1
  282. package/dist/PortugueseConverter.js +0 -3
  283. package/dist/PortugueseConverter.js.map +0 -1
  284. package/dist/PunjabiConverter.js +0 -3
  285. package/dist/PunjabiConverter.js.map +0 -1
  286. package/dist/RomanianConverter.js +0 -3
  287. package/dist/RomanianConverter.js.map +0 -1
  288. package/dist/RussianConverter.js +0 -3
  289. package/dist/RussianConverter.js.map +0 -1
  290. package/dist/SerbianCyrillicConverter.js +0 -3
  291. package/dist/SerbianCyrillicConverter.js.map +0 -1
  292. package/dist/SerbianLatinConverter.js +0 -3
  293. package/dist/SerbianLatinConverter.js.map +0 -1
  294. package/dist/SimplifiedChineseConverter.js +0 -3
  295. package/dist/SimplifiedChineseConverter.js.map +0 -1
  296. package/dist/SpanishConverter.js +0 -3
  297. package/dist/SpanishConverter.js.map +0 -1
  298. package/dist/SwahiliConverter.js +0 -3
  299. package/dist/SwahiliConverter.js.map +0 -1
  300. package/dist/SwedishConverter.js +0 -3
  301. package/dist/SwedishConverter.js.map +0 -1
  302. package/dist/TamilConverter.js +0 -3
  303. package/dist/TamilConverter.js.map +0 -1
  304. package/dist/TeluguConverter.js +0 -3
  305. package/dist/TeluguConverter.js.map +0 -1
  306. package/dist/ThaiConverter.js +0 -3
  307. package/dist/ThaiConverter.js.map +0 -1
  308. package/dist/TraditionalChineseConverter.js +0 -3
  309. package/dist/TraditionalChineseConverter.js.map +0 -1
  310. package/dist/TurkishConverter.js +0 -3
  311. package/dist/TurkishConverter.js.map +0 -1
  312. package/dist/UkrainianConverter.js +0 -3
  313. package/dist/UkrainianConverter.js.map +0 -1
  314. package/dist/UrduConverter.js +0 -3
  315. package/dist/UrduConverter.js.map +0 -1
  316. package/dist/VietnameseConverter.js +0 -3
  317. package/dist/VietnameseConverter.js.map +0 -1
  318. package/lib/classes/abstract-language.d.ts +0 -178
  319. package/lib/classes/abstract-language.js +0 -268
  320. package/lib/classes/greedy-scale-language.d.ts +0 -109
  321. package/lib/classes/greedy-scale-language.js +0 -201
  322. package/lib/classes/slavic-language.d.ts +0 -148
  323. package/lib/classes/slavic-language.js +0 -281
  324. package/lib/classes/south-asian-language.d.ts +0 -70
  325. package/lib/classes/south-asian-language.js +0 -154
  326. package/lib/classes/turkic-language.d.ts +0 -26
  327. package/lib/classes/turkic-language.js +0 -59
@@ -1,22 +1,7 @@
1
1
  /**
2
- * Hungarian language converter.
2
+ * Converts a numeric value to Hungarian words.
3
3
  *
4
- * Supports:
5
- * - Agglutinative structure (no spaces between compound parts)
6
- * - Special handling for "egy" (one) omission
7
- * - Pre-composed twenties (huszonegy through huszonkilenc)
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Hungarian words
8
6
  */
9
- export class Hungarian extends GreedyScaleLanguage {
10
- scaleWords: (string | bigint)[][];
11
- /** Converts tens (30-99) with agglutinative composition. */
12
- tensToCardinal(number: any): string | undefined;
13
- /** Converts hundreds (100-999) with "száz" composition. */
14
- hundredsToCardinal(number: any): string;
15
- /** Converts thousands (1000-999999) with "ezer" composition. */
16
- thousandsToCardinal(number: any): string;
17
- /** Converts large numbers (millions and above) with scale words. */
18
- bigNumberToCardinal(number: any): string;
19
- /** Converts integer part using Hungarian agglutinative rules. */
20
- integerToWords(integerPart: any, zeroWord?: string): string;
21
- }
22
- import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
7
+ export function toWords(value: number | string | bigint): string;
@@ -1,137 +1,216 @@
1
- import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
-
3
1
  /**
4
- * Hungarian language converter.
2
+ * Hungarian language converter - Functional Implementation
3
+ *
4
+ * Self-contained converter with agglutinative word formation.
5
5
  *
6
- * Supports:
6
+ * Key features:
7
7
  * - Agglutinative structure (no spaces between compound parts)
8
8
  * - Special handling for "egy" (one) omission
9
9
  * - Pre-composed twenties (huszonegy through huszonkilenc)
10
+ * - "két" instead of "kettő" in compound forms
10
11
  */
11
- export class Hungarian extends GreedyScaleLanguage {
12
- negativeWord = 'mínusz'
13
- decimalSeparatorWord = 'egész'
14
- zeroWord = 'nulla'
15
-
16
- scaleWords = [
17
- [1_000_000_000_000_000_000_000_000_000n, 'quadrilliárd'],
18
- [1_000_000_000_000_000_000_000_000n, 'quadrillió'],
19
- [1_000_000_000_000_000_000_000n, 'trilliárd'],
20
- [1_000_000_000_000_000_000n, 'trillió'],
21
- [1_000_000_000_000_000n, 'billiárd'],
22
- [1_000_000_000_000n, 'billió'],
23
- [1_000_000_000n, 'milliárd'],
24
- [1_000_000n, 'millió'],
25
- [1000n, 'ezer'],
26
- [100n, 'száz'],
27
- [90n, 'kilencven'],
28
- [80n, 'nyolcvan'],
29
- [70n, 'hetven'],
30
- [60n, 'hatvan'],
31
- [50n, 'ötven'],
32
- [40n, 'negyven'],
33
- [30n, 'harminc'],
34
- [29n, 'huszonkilenc'],
35
- [28n, 'huszonnyolc'],
36
- [27n, 'huszonhét'],
37
- [26n, 'huszonhat'],
38
- [25n, 'huszonöt'],
39
- [24n, 'huszonnégy'],
40
- [23n, 'huszonhárom'],
41
- [22n, 'huszonkettő'],
42
- [21n, 'huszonegy'],
43
- [20n, 'húsz'],
44
- [19n, 'tizenkilenc'],
45
- [18n, 'tizennyolc'],
46
- [17n, 'tizenhét'],
47
- [16n, 'tizenhat'],
48
- [15n, 'tizenöt'],
49
- [14n, 'tizennégy'],
50
- [13n, 'tizenhárom'],
51
- [12n, 'tizenkettő'],
52
- [11n, 'tizenegy'],
53
- [10n, 'tíz'],
54
- [9n, 'kilenc'],
55
- [8n, 'nyolc'],
56
- [7n, 'hét'],
57
- [6n, 'hat'],
58
- [5n, 'öt'],
59
- [4n, 'négy'],
60
- [3n, 'három'],
61
- [2n, 'kettő'],
62
- [1n, 'egy'],
63
- [0n, 'nulla']
64
- ]
65
-
66
- /** Converts tens (30-99) with agglutinative composition. */
67
- tensToCardinal (number) {
68
- // Expecting `number` as bigint when called from integerToWords
69
- if (this.wordForScale(number)) {
70
- return this.wordForScale(number)
71
- } else {
72
- const tens = number / 10n
73
- const units = number % 10n
74
- return this.wordForScale(tens * 10n) + this.integerToWords(units)
75
- }
12
+
13
+ import { parseNumericValue } from '../utils/parse-numeric.js'
14
+
15
+ // ============================================================================
16
+ // Vocabulary
17
+ // ============================================================================
18
+
19
+ // Word map using BigInt keys for scale values
20
+ const WORDS = new Map([
21
+ [1_000_000_000_000_000_000_000_000_000n, 'quadrilliárd'],
22
+ [1_000_000_000_000_000_000_000_000n, 'quadrillió'],
23
+ [1_000_000_000_000_000_000_000n, 'trilliárd'],
24
+ [1_000_000_000_000_000_000n, 'trillió'],
25
+ [1_000_000_000_000_000n, 'billiárd'],
26
+ [1_000_000_000_000n, 'billió'],
27
+ [1_000_000_000n, 'milliárd'],
28
+ [1_000_000n, 'millió'],
29
+ [1000n, 'ezer'],
30
+ [100n, 'száz'],
31
+ [90n, 'kilencven'],
32
+ [80n, 'nyolcvan'],
33
+ [70n, 'hetven'],
34
+ [60n, 'hatvan'],
35
+ [50n, 'ötven'],
36
+ [40n, 'negyven'],
37
+ [30n, 'harminc'],
38
+ [29n, 'huszonkilenc'],
39
+ [28n, 'huszonnyolc'],
40
+ [27n, 'huszonhét'],
41
+ [26n, 'huszonhat'],
42
+ [25n, 'huszonöt'],
43
+ [24n, 'huszonnégy'],
44
+ [23n, 'huszonhárom'],
45
+ [22n, 'huszonkettő'],
46
+ [21n, 'huszonegy'],
47
+ [20n, 'húsz'],
48
+ [19n, 'tizenkilenc'],
49
+ [18n, 'tizennyolc'],
50
+ [17n, 'tizenhét'],
51
+ [16n, 'tizenhat'],
52
+ [15n, 'tizenöt'],
53
+ [14n, 'tizennégy'],
54
+ [13n, 'tizenhárom'],
55
+ [12n, 'tizenkettő'],
56
+ [11n, 'tizenegy'],
57
+ [10n, 'tíz'],
58
+ [9n, 'kilenc'],
59
+ [8n, 'nyolc'],
60
+ [7n, 'hét'],
61
+ [6n, 'hat'],
62
+ [5n, 'öt'],
63
+ [4n, 'négy'],
64
+ [3n, 'három'],
65
+ [2n, 'kettő'],
66
+ [1n, 'egy'],
67
+ [0n, 'nulla']
68
+ ])
69
+
70
+ const ZERO = 'nulla'
71
+ const NEGATIVE = 'mínusz'
72
+ const DECIMAL_SEP = 'egész'
73
+
74
+ // ============================================================================
75
+ // Conversion Functions
76
+ // ============================================================================
77
+
78
+ function wordForScale (value) {
79
+ return WORDS.get(value)
80
+ }
81
+
82
+ function tensToCardinal (n) {
83
+ if (WORDS.has(n)) {
84
+ return WORDS.get(n)
85
+ }
86
+ const tens = n / 10n
87
+ const units = n % 10n
88
+ return wordForScale(tens * 10n) + integerToWordsInner(units)
89
+ }
90
+
91
+ function hundredsToCardinal (n) {
92
+ const hundreds = n / 100n
93
+ let prefix = 'száz'
94
+ if (hundreds !== 1n) {
95
+ prefix = integerToWordsInner(hundreds, '') + prefix
76
96
  }
97
+ const postfix = integerToWordsInner(n % 100n, '')
98
+ return prefix + postfix
99
+ }
77
100
 
78
- /** Converts hundreds (100-999) with "száz" composition. */
79
- hundredsToCardinal (number) {
80
- const hundreds = number / 100n
81
- let prefix = 'száz'
82
- if (hundreds !== 1n) {
83
- prefix = this.integerToWords(hundreds, '') + prefix
84
- }
85
- const postfix = this.integerToWords(number % 100n, '')
86
- return prefix + postfix
101
+ function thousandsToCardinal (n) {
102
+ const thousands = n / 1000n
103
+ let prefix = 'ezer'
104
+ if (thousands !== 1n) {
105
+ prefix = integerToWordsInner(thousands, '') + prefix
87
106
  }
107
+ const postfix = integerToWordsInner(n % 1000n, '')
108
+ const middle = (n <= 2000n || postfix === '') ? '' : '-'
109
+ return prefix + middle + postfix
110
+ }
111
+
112
+ // Scale values for finding appropriate scale (avoids toString)
113
+ const SCALES = [
114
+ 1_000_000_000_000_000_000_000_000_000n,
115
+ 1_000_000_000_000_000_000_000_000n,
116
+ 1_000_000_000_000_000_000_000n,
117
+ 1_000_000_000_000_000_000n,
118
+ 1_000_000_000_000_000n,
119
+ 1_000_000_000_000n,
120
+ 1_000_000_000n,
121
+ 1_000_000n
122
+ ]
88
123
 
89
- /** Converts thousands (1000-999999) with "ezer" composition. */
90
- thousandsToCardinal (number) {
91
- const thousands = number / 1000n
92
- let prefix = 'ezer'
93
- if (thousands !== 1n) {
94
- prefix = this.integerToWords(thousands, '') + prefix
124
+ function bigNumberToCardinal (n) {
125
+ // Find appropriate scale using BigInt comparison (avoids toString)
126
+ let exp = 1_000_000n
127
+ for (const scale of SCALES) {
128
+ if (n >= scale) {
129
+ exp = scale
130
+ break
95
131
  }
96
- const postfix = this.integerToWords(number % 1000n, '')
97
- const middle = (number <= 2000n || postfix === '') ? '' : '-'
98
- return prefix + middle + postfix
99
132
  }
100
133
 
101
- /** Converts large numbers (millions and above) with scale words. */
102
- bigNumberToCardinal (number) {
103
- const numberLength = number.toString().length
104
- const digits = (numberLength % 3 === 0) ? numberLength - 2 : numberLength
105
- const exp = 10 ** (Math.floor(digits / 3) * 3)
106
- const prefix = this.integerToWords(number / BigInt(exp), '')
107
- const rest = this.integerToWords(number % BigInt(exp), '')
108
- const postfix = (rest === '') ? '' : ('-' + rest)
109
- return prefix + this.wordForScale(BigInt(exp)) + postfix
134
+ const prefix = integerToWordsInner(n / exp, '')
135
+ const rest = integerToWordsInner(n % exp, '')
136
+ const postfix = (rest === '') ? '' : ('-' + rest)
137
+ return prefix + wordForScale(exp) + postfix
138
+ }
139
+
140
+ function integerToWordsInner (n, zeroWord = ZERO) {
141
+ // Normalize to BigInt for consistent comparisons
142
+ if (typeof n !== 'bigint') n = BigInt(n)
143
+
144
+ if (n === 0n) {
145
+ return zeroWord
146
+ }
147
+ if (zeroWord === '' && n === 2n) {
148
+ return 'két'
149
+ }
150
+ if (n < 30n) {
151
+ return wordForScale(n)
152
+ }
153
+ if (n < 100n) {
154
+ return tensToCardinal(n)
110
155
  }
156
+ if (n < 1000n) {
157
+ return hundredsToCardinal(n)
158
+ }
159
+ if (n < 1_000_000n) {
160
+ return thousandsToCardinal(n)
161
+ }
162
+ return bigNumberToCardinal(n)
163
+ }
111
164
 
112
- /** Converts integer part using Hungarian agglutinative rules. */
113
- integerToWords (integerPart, zeroWord = this.zeroWord) {
114
- let words = ''
115
-
116
- // Normalize to BigInt for consistent comparisons
117
- if (typeof integerPart !== 'bigint') integerPart = BigInt(integerPart)
118
-
119
- if (integerPart === 0n) {
120
- words = zeroWord
121
- } else if (zeroWord === '' && integerPart === 2n) {
122
- words = 'két'
123
- } else if (integerPart < 30n) {
124
- words = this.wordForScale(integerPart)
125
- } else if (integerPart < 100n) {
126
- words = this.tensToCardinal(integerPart)
127
- } else if (integerPart < 1000n) {
128
- words = this.hundredsToCardinal(integerPart)
129
- } else if (integerPart < 1_000_000n) {
130
- words = this.thousandsToCardinal(integerPart)
131
- } else {
132
- words = this.bigNumberToCardinal(integerPart)
133
- }
165
+ function integerToWords (n) {
166
+ return integerToWordsInner(n, ZERO)
167
+ }
168
+
169
+ function decimalPartToWords (decimalPart) {
170
+ let result = ''
171
+ let i = 0
134
172
 
135
- return words
173
+ while (i < decimalPart.length && decimalPart[i] === '0') {
174
+ if (result) result += ' '
175
+ result += ZERO
176
+ i++
136
177
  }
178
+
179
+ const remainder = decimalPart.slice(i)
180
+ if (remainder) {
181
+ if (result) result += ' '
182
+ result += integerToWords(BigInt(remainder))
183
+ }
184
+
185
+ return result
137
186
  }
187
+
188
+ /**
189
+ * Converts a numeric value to Hungarian words.
190
+ *
191
+ * @param {number | string | bigint} value - The numeric value to convert
192
+ * @returns {string} The number in Hungarian words
193
+ */
194
+ function toWords (value) {
195
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
196
+
197
+ let result = ''
198
+
199
+ if (isNegative) {
200
+ result = NEGATIVE + ' '
201
+ }
202
+
203
+ result += integerToWords(integerPart)
204
+
205
+ if (decimalPart) {
206
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
207
+ }
208
+
209
+ return result
210
+ }
211
+
212
+ // ============================================================================
213
+ // Exports
214
+ // ============================================================================
215
+
216
+ export { toWords }
@@ -1,37 +1,7 @@
1
1
  /**
2
- * Indonesian language converter.
2
+ * Converts a numeric value to Indonesian words.
3
3
  *
4
- * Supports:
5
- * - "Se-" prefix for one (seratus, seribu, sejuta)
6
- * - Regular patterns (puluh for tens, ratus for hundreds)
7
- * - Space-separated number components
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Indonesian words
8
6
  */
9
- export class Indonesian 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
- /** Splits number into groups of 3 digits. */
25
- splitBy3(number: any): any[][];
26
- /** Converts digit blocks to Indonesian words. */
27
- spell(blocks: any): any[];
28
- /** Converts hundreds digit with "seratus" or "ratus" suffix. */
29
- getHundreds(number: any): string[];
30
- /** Converts tens and units digits with "puluh" or "belas" suffix. */
31
- getTens(number: any): string[];
32
- /** Joins word blocks with magnitude scale words. */
33
- join(wordBlocks: any): string;
34
- /** Converts integer part using Indonesian group-based conversion. */
35
- integerToWords(integerPart: any): string;
36
- }
37
- import { AbstractLanguage } from '../classes/abstract-language.js';
7
+ export function toWords(value: number | string | bigint): string;