n2words 1.24.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +183 -156
  3. package/dist/languages/am-Latn.js +3 -0
  4. package/dist/languages/am-Latn.js.map +1 -0
  5. package/dist/languages/am.js +3 -0
  6. package/dist/languages/am.js.map +1 -0
  7. package/dist/languages/ar.js +3 -2
  8. package/dist/languages/ar.js.map +1 -1
  9. package/dist/languages/az.js +3 -2
  10. package/dist/languages/az.js.map +1 -1
  11. package/dist/languages/bn.js +3 -2
  12. package/dist/languages/bn.js.map +1 -1
  13. package/dist/languages/cs.js +3 -2
  14. package/dist/languages/cs.js.map +1 -1
  15. package/dist/languages/da.js +3 -2
  16. package/dist/languages/da.js.map +1 -1
  17. package/dist/languages/de.js +3 -2
  18. package/dist/languages/de.js.map +1 -1
  19. package/dist/languages/el.js +3 -2
  20. package/dist/languages/el.js.map +1 -1
  21. package/dist/languages/en.js +3 -2
  22. package/dist/languages/en.js.map +1 -1
  23. package/dist/languages/es.js +3 -2
  24. package/dist/languages/es.js.map +1 -1
  25. package/dist/languages/fa.js +3 -2
  26. package/dist/languages/fa.js.map +1 -1
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -2
  30. package/dist/languages/fil.js.map +1 -1
  31. package/dist/languages/fr-BE.js +3 -2
  32. package/dist/languages/fr-BE.js.map +1 -1
  33. package/dist/languages/fr.js +3 -2
  34. package/dist/languages/fr.js.map +1 -1
  35. package/dist/languages/gu.js +3 -2
  36. package/dist/languages/gu.js.map +1 -1
  37. package/dist/languages/ha.js +3 -0
  38. package/dist/languages/ha.js.map +1 -0
  39. package/dist/languages/hbo.js +3 -0
  40. package/dist/languages/hbo.js.map +1 -0
  41. package/dist/languages/he.js +3 -2
  42. package/dist/languages/he.js.map +1 -1
  43. package/dist/languages/hi.js +3 -2
  44. package/dist/languages/hi.js.map +1 -1
  45. package/dist/languages/hr.js +3 -2
  46. package/dist/languages/hr.js.map +1 -1
  47. package/dist/languages/hu.js +3 -2
  48. package/dist/languages/hu.js.map +1 -1
  49. package/dist/languages/id.js +3 -2
  50. package/dist/languages/id.js.map +1 -1
  51. package/dist/languages/it.js +3 -2
  52. package/dist/languages/it.js.map +1 -1
  53. package/dist/languages/ja.js +3 -2
  54. package/dist/languages/ja.js.map +1 -1
  55. package/dist/languages/kn.js +3 -2
  56. package/dist/languages/kn.js.map +1 -1
  57. package/dist/languages/ko.js +3 -2
  58. package/dist/languages/ko.js.map +1 -1
  59. package/dist/languages/lt.js +3 -2
  60. package/dist/languages/lt.js.map +1 -1
  61. package/dist/languages/lv.js +3 -2
  62. package/dist/languages/lv.js.map +1 -1
  63. package/dist/languages/mr.js +3 -2
  64. package/dist/languages/mr.js.map +1 -1
  65. package/dist/languages/ms.js +3 -2
  66. package/dist/languages/ms.js.map +1 -1
  67. package/dist/languages/nb.js +3 -2
  68. package/dist/languages/nb.js.map +1 -1
  69. package/dist/languages/nl.js +3 -2
  70. package/dist/languages/nl.js.map +1 -1
  71. package/dist/languages/pa.js +3 -0
  72. package/dist/languages/pa.js.map +1 -0
  73. package/dist/languages/pl.js +3 -2
  74. package/dist/languages/pl.js.map +1 -1
  75. package/dist/languages/pt.js +3 -2
  76. package/dist/languages/pt.js.map +1 -1
  77. package/dist/languages/ro.js +3 -2
  78. package/dist/languages/ro.js.map +1 -1
  79. package/dist/languages/ru.js +3 -2
  80. package/dist/languages/ru.js.map +1 -1
  81. package/dist/languages/sr-Cyrl.js +3 -0
  82. package/dist/languages/sr-Cyrl.js.map +1 -0
  83. package/dist/languages/sr-Latn.js +3 -2
  84. package/dist/languages/sr-Latn.js.map +1 -1
  85. package/dist/languages/sv.js +3 -2
  86. package/dist/languages/sv.js.map +1 -1
  87. package/dist/languages/sw.js +3 -2
  88. package/dist/languages/sw.js.map +1 -1
  89. package/dist/languages/ta.js +3 -2
  90. package/dist/languages/ta.js.map +1 -1
  91. package/dist/languages/te.js +3 -2
  92. package/dist/languages/te.js.map +1 -1
  93. package/dist/languages/th.js +3 -2
  94. package/dist/languages/th.js.map +1 -1
  95. package/dist/languages/tr.js +3 -2
  96. package/dist/languages/tr.js.map +1 -1
  97. package/dist/languages/uk.js +3 -2
  98. package/dist/languages/uk.js.map +1 -1
  99. package/dist/languages/ur.js +3 -2
  100. package/dist/languages/ur.js.map +1 -1
  101. package/dist/languages/vi.js +3 -2
  102. package/dist/languages/vi.js.map +1 -1
  103. package/dist/languages/zh-Hans.js +3 -2
  104. package/dist/languages/zh-Hans.js.map +1 -1
  105. package/dist/languages/zh-Hant.js +3 -0
  106. package/dist/languages/zh-Hant.js.map +1 -0
  107. package/dist/n2words.js +3 -2
  108. package/dist/n2words.js.map +1 -1
  109. package/lib/languages/am-Latn.d.ts +7 -0
  110. package/lib/languages/am-Latn.js +164 -0
  111. package/lib/languages/am.d.ts +7 -0
  112. package/lib/languages/am.js +164 -0
  113. package/lib/languages/ar.d.ts +17 -0
  114. package/lib/languages/ar.js +171 -209
  115. package/lib/languages/az.d.ts +7 -0
  116. package/lib/languages/az.js +167 -49
  117. package/lib/languages/bn.d.ts +7 -0
  118. package/lib/languages/bn.js +142 -123
  119. package/lib/languages/cs.d.ts +18 -0
  120. package/lib/languages/cs.js +303 -176
  121. package/lib/languages/da.d.ts +14 -0
  122. package/lib/languages/da.js +267 -139
  123. package/lib/languages/de.d.ts +17 -0
  124. package/lib/languages/de.js +310 -113
  125. package/lib/languages/el.d.ts +14 -0
  126. package/lib/languages/el.js +225 -98
  127. package/lib/languages/en.d.ts +17 -0
  128. package/lib/languages/en.js +235 -102
  129. package/lib/languages/es.d.ts +21 -0
  130. package/lib/languages/es.js +307 -125
  131. package/lib/languages/fa.d.ts +7 -0
  132. package/lib/languages/fa.js +115 -108
  133. package/lib/languages/fi.d.ts +14 -0
  134. package/lib/languages/fi.js +245 -0
  135. package/lib/languages/fil.d.ts +7 -0
  136. package/lib/languages/fil.js +199 -139
  137. package/lib/languages/fr-BE.d.ts +11 -0
  138. package/lib/languages/fr-BE.js +287 -48
  139. package/lib/languages/fr.d.ts +21 -0
  140. package/lib/languages/fr.js +343 -119
  141. package/lib/languages/gu.d.ts +7 -0
  142. package/lib/languages/gu.js +125 -144
  143. package/lib/languages/ha.d.ts +7 -0
  144. package/lib/languages/ha.js +230 -0
  145. package/lib/languages/hbo.d.ts +13 -0
  146. package/lib/languages/hbo.js +300 -0
  147. package/lib/languages/he.d.ts +13 -0
  148. package/lib/languages/he.js +230 -283
  149. package/lib/languages/hi.d.ts +7 -0
  150. package/lib/languages/hi.js +142 -123
  151. package/lib/languages/hr.d.ts +11 -0
  152. package/lib/languages/hr.js +190 -129
  153. package/lib/languages/hu.d.ts +7 -0
  154. package/lib/languages/hu.js +194 -133
  155. package/lib/languages/id.d.ts +7 -0
  156. package/lib/languages/id.js +167 -140
  157. package/lib/languages/it.d.ts +19 -0
  158. package/lib/languages/it.js +337 -108
  159. package/lib/languages/ja.d.ts +17 -0
  160. package/lib/languages/ja.js +224 -155
  161. package/lib/languages/kn.d.ts +7 -0
  162. package/lib/languages/kn.js +128 -62
  163. package/lib/languages/ko.d.ts +14 -0
  164. package/lib/languages/ko.js +250 -70
  165. package/lib/languages/lt.d.ts +18 -0
  166. package/lib/languages/lt.js +287 -148
  167. package/lib/languages/lv.d.ts +18 -0
  168. package/lib/languages/lv.js +291 -123
  169. package/lib/languages/mr.d.ts +7 -0
  170. package/lib/languages/mr.js +125 -144
  171. package/lib/languages/ms.d.ts +7 -0
  172. package/lib/languages/ms.js +171 -112
  173. package/lib/languages/nb.d.ts +14 -0
  174. package/lib/languages/nb.js +275 -100
  175. package/lib/languages/nl.d.ts +26 -0
  176. package/lib/languages/nl.js +307 -174
  177. package/lib/languages/pa.d.ts +7 -0
  178. package/lib/languages/pa.js +163 -0
  179. package/lib/languages/pl.d.ts +22 -0
  180. package/lib/languages/pl.js +299 -158
  181. package/lib/languages/pt.d.ts +17 -0
  182. package/lib/languages/pt.js +279 -120
  183. package/lib/languages/ro.d.ts +18 -0
  184. package/lib/languages/ro.js +214 -337
  185. package/lib/languages/ru.d.ts +11 -0
  186. package/lib/languages/ru.js +219 -95
  187. package/lib/languages/sr-Cyrl.d.ts +11 -0
  188. package/lib/languages/sr-Cyrl.js +215 -0
  189. package/lib/languages/sr-Latn.d.ts +11 -0
  190. package/lib/languages/sr-Latn.js +190 -132
  191. package/lib/languages/sv.d.ts +14 -0
  192. package/lib/languages/sv.js +280 -103
  193. package/lib/languages/sw.d.ts +7 -0
  194. package/lib/languages/sw.js +135 -103
  195. package/lib/languages/ta.d.ts +7 -0
  196. package/lib/languages/ta.js +133 -205
  197. package/lib/languages/te.d.ts +7 -0
  198. package/lib/languages/te.js +148 -213
  199. package/lib/languages/th.d.ts +7 -0
  200. package/lib/languages/th.js +139 -101
  201. package/lib/languages/tr.d.ts +18 -0
  202. package/lib/languages/tr.js +246 -66
  203. package/lib/languages/uk.d.ts +11 -0
  204. package/lib/languages/uk.js +197 -101
  205. package/lib/languages/ur.d.ts +7 -0
  206. package/lib/languages/ur.js +160 -123
  207. package/lib/languages/vi.d.ts +17 -0
  208. package/lib/languages/vi.js +287 -164
  209. package/lib/languages/zh-Hans.d.ts +11 -0
  210. package/lib/languages/zh-Hans.js +159 -142
  211. package/lib/languages/zh-Hant.d.ts +11 -0
  212. package/lib/languages/zh-Hant.js +202 -0
  213. package/lib/n2words.d.ts +53 -0
  214. package/lib/n2words.js +91 -227
  215. package/lib/utils/is-plain-object.d.ts +13 -0
  216. package/lib/utils/is-plain-object.js +17 -0
  217. package/lib/utils/parse-numeric.d.ts +17 -0
  218. package/lib/utils/parse-numeric.js +108 -0
  219. package/lib/utils/validate-options.d.ts +8 -0
  220. package/lib/utils/validate-options.js +16 -0
  221. package/package.json +118 -67
  222. package/dist/languages/pa-Guru.js +0 -2
  223. package/dist/languages/pa-Guru.js.map +0 -1
  224. package/lib/classes/abstract-language.js +0 -261
  225. package/lib/classes/greedy-scale-language.js +0 -195
  226. package/lib/classes/slavic-language.js +0 -251
  227. package/lib/classes/south-asian-language.js +0 -161
  228. package/lib/classes/turkic-language.js +0 -63
  229. package/lib/languages/pa-Guru.js +0 -126
  230. package/typings/classes/abstract-language.d.ts +0 -144
  231. package/typings/classes/greedy-scale-language.d.ts +0 -148
  232. package/typings/classes/slavic-language.d.ts +0 -145
  233. package/typings/classes/south-asian-language.d.ts +0 -101
  234. package/typings/classes/turkic-language.d.ts +0 -42
  235. package/typings/languages/ar.d.ts +0 -93
  236. package/typings/languages/az.d.ts +0 -25
  237. package/typings/languages/bn.d.ts +0 -1
  238. package/typings/languages/cs.d.ts +0 -120
  239. package/typings/languages/da.d.ts +0 -53
  240. package/typings/languages/de.d.ts +0 -26
  241. package/typings/languages/el.d.ts +0 -11
  242. package/typings/languages/en.d.ts +0 -30
  243. package/typings/languages/es.d.ts +0 -43
  244. package/typings/languages/fa.d.ts +0 -81
  245. package/typings/languages/fil.d.ts +0 -12
  246. package/typings/languages/fr-BE.d.ts +0 -41
  247. package/typings/languages/fr.d.ts +0 -43
  248. package/typings/languages/gu.d.ts +0 -12
  249. package/typings/languages/he.d.ts +0 -197
  250. package/typings/languages/hi.d.ts +0 -1
  251. package/typings/languages/hr.d.ts +0 -110
  252. package/typings/languages/hu.d.ts +0 -37
  253. package/typings/languages/id.d.ts +0 -69
  254. package/typings/languages/it.d.ts +0 -51
  255. package/typings/languages/ja.d.ts +0 -58
  256. package/typings/languages/kn.d.ts +0 -11
  257. package/typings/languages/ko.d.ts +0 -25
  258. package/typings/languages/lt.d.ts +0 -110
  259. package/typings/languages/lv.d.ts +0 -99
  260. package/typings/languages/mr.d.ts +0 -12
  261. package/typings/languages/ms.d.ts +0 -37
  262. package/typings/languages/nb.d.ts +0 -27
  263. package/typings/languages/nl.d.ts +0 -65
  264. package/typings/languages/pa-Guru.d.ts +0 -1
  265. package/typings/languages/pl.d.ts +0 -116
  266. package/typings/languages/pt.d.ts +0 -39
  267. package/typings/languages/ro.d.ts +0 -229
  268. package/typings/languages/ru.d.ts +0 -108
  269. package/typings/languages/sr-Latn.d.ts +0 -98
  270. package/typings/languages/sv.d.ts +0 -30
  271. package/typings/languages/sw.d.ts +0 -1
  272. package/typings/languages/ta.d.ts +0 -1
  273. package/typings/languages/te.d.ts +0 -1
  274. package/typings/languages/th.d.ts +0 -1
  275. package/typings/languages/tr.d.ts +0 -46
  276. package/typings/languages/uk.d.ts +0 -117
  277. package/typings/languages/ur.d.ts +0 -1
  278. package/typings/languages/vi.d.ts +0 -116
  279. package/typings/languages/zh-Hans.d.ts +0 -57
  280. package/typings/n2words.d.ts +0 -177
