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,131 +1,145 @@
1
- import { SouthAsianLanguage } from '../classes/south-asian-language.js'
2
-
3
1
  /**
4
- * Hindi language converter.
2
+ * Hindi language converter - Functional Implementation
3
+ *
4
+ * Self-contained converter for South Asian numbering.
5
5
  *
6
- * Supports:
6
+ * Key features:
7
7
  * - Indian numbering system (हज़ार, लाख, करोड़)
8
8
  * - Devanagari script
9
+ * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)
9
10
  * - Complete word forms for 0-99
10
11
  */
11
- export class Hindi extends SouthAsianLanguage {
12
- negativeWord = 'माइनस'
13
- decimalSeparatorWord = 'दशमलव'
14
- zeroWord = 'शून्य'
15
- hundredWord = 'सौ'
16
-
17
- belowHundredWords = [
18
- 'शून्य',
19
- 'एक',
20
- 'दो',
21
- 'तीन',
22
- 'चार',
23
- 'पाँच',
24
- 'छह',
25
- 'सात',
26
- 'आठ',
27
- 'नौ',
28
- 'दस',
29
- 'ग्यारह',
30
- 'बारह',
31
- 'तेरह',
32
- 'चौदह',
33
- 'पंद्रह',
34
- 'सोलह',
35
- 'सत्रह',
36
- 'अठारह',
37
- 'उन्नीस',
38
- 'बीस',
39
- 'इक्कीस',
40
- 'बाईस',
41
- 'तेईस',
42
- 'चौबीस',
43
- 'पच्चीस',
44
- 'छब्बीस',
45
- 'सत्ताईस',
46
- 'अट्ठाईस',
47
- 'उनतीस',
48
- 'तीस',
49
- 'इकतीस',
50
- 'बत्तीस',
51
- 'तैंतीस',
52
- 'चौंतीस',
53
- 'पैंतीस',
54
- 'छत्तीस',
55
- 'सैंतीस',
56
- 'अड़तीस',
57
- 'उनतालीस',
58
- 'चालीस',
59
- 'इकतालीस',
60
- 'बयालीस',
61
- 'तेतालीस',
62
- 'चवालीस',
63
- 'पैंतालीस',
64
- 'छियालीस',
65
- 'सैंतालीस',
66
- 'अड़तालीस',
67
- 'उनचास',
68
- 'पचास',
69
- 'इक्यावन',
70
- 'बावन',
71
- 'तिरपन',
72
- 'चौवन',
73
- 'पचपन',
74
- 'छप्पन',
75
- 'सत्तावन',
76
- 'अट्ठावन',
77
- 'उनसठ',
78
- 'साठ',
79
- 'इकसठ',
80
- 'बासठ',
81
- 'तिरसठ',
82
- 'चौंसठ',
83
- 'पैंसठ',
84
- 'छियासठ',
85
- 'सड़सठ',
86
- 'अड़सठ',
87
- 'उनहत्तर',
88
- 'सत्तर',
89
- 'इकहत्तर',
90
- 'बहत्तर',
91
- 'तिहत्तर',
92
- 'चौहत्तर',
93
- 'पचहत्तर',
94
- 'छिहत्तर',
95
- 'सतहत्तर',
96
- 'अठहत्तर',
97
- 'उन्यासी',
98
- 'अस्सी',
99
- 'इक्यासी',
100
- 'बयासी',
101
- 'तिरासी',
102
- 'चौरासी',
103
- 'पचासी',
104
- 'छियासी',
105
- 'सत्तासी',
106
- 'अट्ठासी',
107
- 'नवासी',
108
- 'नब्बे',
109
- 'इक्यानवे',
110
- 'बानवे',
111
- 'तिरानवे',
112
- 'चौरानवे',
113
- 'पचानवे',
114
- 'छियानवे',
115
- 'सत्तानवे',
116
- 'अट्ठानवे',
117
- 'निन्यानवे'
118
- ]
119
-
120
- scaleWords = [
121
- '',
122
- 'हज़ार',
123
- 'लाख',
124
- 'करोड़',
125
- 'अरब',
126
- 'खरब',
127
- 'नील',
128
- 'पद्म',
129
- 'शंख'
130
- ]
12
+
13
+ import { parseNumericValue } from '../utils/parse-numeric.js'
14
+
15
+ // ============================================================================
16
+ // Vocabulary
17
+ // ============================================================================
18
+
19
+ const ZERO = 'शून्य'
20
+ const NEGATIVE = 'माइनस'
21
+ const DECIMAL_SEP = 'दशमलव'
22
+ const HUNDRED = 'सौ'
23
+
24
+ const BELOW_HUNDRED = [
25
+ 'शून्य', 'एक', 'दो', 'तीन', 'चार', 'पाँच', 'छह', 'सात', 'आठ', 'नौ',
26
+ 'दस', 'ग्यारह', 'बारह', 'तेरह', 'चौदह', 'पंद्रह', 'सोलह', 'सत्रह', 'अठारह', 'उन्नीस',
27
+ 'बीस', 'इक्कीस', 'बाईस', 'तेईस', 'चौबीस', 'पच्चीस', 'छब्बीस', 'सत्ताईस', 'अट्ठाईस', 'उनतीस',
28
+ 'तीस', 'इकतीस', 'बत्तीस', 'तैंतीस', 'चौंतीस', 'पैंतीस', 'छत्तीस', 'सैंतीस', 'अड़तीस', 'उनतालीस',
29
+ 'चालीस', 'इकतालीस', 'बयालीस', 'तेतालीस', 'चवालीस', 'पैंतालीस', 'छियालीस', 'सैंतालीस', 'अड़तालीस', 'उनचास',
30
+ 'पचास', 'इक्यावन', 'बावन', 'तिरपन', 'चौवन', 'पचपन', 'छप्पन', 'सत्तावन', 'अट्ठावन', 'उनसठ',
31
+ 'साठ', 'इकसठ', 'बासठ', 'तिरसठ', 'चौंसठ', 'पैंसठ', 'छियासठ', 'सड़सठ', 'अड़सठ', 'उनहत्तर',
32
+ 'सत्तर', 'इकहत्तर', 'बहत्तर', 'तिहत्तर', 'चौहत्तर', 'पचहत्तर', 'छिहत्तर', 'सतहत्तर', 'अठहत्तर', 'उन्यासी',
33
+ 'अस्सी', 'इक्यासी', 'बयासी', 'तिरासी', 'चौरासी', 'पचासी', 'छियासी', 'सत्तासी', 'अट्ठासी', 'नवासी',
34
+ 'नब्बे', 'इक्यानवे', 'बानवे', 'तिरानवे', 'चौरानवे', 'पचानवे', 'छियानवे', 'सत्तानवे', 'अट्ठानवे', 'निन्यानवे'
35
+ ]
36
+
37
+ // Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.
38
+ const SCALE_WORDS = ['', 'हज़ार', 'लाख', 'करोड़', 'अरब', 'खरब', 'नील', 'पद्म', 'शंख']
39
+
40
+ // ============================================================================
41
+ // Segment Splitting (inlined for performance)
42
+ // ============================================================================
43
+
44
+ function groupByThreeThenTwos (n) {
45
+ const numStr = n.toString()
46
+ if (numStr.length <= 3) return [Number(numStr)]
47
+
48
+ const segments = []
49
+ segments.unshift(Number(numStr.slice(-3)))
50
+
51
+ let remaining = numStr.slice(0, -3)
52
+ while (remaining.length > 0) {
53
+ segments.unshift(Number(remaining.slice(-2)))
54
+ remaining = remaining.slice(0, -2)
55
+ }
56
+
57
+ return segments
58
+ }
59
+
60
+ function segmentToWords (n) {
61
+ if (n === 0) return ''
62
+ if (n < 100) return BELOW_HUNDRED[n]
63
+
64
+ const hundreds = Math.trunc(n / 100)
65
+ const remainder = n % 100
66
+
67
+ if (remainder === 0) {
68
+ return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED
69
+ }
70
+ return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]
71
+ }
72
+
73
+ // ============================================================================
74
+ // Conversion Functions
75
+ // ============================================================================
76
+
77
+ function integerToWords (n) {
78
+ if (n === 0n) return ZERO
79
+
80
+ const segments = groupByThreeThenTwos(n)
81
+ const segmentCount = segments.length
82
+ const words = []
83
+
84
+ for (let i = 0; i < segmentCount; i++) {
85
+ const segmentValue = segments[i]
86
+ if (segmentValue === 0) continue
87
+
88
+ const scaleIndex = segmentCount - i - 1
89
+ words.push(segmentToWords(segmentValue))
90
+ if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {
91
+ words.push(SCALE_WORDS[scaleIndex])
92
+ }
93
+ }
94
+
95
+ return words.join(' ').trim()
96
+ }
97
+
98
+ function decimalPartToWords (decimalPart) {
99
+ let result = ''
100
+ let i = 0
101
+
102
+ while (i < decimalPart.length && decimalPart[i] === '0') {
103
+ if (result) result += ' '
104
+ result += ZERO
105
+ i++
106
+ }
107
+
108
+ const remainder = decimalPart.slice(i)
109
+ if (remainder) {
110
+ if (result) result += ' '
111
+ result += integerToWords(BigInt(remainder))
112
+ }
113
+
114
+ return result
115
+ }
116
+
117
+ /**
118
+ * Converts a numeric value to Hindi words.
119
+ *
120
+ * @param {number | string | bigint} value - The numeric value to convert
121
+ * @returns {string} The number in Hindi words
122
+ */
123
+ function toWords (value) {
124
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
125
+
126
+ let result = ''
127
+
128
+ if (isNegative) {
129
+ result = NEGATIVE + ' '
130
+ }
131
+
132
+ result += integerToWords(integerPart)
133
+
134
+ if (decimalPart) {
135
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
136
+ }
137
+
138
+ return result
131
139
  }