@@ -1,155 +1,216 @@
1
- import GreedyScaleLanguage from '../classes/greedy-scale-language.js'
2
-
3
1
  /**
4
- * Hungarian language converter.
2
+ * Hungarian language converter - Functional Implementation
5
3
  *
6
- * Converts numbers to Hungarian words following Hungarian conventions:
7
- * - Agglutinative structure for compound numbers
8
- * - No spaces between tens and units (e.g., "huszonegy" = twenty-one)
9
- * - Special handling for "egy" (one) - often omitted as multiplier
10
- * - Vowel harmony in compound words
4
+ * Self-contained converter with agglutinative word formation.
11
5
  *
12
- * Features:
13
- * - Compact number representations (húsz, harminc, negyven)
6
+ * Key features:
7
+ * - Agglutinative structure (no spaces between compound parts)
8
+ * - Special handling for "egy" (one) omission
14
9
  * - Pre-composed twenties (huszonegy through huszonkilenc)
15
- * - "egész" as decimal separator (meaning "whole")
16
- * - Support for very large numbers (up to quadrilliards)
10
+ * - "két" instead of "kettő" in compound forms
17
11
  */
18
- export class Hungarian extends GreedyScaleLanguage {
19
- negativeWord = 'mínusz'
20
- decimalSeparatorWord = 'egész'
21
- zeroWord = 'nulla'
22
- scaleWordPairs = [
23
- [1_000_000_000_000_000_000_000_000_000n, 'quadrilliárd'],
24
- [1_000_000_000_000_000_000_000_000n, 'quadrillió'],
25
- [1_000_000_000_000_000_000_000n, 'trilliárd'],
26
- [1_000_000_000_000_000_000n, 'trillió'],
27
- [1_000_000_000_000_000n, 'billiárd'],
28
- [1_000_000_000_000n, 'billió'],
29
- [1_000_000_000n, 'milliárd'],
30
- [1_000_000n, 'millió'],
31
- [1000n, 'ezer'],
32
- [100n, 'száz'],
33
- [90n, 'kilencven'],
34
- [80n, 'nyolcvan'],
35
- [70n, 'hetven'],
36
- [60n, 'hatvan'],
37
- [50n, 'ötven'],
38
- [40n, 'negyven'],
39
- [30n, 'harminc'],
40
- [29n, 'huszonkilenc'],
41
- [28n, 'huszonnyolc'],
42
- [27n, 'huszonhét'],
43
- [26n, 'huszonhat'],
44
- [25n, 'huszonöt'],
45
- [24n, 'huszonnégy'],
46
- [23n, 'huszonhárom'],
47
- [22n, 'huszonkettő'],
48
- [21n, 'huszonegy'],
49
- [20n, 'húsz'],
50
- [19n, 'tizenkilenc'],
51
- [18n, 'tizennyolc'],
52
- [17n, 'tizenhét'],
53
- [16n, 'tizenhat'],
54
- [15n, 'tizenöt'],
55
- [14n, 'tizennégy'],
56
- [13n, 'tizenhárom'],
57
- [12n, 'tizenkettő'],
58
- [11n, 'tizenegy'],
59
- [10n, 'tíz'],
60
- [9n, 'kilenc'],
61
- [8n, 'nyolc'],
62
- [7n, 'hét'],
63
- [6n, 'hat'],
64
- [5n, 'öt'],
65
- [4n, 'négy'],
66
- [3n, 'három'],
67
- [2n, 'kettő'],
68
- [1n, 'egy'],
69
- [0n, 'nulla']
70
- ]
71
-
72
- tensToCardinal (number) {
73
- // Expecting `number` as bigint when called from convertWholePart
74
- if (this.getScaleWord(number)) {
75
- return this.getScaleWord(number)
76
- } else {
77
- const tens = number / 10n
78
- const units = number % 10n
79
- return this.getScaleWord(tens * 10n) + this.convertWholePart(units)
80
- }
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)
81
85
  }
86
+ const tens = n / 10n
87
+ const units = n % 10n
88
+ return wordForScale(tens * 10n) + integerToWordsInner(units)
89
+ }
82
90
 
83
- hundredsToCardinal (number) {
84
- const hundreds = number / 100n
85
- let prefix = 'száz'
86
- if (hundreds !== 1n) {
87
- prefix = this.convertWholePart(hundreds, '') + prefix
88
- }
89
- const postfix = this.convertWholePart(number % 100n, '')
90
- return prefix + postfix
91
+ function hundredsToCardinal (n) {
92
+ const hundreds = n / 100n
93
+ let prefix = 'száz'
94
+ if (hundreds !== 1n) {
95
+ prefix = integerToWordsInner(hundreds, '') + prefix
91
96
  }
97
+ const postfix = integerToWordsInner(n % 100n, '')
98
+ return prefix + postfix
99
+ }
100
+
101
+ function thousandsToCardinal (n) {
102
+ const thousands = n / 1000n
103
+ let prefix = 'ezer'
104
+ if (thousands !== 1n) {
105
+ prefix = integerToWordsInner(thousands, '') + prefix
106
+ }
107
+ const postfix = integerToWordsInner(n % 1000n, '')
108
+ const middle = (n <= 2000n || postfix === '') ? '' : '-'
109
+ return prefix + middle + postfix
110
+ }
92
111
 
93
- thousandsToCardinal (number) {
94
- const thousands = number / 1000n
95
- let prefix = 'ezer'
96
- if (thousands !== 1n) {
97
- prefix = this.convertWholePart(thousands, '') + prefix
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
+ ]
123
+
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
98
131
  }
99
- const postfix = this.convertWholePart(number % 1000n, '')
100
- const middle = (number <= 2000n || postfix === '') ? '' : '-'
101
- return prefix + middle + postfix
102
132
  }