140
+
141
+ // ============================================================================
142
+ // Exports
143
+ // ============================================================================
144
+
145
+ export { toWords }
@@ -1,80 +1,11 @@
1
1
  /**
2
- * Croatian language converter.
2
+ * Converts a numeric value to Croatian words.
3
3
  *
4
- * Supports:
5
- * - Three-form pluralization (one/few/many)
6
- * - Gender agreement (jedan/jedna, dva/dvije)
7
- * - Croatian-specific declension endings
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @param {Object} [options] - Optional configuration
6
+ * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
7
+ * @returns {string} The number in Croatian words
8
8
  */
9
- export class Croatian extends SlavicLanguage {
10
- onesWords: {
11
- 1: string;
12
- 2: string;
13
- 3: string;
14
- 4: string;
15
- 5: string;
16
- 6: string;
17
- 7: string;
18
- 8: string;
19
- 9: string;
20
- };
21
- onesFeminineWords: {
22
- 1: string;
23
- 2: string;
24
- 3: string;
25
- 4: string;
26
- 5: string;
27
- 6: string;
28
- 7: string;
29
- 8: string;
30
- 9: string;
31
- };
32
- teensWords: {
33
- 0: string;
34
- 1: string;
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
- twentiesWords: {
45
- 2: string;
46
- 3: string;
47
- 4: string;
48
- 5: string;
49
- 6: string;
50
- 7: string;
51
- 8: string;
52
- 9: string;
53
- };
54
- hundredsWords: {
55
- 1: string;
56
- 2: string;
57
- 3: string;
58
- 4: string;
59
- 5: string;
60
- 6: string;
61
- 7: string;
62
- 8: string;
63
- 9: string;
64
- };
65
- pluralForms: {
66
- 1: string[];
67
- 2: string[];
68
- 3: string[];
69
- 4: string[];
70
- 5: string[];
71
- 6: string[];
72
- 7: string[];
73
- 8: string[];
74
- 9: string[];
75
- 10: string[];
76
- };
77
- /** Selects Croatian plural form: 1 = singular, 2-4 = few, else = many. */
78
- pluralize(n: any, forms: any): any;
79
- }
80
- import { SlavicLanguage } from '../classes/slavic-language.js';
9
+ export function toWords(value: number | string | bigint, options?: {
10
+ gender?: "masculine" | "feminine" | undefined;
11
+ }): string;
@@ -1,113 +1,218 @@
1
- import { SlavicLanguage } from '../classes/slavic-language.js'
2
-
3
1
  /**
4
- * Croatian language converter.
2
+ * Croatian language converter - Functional Implementation
3
+ *
4
+ * Self-contained converter using shared Slavic utilities.
5
5
  *
6
- * Supports:
6
+ * Key features:
7
7
  * - Three-form pluralization (one/few/many)
8
- * - Gender agreement (jedan/jedna, dva/dvije)
9
- * - Croatian-specific declension endings
8
+ * - Gender: thousands are feminine, millions+ are masculine
9
+ * - Irregular hundreds (dvjesto, tristo, etc.)
10
+ * - Long scale naming with -ard forms
10
11
  */
11
- export class Croatian extends SlavicLanguage {
12
- negativeWord = 'minus'
13
- decimalSeparatorWord = 'zarez'
14
- zeroWord = 'nula'
15
-
16
- onesWords = {
17
- 1: 'jedan',
18
- 2: 'dva',
19
- 3: 'tri',
20
- 4: 'četiri',
21
- 5: 'pet',
22
- 6: 'šest',
23
- 7: 'sedam',
24
- 8: 'osam',
25
- 9: 'devet'
12
+
13
+ import { parseNumericValue } from '../utils/parse-numeric.js'
14
+ import { validateOptions } from '../utils/validate-options.js'
15
+
16
+ // ============================================================================
17
+ // Slavic Utilities (inlined for performance)
18
+ // ============================================================================
19
+
20
+ function pluralize (n, forms) {
21
+ const num = typeof n === 'bigint' ? Number(n) : n
22
+ const lastDigit = num % 10
23
+ const lastTwoDigits = num % 100
24
+
25
+ if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
26
+ return forms[2]
26
27
  }
27
28
 
28
- onesFeminineWords = {
29
- 1: 'jedna',
30
- 2: 'dvije',
31
- 3: 'tri',
32
- 4: 'četiri',
33
- 5: 'pet',
34
- 6: 'šest',
35
- 7: 'sedam',
36
- 8: 'osam',
37
- 9: 'devet'
29
+ if (lastDigit === 1) return forms[0]
30
+ if (lastDigit >= 2 && lastDigit <= 4) return forms[1]
31
+ return forms[2]
32
+ }
33
+
34
+ function buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {
35
+ const masc = new Array(1000)
36
+ const fem = new Array(1000)
37
+
38
+ for (let i = 0; i < 1000; i++) {
39
+ masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)
40
+ fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)
38
41
  }
39
42
 
40
- teensWords = {
41
- 0: 'deset',
42
- 1: 'jedanaest',
43
- 2: 'dvanaest',
44
- 3: 'trinaest',
45
- 4: 'četrnaest',
46
- 5: 'petnaest',
47
- 6: 'šesnaest',
48
- 7: 'sedamnaest',
49
- 8: 'osamnaest',
50
- 9: 'devetnaest'
43
+ return { masc, fem }
44
+ }
45
+
46
+ function buildSegment (n, ones, teens, tens, hundreds) {
47
+ if (n === 0) return ''
48
+
49
+ const onesDigit = n % 10
50
+ const tensDigit = Math.floor(n / 10) % 10
51
+ const hundredsDigit = Math.floor(n / 100)
52
+
53
+ const parts = []
54
+
55
+ if (hundredsDigit > 0) {
56
+ parts.push(hundreds[hundredsDigit])
51
57
  }
52
58
 
53
- twentiesWords = {
54
- 2: 'dvadeset',
55
- 3: 'trideset',
56
- 4: 'četrdeset',
57
- 5: 'pedeset',
58
- 6: 'šezdeset',
59
- 7: 'sedamdeset',
60
- 8: 'osamdeset',
61
- 9: 'devedeset'
59
+ if (tensDigit > 1) {
60
+ parts.push(tens[tensDigit])
62
61
  }
63
62
 
64
- hundredsWords = {
65
- 1: 'sto',
66
- 2: 'dvjesto',
67
- 3: 'tristo',
68
- 4: 'četiristo',
69
- 5: 'petsto',
70
- 6: 'šesto',
71
- 7: 'sedamsto',
72
- 8: 'osamsto',
73
- 9: 'devetsto'
63
+ if (tensDigit === 1) {
64
+ parts.push(teens[onesDigit])
65
+ } else if (onesDigit > 0) {
66
+ parts.push(ones[onesDigit])
74
67
  }
75
68
 
76
- pluralForms = {
77
- 1: ['tisuća', 'tisuće', 'tisuća'], // 10 ^ 3
78
- 2: ['milijun', 'milijuna', 'milijuna'], // 10 ^ 6
79
- 3: ['milijarda', 'milijarde', 'milijarda'], // 10 ^ 9
80
- 4: ['bilijun', 'bilijuna', 'bilijuna'], // 10 ^ 12
81
- 5: ['bilijarda', 'bilijarde', 'bilijarda'], // 10 ^ 15
82
- 6: ['trilijun', 'trilijuna', 'trilijuna'], // 10 ^ 18
83
- 7: ['trilijarda', 'trilijarde', 'trilijarda'], // 10 ^ 21
84
- 8: ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna'], // 10 ^ 24
85
- 9: ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda'], // 10 ^ 27
86
- 10: ['kvintilijun', 'kvintilijuna', 'kvintilijuna'] // 10 ^ 30
69
+ return parts.join(' ')
70
+ }
71
+
72
+ // ============================================================================
73
+ // Vocabulary
74
+ // ============================================================================
75
+
76
+ const ONES_MASC = ['', 'jedan', 'dva', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
77
+ const ONES_FEM = ['', 'jedna', 'dvije', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']
78
+
79
+ const TEENS = ['deset', 'jedanaest', 'dvanaest', 'trinaest', 'četrnaest', 'petnaest', 'šesnaest', 'sedamnaest', 'osamnaest', 'devetnaest']
80
+ const TENS = ['', '', 'dvadeset', 'trideset', 'četrdeset', 'pedeset', 'šezdeset', 'sedamdeset', 'osamdeset', 'devedeset']
81
+
82
+ // Croatian has irregular hundreds
83
+ const HUNDREDS = ['', 'sto', 'dvjesto', 'tristo', 'četiristo', 'petsto', 'šesto', 'sedamsto', 'osamsto', 'devetsto']
84
+
85
+ const ZERO = 'nula'
86
+ const NEGATIVE = 'minus'
87
+ const DECIMAL_SEP = 'zarez'
88
+
89
+ // Scale words: [singular, few, many]
90
+ // Thousands (index 0) are feminine, rest are masculine
91
+ const SCALE_FORMS = [
92
+ ['tisuća', 'tisuće', 'tisuća'],
93
+ ['milijun', 'milijuna', 'milijuna'],
94
+ ['milijarda', 'milijarde', 'milijarda'],
95
+ ['bilijun', 'bilijuna', 'bilijuna'],
96
+ ['bilijarda', 'bilijarde', 'bilijarda'],
97
+ ['trilijun', 'trilijuna', 'trilijuna'],
98
+ ['trilijarda', 'trilijarde', 'trilijarda'],
99
+ ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna'],
100
+ ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda']
101
+ ]
102
+
103
+ // ============================================================================
104
+ // Precomputed Lookup Tables
105
+ // ============================================================================
106
+
107
+ const { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)
108
+
109
+ // ============================================================================
110
+ // Conversion Functions
111
+ // ============================================================================
112
+
113
+ function integerToWords (n, options = {}) {
114
+ if (n === 0n) return ZERO
115
+
116
+ if (n < 1000n) {
117
+ const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
118
+ return segments[Number(n)]
87
119
  }
88
120
 
89
- /**
90
- * Maps segment indices to whether they are grammatically feminine.
91
- * In Croatian, thousands (index 1) are feminine, others are masculine.
92
- * @type {Object.<number, boolean>}
93
- */
94
- scaleGenders = {
95
- 1: true // thousands are feminine (others default to false)
121
+ return buildLargeNumberWords(n, options)
122
+ }
123
+
124
+ function buildLargeNumberWords (n, options) {
125
+ const numStr = n.toString()
126
+ const len = numStr.length
127
+
128
+ const segments = []
129
+ const segmentSize = 3
130
+
131
+ const remainderLen = len % segmentSize
132
+ let pos = 0
133
+ if (remainderLen > 0) {
134
+ segments.push(Number(numStr.slice(0, remainderLen)))
135
+ pos = remainderLen
136
+ }
137
+ while (pos < len) {
138
+ segments.push(Number(numStr.slice(pos, pos + segmentSize)))
139
+ pos += segmentSize
96
140
  }
97
141
 
98
- /** Selects Croatian plural form: 1 = singular, 2-4 = few, else = many. */
99
- pluralize (n, forms) {
100
- const lastDigit = n % 10n
101
- const lastTwoDigits = n % 100n
142
+ const parts = []
143
+ let scaleIndex = segments.length - 1
102
144
 
103
- if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {
104
- return forms[0]
105
- }
145
+ for (let i = 0; i < segments.length; i++) {
146
+ const segment = segments[i]
106
147
 
107
- if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {
108
- return forms[1]
148
+ if (segment !== 0) {
149
+ if (scaleIndex === 0) {
150
+ const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC
151
+ parts.push(segmentWords[segment])
152
+ } else {
153
+ const scaleForms = SCALE_FORMS[scaleIndex - 1]
154
+ const scaleWord = pluralize(segment, scaleForms)
155
+ // Thousands (scaleIndex=1) are feminine, others masculine
156
+ const isFeminine = scaleIndex === 1
157
+ const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC
158
+ parts.push(segmentWords[segment] + ' ' + scaleWord)
159
+ }
109
160
  }
110
161
 
111
- return forms[2]
162
+ scaleIndex--
163
+ }
164
+
165
+ return parts.join(' ')
166
+ }
167
+
168
+ function decimalPartToWords (decimalPart, options) {
169
+ let result = ''
170
+ let i = 0
171
+
172
+ while (i < decimalPart.length && decimalPart[i] === '0') {
173
+ if (result) result += ' '
174
+ result += ZERO
175
+ i++
176
+ }
177
+
178
+ const remainder = decimalPart.slice(i)
179
+ if (remainder) {
180
+ if (result) result += ' '
181
+ result += integerToWords(BigInt(remainder), options)
182
+ }
183
+
184
+ return result
185
+ }
186
+
187
+ /**
188
+ * Converts a numeric value to Croatian words.
189
+ *
190
+ * @param {number | string | bigint} value - The numeric value to convert
191
+ * @param {Object} [options] - Optional configuration
192
+ * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
193
+ * @returns {string} The number in Croatian words
194
+ */
195
+ function toWords (value, options) {
196
+ options = validateOptions(options)
197
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
198
+
199
+ let result = ''
200
+
201
+ if (isNegative) {
202
+ result = NEGATIVE + ' '
203
+ }
204
+
205
+ result += integerToWords(integerPart, options)
206
+
207
+ if (decimalPart) {
208
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)
112
209
  }
210
+
211
+ return result
113
212
  }
213
+
214
+ // ============================================================================
215
+ // Exports
216
+ // ============================================================================
217
+
218
+ export { toWords }