103
133
 
104
- bigNumberToCardinal (number) {
105
- const numberLength = number.toString().length
106
- const digits = (numberLength % 3 === 0) ? numberLength - 2 : numberLength
107
- const exp = 10 ** (Math.floor(digits / 3) * 3)
108
- const prefix = this.convertWholePart(number / BigInt(exp), '')
109
- const rest = this.convertWholePart(number % BigInt(exp), '')
110
- const postfix = (rest === '') ? '' : ('-' + rest)
111
- return prefix + this.getScaleWord(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'
112
149
  }
150
+ if (n < 30n) {
151
+ return wordForScale(n)
152
+ }
153
+ if (n < 100n) {
154
+ return tensToCardinal(n)
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
+ }
113
164
 
114
- convertWholePart (number, zeroWord = this.zeroWord) {
115
- let words = ''
116
-
117
- // Normalize to BigInt for consistent comparisons
118
- if (typeof number !== 'bigint') number = BigInt(number)
119
-
120
- if (number === 0n) {
121
- words = zeroWord
122
- } else if (zeroWord === '' && number === 2n) {
123
- words = 'két'
124
- } else if (number < 30n) {
125
- words = this.getScaleWord(number)
126
- } else if (number < 100n) {
127
- words = this.tensToCardinal(number)
128
- } else if (number < 1000n) {
129
- words = this.hundredsToCardinal(number)
130
- } else if (number < 1_000_000n) {
131
- words = this.thousandsToCardinal(number)
132
- } else {
133
- words = this.bigNumberToCardinal(number)
134
- }
165
+ function integerToWords (n) {
166
+ return integerToWordsInner(n, ZERO)
167
+ }
168
+
169
+ function decimalPartToWords (decimalPart) {
170
+ let result = ''
171
+ let i = 0
135
172
 
136
- return words
173
+ while (i < decimalPart.length && decimalPart[i] === '0') {
174
+ if (result) result += ' '
175
+ result += ZERO
176
+ i++
137
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
138
186
  }
139
187
 
140
188
  /**
141
- * Converts a number to Hungarian cardinal (written) form.
189
+ * Converts a numeric value to Hungarian words.
142
190
  *
143
- * @param {number|string|bigint} value The number to convert.
144
- * @param {Object} [options] Conversion options (see Hungarian class options).
145
- * @returns {string} The number expressed in Hungarian words.
146
- * @throws {TypeError} If value is NaN or invalid type.
147
- * @throws {Error} If value is an invalid number string.
148
- *
149
- * @example
150
- * convertToWords(42); // 'negyvenkettő'
151
- * convertToWords(21); // 'huszonegy'
191
+ * @param {number | string | bigint} value - The numeric value to convert
192
+ * @returns {string} The number in Hungarian words
152
193
  */
153
- export default function convertToWords (value, options = {}) {
154
- return new Hungarian(options).convertToWords(value)
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
155
210
  }
211
+
212
+ // ============================================================================
213
+ // Exports
214
+ // ============================================================================
215
+
216
+ export { toWords }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Converts a numeric value to Indonesian words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Indonesian words
6
+ */
7
+ export function toWords(value: number | string | bigint): string;