n2words 3.0.0 → 4.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 (488) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +1 -1
  3. package/README.md +64 -184
  4. package/dist/am-ET.js +2 -0
  5. package/dist/am-ET.umd.js +2 -0
  6. package/dist/am-Latn-ET.js +2 -0
  7. package/dist/am-Latn-ET.umd.js +2 -0
  8. package/dist/ar-SA.js +2 -0
  9. package/dist/ar-SA.umd.js +2 -0
  10. package/dist/az-AZ.js +2 -0
  11. package/dist/az-AZ.umd.js +2 -0
  12. package/dist/bn-BD.js +2 -0
  13. package/dist/bn-BD.umd.js +2 -0
  14. package/dist/cs-CZ.js +2 -0
  15. package/dist/cs-CZ.umd.js +2 -0
  16. package/dist/da-DK.js +2 -0
  17. package/dist/da-DK.umd.js +2 -0
  18. package/dist/de-DE.js +2 -0
  19. package/dist/de-DE.umd.js +2 -0
  20. package/dist/el-GR.js +2 -0
  21. package/dist/el-GR.umd.js +2 -0
  22. package/dist/en-AU.js +2 -0
  23. package/dist/en-AU.umd.js +2 -0
  24. package/dist/en-BD.js +2 -0
  25. package/dist/en-BD.umd.js +2 -0
  26. package/dist/en-CA.js +2 -0
  27. package/dist/en-CA.umd.js +2 -0
  28. package/dist/en-GB.js +2 -0
  29. package/dist/en-GB.umd.js +2 -0
  30. package/dist/en-GH.js +2 -0
  31. package/dist/en-GH.umd.js +2 -0
  32. package/dist/en-IE.js +2 -0
  33. package/dist/en-IE.umd.js +2 -0
  34. package/dist/en-IN.js +2 -0
  35. package/dist/en-IN.umd.js +2 -0
  36. package/dist/en-KE.js +2 -0
  37. package/dist/en-KE.umd.js +2 -0
  38. package/dist/en-MY.js +2 -0
  39. package/dist/en-MY.umd.js +2 -0
  40. package/dist/en-NG.js +2 -0
  41. package/dist/en-NG.umd.js +2 -0
  42. package/dist/en-NZ.js +2 -0
  43. package/dist/en-NZ.umd.js +2 -0
  44. package/dist/en-PH.js +2 -0
  45. package/dist/en-PH.umd.js +2 -0
  46. package/dist/en-PK.js +2 -0
  47. package/dist/en-PK.umd.js +2 -0
  48. package/dist/en-SG.js +2 -0
  49. package/dist/en-SG.umd.js +2 -0
  50. package/dist/en-US.js +2 -0
  51. package/dist/en-US.umd.js +2 -0
  52. package/dist/en-ZA.js +2 -0
  53. package/dist/en-ZA.umd.js +2 -0
  54. package/dist/es-ES.js +2 -0
  55. package/dist/es-ES.umd.js +2 -0
  56. package/dist/es-MX.js +2 -0
  57. package/dist/es-MX.umd.js +2 -0
  58. package/dist/es-US.js +2 -0
  59. package/dist/es-US.umd.js +2 -0
  60. package/dist/fa-IR.js +2 -0
  61. package/dist/fa-IR.umd.js +2 -0
  62. package/dist/fi-FI.js +2 -0
  63. package/dist/fi-FI.umd.js +2 -0
  64. package/dist/fil-PH.js +2 -0
  65. package/dist/fil-PH.umd.js +2 -0
  66. package/dist/fr-BE.js +2 -0
  67. package/dist/fr-BE.umd.js +2 -0
  68. package/dist/fr-FR.js +2 -0
  69. package/dist/fr-FR.umd.js +2 -0
  70. package/dist/gu-IN.js +2 -0
  71. package/dist/gu-IN.umd.js +2 -0
  72. package/dist/ha-NG.js +2 -0
  73. package/dist/ha-NG.umd.js +2 -0
  74. package/dist/hbo-IL.js +2 -0
  75. package/dist/hbo-IL.umd.js +2 -0
  76. package/dist/he-IL.js +2 -0
  77. package/dist/he-IL.umd.js +2 -0
  78. package/dist/hi-IN.js +2 -0
  79. package/dist/hi-IN.umd.js +2 -0
  80. package/dist/hr-HR.js +2 -0
  81. package/dist/hr-HR.umd.js +2 -0
  82. package/dist/hu-HU.js +2 -0
  83. package/dist/hu-HU.umd.js +2 -0
  84. package/dist/id-ID.js +2 -0
  85. package/dist/id-ID.umd.js +2 -0
  86. package/dist/it-IT.js +2 -0
  87. package/dist/it-IT.umd.js +2 -0
  88. package/dist/ja-JP.js +2 -0
  89. package/dist/ja-JP.umd.js +2 -0
  90. package/dist/ka-GE.js +2 -0
  91. package/dist/ka-GE.umd.js +2 -0
  92. package/dist/kn-IN.js +2 -0
  93. package/dist/kn-IN.umd.js +2 -0
  94. package/dist/ko-KR.js +2 -0
  95. package/dist/ko-KR.umd.js +2 -0
  96. package/dist/lt-LT.js +2 -0
  97. package/dist/lt-LT.umd.js +2 -0
  98. package/dist/lv-LV.js +2 -0
  99. package/dist/lv-LV.umd.js +2 -0
  100. package/dist/mr-IN.js +2 -0
  101. package/dist/mr-IN.umd.js +2 -0
  102. package/dist/ms-MY.js +2 -0
  103. package/dist/ms-MY.umd.js +2 -0
  104. package/dist/nb-NO.js +2 -0
  105. package/dist/nb-NO.umd.js +2 -0
  106. package/dist/nl-NL.js +2 -0
  107. package/dist/nl-NL.umd.js +2 -0
  108. package/dist/pa-IN.js +2 -0
  109. package/dist/pa-IN.umd.js +2 -0
  110. package/dist/pl-PL.js +2 -0
  111. package/dist/pl-PL.umd.js +2 -0
  112. package/dist/pt-PT.js +2 -0
  113. package/dist/pt-PT.umd.js +2 -0
  114. package/dist/ro-RO.js +2 -0
  115. package/dist/ro-RO.umd.js +2 -0
  116. package/dist/ru-RU.js +2 -0
  117. package/dist/ru-RU.umd.js +2 -0
  118. package/dist/sr-Cyrl-RS.js +2 -0
  119. package/dist/sr-Cyrl-RS.umd.js +2 -0
  120. package/dist/sr-Latn-RS.js +2 -0
  121. package/dist/sr-Latn-RS.umd.js +2 -0
  122. package/dist/sv-SE.js +2 -0
  123. package/dist/sv-SE.umd.js +2 -0
  124. package/dist/sw-KE.js +2 -0
  125. package/dist/sw-KE.umd.js +2 -0
  126. package/dist/ta-IN.js +2 -0
  127. package/dist/ta-IN.umd.js +2 -0
  128. package/dist/te-IN.js +2 -0
  129. package/dist/te-IN.umd.js +2 -0
  130. package/dist/th-TH.js +2 -0
  131. package/dist/th-TH.umd.js +2 -0
  132. package/dist/tr-TR.js +2 -0
  133. package/dist/tr-TR.umd.js +2 -0
  134. package/dist/uk-UA.js +2 -0
  135. package/dist/uk-UA.umd.js +2 -0
  136. package/dist/ur-PK.js +2 -0
  137. package/dist/ur-PK.umd.js +2 -0
  138. package/dist/vi-VN.js +2 -0
  139. package/dist/vi-VN.umd.js +2 -0
  140. package/dist/yo-NG.js +2 -0
  141. package/dist/yo-NG.umd.js +2 -0
  142. package/dist/zh-Hans-CN.js +2 -0
  143. package/dist/zh-Hans-CN.umd.js +2 -0
  144. package/dist/zh-Hant-TW.js +2 -0
  145. package/dist/zh-Hant-TW.umd.js +2 -0
  146. package/package.json +47 -82
  147. package/src/am-ET.d.ts +40 -0
  148. package/src/am-ET.js +269 -0
  149. package/src/am-Latn-ET.d.ts +35 -0
  150. package/src/am-Latn-ET.js +264 -0
  151. package/src/ar-SA.d.ts +49 -0
  152. package/{lib/languages/ar.js → src/ar-SA.js} +177 -15
  153. package/src/az-AZ.d.ts +37 -0
  154. package/src/az-AZ.js +312 -0
  155. package/src/bn-BD.d.ts +36 -0
  156. package/src/bn-BD.js +270 -0
  157. package/src/cs-CZ.d.ts +49 -0
  158. package/{lib/languages/cs.js → src/cs-CZ.js} +249 -40
  159. package/src/da-DK.d.ts +44 -0
  160. package/{lib/languages/da.js → src/da-DK.js} +136 -23
  161. package/src/de-DE.d.ts +57 -0
  162. package/src/de-DE.js +603 -0
  163. package/src/el-GR.d.ts +40 -0
  164. package/src/el-GR.js +418 -0
  165. package/src/en-AU.d.ts +47 -0
  166. package/src/en-AU.js +423 -0
  167. package/src/en-BD.d.ts +49 -0
  168. package/src/en-BD.js +415 -0
  169. package/src/en-CA.d.ts +63 -0
  170. package/src/en-CA.js +518 -0
  171. package/src/en-GB.d.ts +56 -0
  172. package/src/en-GB.js +469 -0
  173. package/src/en-GH.d.ts +11 -0
  174. package/src/en-GH.js +345 -0
  175. package/src/en-IE.d.ts +56 -0
  176. package/src/en-IE.js +479 -0
  177. package/src/en-IN.d.ts +49 -0
  178. package/src/en-IN.js +415 -0
  179. package/src/en-KE.d.ts +11 -0
  180. package/src/en-KE.js +345 -0
  181. package/src/en-MY.d.ts +11 -0
  182. package/src/en-MY.js +347 -0
  183. package/src/en-NG.d.ts +56 -0
  184. package/src/en-NG.js +479 -0
  185. package/src/en-NZ.d.ts +11 -0
  186. package/src/en-NZ.js +375 -0
  187. package/src/en-PH.d.ts +11 -0
  188. package/src/en-PH.js +345 -0
  189. package/src/en-PK.d.ts +49 -0
  190. package/src/en-PK.js +415 -0
  191. package/src/en-SG.d.ts +11 -0
  192. package/src/en-SG.js +345 -0
  193. package/src/en-US.d.ts +63 -0
  194. package/src/en-US.js +516 -0
  195. package/src/en-ZA.d.ts +56 -0
  196. package/src/en-ZA.js +478 -0
  197. package/src/es-ES.d.ts +65 -0
  198. package/src/es-ES.js +541 -0
  199. package/src/es-MX.d.ts +58 -0
  200. package/{lib/languages/es.js → src/es-MX.js} +237 -47
  201. package/src/es-US.d.ts +58 -0
  202. package/src/es-US.js +446 -0
  203. package/src/fa-IR.d.ts +38 -0
  204. package/src/fa-IR.js +246 -0
  205. package/src/fi-FI.d.ts +46 -0
  206. package/src/fi-FI.js +379 -0
  207. package/src/fil-PH.d.ts +37 -0
  208. package/{lib/languages/fil.js → src/fil-PH.js} +149 -24
  209. package/src/fr-BE.d.ts +49 -0
  210. package/src/fr-BE.js +453 -0
  211. package/src/fr-FR.d.ts +63 -0
  212. package/{lib/languages/fr.js → src/fr-FR.js} +200 -47
  213. package/src/gu-IN.d.ts +35 -0
  214. package/src/gu-IN.js +259 -0
  215. package/src/ha-NG.d.ts +37 -0
  216. package/{lib/languages/ha.js → src/ha-NG.js} +110 -16
  217. package/src/hbo-IL.d.ts +39 -0
  218. package/{lib/languages/hbo.js → src/hbo-IL.js} +217 -43
  219. package/src/he-IL.d.ts +37 -0
  220. package/src/he-IL.js +537 -0
  221. package/src/hi-IN.d.ts +36 -0
  222. package/src/hi-IN.js +280 -0
  223. package/src/hr-HR.d.ts +42 -0
  224. package/src/hr-HR.js +463 -0
  225. package/src/hu-HU.d.ts +38 -0
  226. package/{lib/languages/hu.js → src/hu-HU.js} +164 -6
  227. package/src/id-ID.d.ts +38 -0
  228. package/{lib/languages/id.js → src/id-ID.js} +106 -20
  229. package/src/it-IT.d.ts +59 -0
  230. package/src/it-IT.js +506 -0
  231. package/src/ja-JP.d.ts +49 -0
  232. package/{lib/languages/ja.js → src/ja-JP.js} +119 -32
  233. package/src/ka-GE.d.ts +44 -0
  234. package/src/ka-GE.js +393 -0
  235. package/src/kn-IN.d.ts +35 -0
  236. package/{lib/languages/kn.js → src/kn-IN.js} +156 -34
  237. package/src/ko-KR.d.ts +45 -0
  238. package/{lib/languages/ko.js → src/ko-KR.js} +99 -24
  239. package/src/lt-LT.d.ts +49 -0
  240. package/src/lt-LT.js +543 -0
  241. package/src/lv-LV.d.ts +49 -0
  242. package/src/lv-LV.js +595 -0
  243. package/src/mr-IN.d.ts +36 -0
  244. package/src/mr-IN.js +260 -0
  245. package/src/ms-MY.d.ts +37 -0
  246. package/{lib/languages/ms.js → src/ms-MY.js} +118 -20
  247. package/src/nb-NO.d.ts +44 -0
  248. package/{lib/languages/nb.js → src/nb-NO.js} +165 -33
  249. package/src/nl-NL.d.ts +54 -0
  250. package/{lib/languages/nl.js → src/nl-NL.js} +271 -47
  251. package/src/pa-IN.d.ts +36 -0
  252. package/src/pa-IN.js +268 -0
  253. package/src/pl-PL.d.ts +55 -0
  254. package/src/pl-PL.js +585 -0
  255. package/src/pt-PT.d.ts +45 -0
  256. package/src/pt-PT.js +514 -0
  257. package/src/ro-RO.d.ts +44 -0
  258. package/{lib/languages/ro.js → src/ro-RO.js} +212 -18
  259. package/src/ru-RU.d.ts +50 -0
  260. package/src/ru-RU.js +535 -0
  261. package/src/sr-Cyrl-RS.d.ts +49 -0
  262. package/src/sr-Cyrl-RS.js +503 -0
  263. package/src/sr-Latn-RS.d.ts +49 -0
  264. package/src/sr-Latn-RS.js +503 -0
  265. package/src/sv-SE.d.ts +44 -0
  266. package/{lib/languages/sv.js → src/sv-SE.js} +149 -34
  267. package/src/sw-KE.d.ts +37 -0
  268. package/{lib/languages/sw.js → src/sw-KE.js} +117 -6
  269. package/src/ta-IN.d.ts +35 -0
  270. package/{lib/languages/ta.js → src/ta-IN.js} +163 -47
  271. package/src/te-IN.d.ts +35 -0
  272. package/{lib/languages/te.js → src/te-IN.js} +147 -46
  273. package/src/th-TH.d.ts +38 -0
  274. package/{lib/languages/th.js → src/th-TH.js} +99 -6
  275. package/src/tr-TR.d.ts +48 -0
  276. package/src/tr-TR.js +397 -0
  277. package/src/uk-UA.d.ts +42 -0
  278. package/src/uk-UA.js +463 -0
  279. package/src/ur-PK.d.ts +36 -0
  280. package/src/ur-PK.js +268 -0
  281. package/src/utils/expand-scientific.d.ts +32 -0
  282. package/src/utils/expand-scientific.js +65 -0
  283. package/src/utils/parse-cardinal.d.ts +14 -0
  284. package/{lib/utils/parse-numeric.js → src/utils/parse-cardinal.js} +14 -44
  285. package/src/utils/parse-currency.d.ts +14 -0
  286. package/src/utils/parse-currency.js +91 -0
  287. package/src/utils/parse-ordinal.d.ts +10 -0
  288. package/src/utils/parse-ordinal.js +103 -0
  289. package/src/vi-VN.d.ts +48 -0
  290. package/{lib/languages/vi.js → src/vi-VN.js} +124 -53
  291. package/src/yo-NG.d.ts +37 -0
  292. package/src/yo-NG.js +403 -0
  293. package/src/zh-Hans-CN.d.ts +48 -0
  294. package/{lib/languages/zh-Hans.js → src/zh-Hans-CN.js} +140 -8
  295. package/src/zh-Hant-TW.d.ts +50 -0
  296. package/{lib/languages/zh-Hant.js → src/zh-Hant-TW.js} +139 -8
  297. package/dist/languages/am-Latn.js +0 -3
  298. package/dist/languages/am-Latn.js.map +0 -1
  299. package/dist/languages/am.js +0 -3
  300. package/dist/languages/am.js.map +0 -1
  301. package/dist/languages/ar.js +0 -3
  302. package/dist/languages/ar.js.map +0 -1
  303. package/dist/languages/az.js +0 -3
  304. package/dist/languages/az.js.map +0 -1
  305. package/dist/languages/bn.js +0 -3
  306. package/dist/languages/bn.js.map +0 -1
  307. package/dist/languages/cs.js +0 -3
  308. package/dist/languages/cs.js.map +0 -1
  309. package/dist/languages/da.js +0 -3
  310. package/dist/languages/da.js.map +0 -1
  311. package/dist/languages/de.js +0 -3
  312. package/dist/languages/de.js.map +0 -1
  313. package/dist/languages/el.js +0 -3
  314. package/dist/languages/el.js.map +0 -1
  315. package/dist/languages/en.js +0 -3
  316. package/dist/languages/en.js.map +0 -1
  317. package/dist/languages/es.js +0 -3
  318. package/dist/languages/es.js.map +0 -1
  319. package/dist/languages/fa.js +0 -3
  320. package/dist/languages/fa.js.map +0 -1
  321. package/dist/languages/fi.js +0 -3
  322. package/dist/languages/fi.js.map +0 -1
  323. package/dist/languages/fil.js +0 -3
  324. package/dist/languages/fil.js.map +0 -1
  325. package/dist/languages/fr-BE.js +0 -3
  326. package/dist/languages/fr-BE.js.map +0 -1
  327. package/dist/languages/fr.js +0 -3
  328. package/dist/languages/fr.js.map +0 -1
  329. package/dist/languages/gu.js +0 -3
  330. package/dist/languages/gu.js.map +0 -1
  331. package/dist/languages/ha.js +0 -3
  332. package/dist/languages/ha.js.map +0 -1
  333. package/dist/languages/hbo.js +0 -3
  334. package/dist/languages/hbo.js.map +0 -1
  335. package/dist/languages/he.js +0 -3
  336. package/dist/languages/he.js.map +0 -1
  337. package/dist/languages/hi.js +0 -3
  338. package/dist/languages/hi.js.map +0 -1
  339. package/dist/languages/hr.js +0 -3
  340. package/dist/languages/hr.js.map +0 -1
  341. package/dist/languages/hu.js +0 -3
  342. package/dist/languages/hu.js.map +0 -1
  343. package/dist/languages/id.js +0 -3
  344. package/dist/languages/id.js.map +0 -1
  345. package/dist/languages/it.js +0 -3
  346. package/dist/languages/it.js.map +0 -1
  347. package/dist/languages/ja.js +0 -3
  348. package/dist/languages/ja.js.map +0 -1
  349. package/dist/languages/kn.js +0 -3
  350. package/dist/languages/kn.js.map +0 -1
  351. package/dist/languages/ko.js +0 -3
  352. package/dist/languages/ko.js.map +0 -1
  353. package/dist/languages/lt.js +0 -3
  354. package/dist/languages/lt.js.map +0 -1
  355. package/dist/languages/lv.js +0 -3
  356. package/dist/languages/lv.js.map +0 -1
  357. package/dist/languages/mr.js +0 -3
  358. package/dist/languages/mr.js.map +0 -1
  359. package/dist/languages/ms.js +0 -3
  360. package/dist/languages/ms.js.map +0 -1
  361. package/dist/languages/nb.js +0 -3
  362. package/dist/languages/nb.js.map +0 -1
  363. package/dist/languages/nl.js +0 -3
  364. package/dist/languages/nl.js.map +0 -1
  365. package/dist/languages/pa.js +0 -3
  366. package/dist/languages/pa.js.map +0 -1
  367. package/dist/languages/pl.js +0 -3
  368. package/dist/languages/pl.js.map +0 -1
  369. package/dist/languages/pt.js +0 -3
  370. package/dist/languages/pt.js.map +0 -1
  371. package/dist/languages/ro.js +0 -3
  372. package/dist/languages/ro.js.map +0 -1
  373. package/dist/languages/ru.js +0 -3
  374. package/dist/languages/ru.js.map +0 -1
  375. package/dist/languages/sr-Cyrl.js +0 -3
  376. package/dist/languages/sr-Cyrl.js.map +0 -1
  377. package/dist/languages/sr-Latn.js +0 -3
  378. package/dist/languages/sr-Latn.js.map +0 -1
  379. package/dist/languages/sv.js +0 -3
  380. package/dist/languages/sv.js.map +0 -1
  381. package/dist/languages/sw.js +0 -3
  382. package/dist/languages/sw.js.map +0 -1
  383. package/dist/languages/ta.js +0 -3
  384. package/dist/languages/ta.js.map +0 -1
  385. package/dist/languages/te.js +0 -3
  386. package/dist/languages/te.js.map +0 -1
  387. package/dist/languages/th.js +0 -3
  388. package/dist/languages/th.js.map +0 -1
  389. package/dist/languages/tr.js +0 -3
  390. package/dist/languages/tr.js.map +0 -1
  391. package/dist/languages/uk.js +0 -3
  392. package/dist/languages/uk.js.map +0 -1
  393. package/dist/languages/ur.js +0 -3
  394. package/dist/languages/ur.js.map +0 -1
  395. package/dist/languages/vi.js +0 -3
  396. package/dist/languages/vi.js.map +0 -1
  397. package/dist/languages/zh-Hans.js +0 -3
  398. package/dist/languages/zh-Hans.js.map +0 -1
  399. package/dist/languages/zh-Hant.js +0 -3
  400. package/dist/languages/zh-Hant.js.map +0 -1
  401. package/dist/n2words.js +0 -3
  402. package/dist/n2words.js.map +0 -1
  403. package/lib/languages/am-Latn.d.ts +0 -7
  404. package/lib/languages/am-Latn.js +0 -164
  405. package/lib/languages/am.d.ts +0 -7
  406. package/lib/languages/am.js +0 -164
  407. package/lib/languages/ar.d.ts +0 -17
  408. package/lib/languages/az.d.ts +0 -7
  409. package/lib/languages/az.js +0 -176
  410. package/lib/languages/bn.d.ts +0 -7
  411. package/lib/languages/bn.js +0 -145
  412. package/lib/languages/cs.d.ts +0 -18
  413. package/lib/languages/da.d.ts +0 -14
  414. package/lib/languages/de.d.ts +0 -17
  415. package/lib/languages/de.js +0 -332
  416. package/lib/languages/el.d.ts +0 -14
  417. package/lib/languages/el.js +0 -243
  418. package/lib/languages/en.d.ts +0 -17
  419. package/lib/languages/en.js +0 -256
  420. package/lib/languages/es.d.ts +0 -21
  421. package/lib/languages/fa.d.ts +0 -7
  422. package/lib/languages/fa.js +0 -134
  423. package/lib/languages/fi.d.ts +0 -14
  424. package/lib/languages/fi.js +0 -245
  425. package/lib/languages/fil.d.ts +0 -7
  426. package/lib/languages/fr-BE.d.ts +0 -11
  427. package/lib/languages/fr-BE.js +0 -300
  428. package/lib/languages/fr.d.ts +0 -21
  429. package/lib/languages/gu.d.ts +0 -7
  430. package/lib/languages/gu.js +0 -137
  431. package/lib/languages/ha.d.ts +0 -7
  432. package/lib/languages/hbo.d.ts +0 -13
  433. package/lib/languages/he.d.ts +0 -13
  434. package/lib/languages/he.js +0 -276
  435. package/lib/languages/hi.d.ts +0 -7
  436. package/lib/languages/hi.js +0 -145
  437. package/lib/languages/hr.d.ts +0 -11
  438. package/lib/languages/hr.js +0 -218
  439. package/lib/languages/hu.d.ts +0 -7
  440. package/lib/languages/id.d.ts +0 -7
  441. package/lib/languages/it.d.ts +0 -19
  442. package/lib/languages/it.js +0 -377
  443. package/lib/languages/ja.d.ts +0 -17
  444. package/lib/languages/kn.d.ts +0 -7
  445. package/lib/languages/ko.d.ts +0 -14
  446. package/lib/languages/lt.d.ts +0 -18
  447. package/lib/languages/lt.js +0 -310
  448. package/lib/languages/lv.d.ts +0 -18
  449. package/lib/languages/lv.js +0 -321
  450. package/lib/languages/mr.d.ts +0 -7
  451. package/lib/languages/mr.js +0 -137
  452. package/lib/languages/ms.d.ts +0 -7
  453. package/lib/languages/nb.d.ts +0 -14
  454. package/lib/languages/nl.d.ts +0 -26
  455. package/lib/languages/pa.d.ts +0 -7
  456. package/lib/languages/pa.js +0 -163
  457. package/lib/languages/pl.d.ts +0 -22
  458. package/lib/languages/pl.js +0 -330
  459. package/lib/languages/pt.d.ts +0 -17
  460. package/lib/languages/pt.js +0 -306
  461. package/lib/languages/ro.d.ts +0 -18
  462. package/lib/languages/ru.d.ts +0 -11
  463. package/lib/languages/ru.js +0 -240
  464. package/lib/languages/sr-Cyrl.d.ts +0 -11
  465. package/lib/languages/sr-Cyrl.js +0 -215
  466. package/lib/languages/sr-Latn.d.ts +0 -11
  467. package/lib/languages/sr-Latn.js +0 -215
  468. package/lib/languages/sv.d.ts +0 -14
  469. package/lib/languages/sw.d.ts +0 -7
  470. package/lib/languages/ta.d.ts +0 -7
  471. package/lib/languages/te.d.ts +0 -7
  472. package/lib/languages/th.d.ts +0 -7
  473. package/lib/languages/tr.d.ts +0 -18
  474. package/lib/languages/tr.js +0 -263
  475. package/lib/languages/uk.d.ts +0 -11
  476. package/lib/languages/uk.js +0 -218
  477. package/lib/languages/ur.d.ts +0 -7
  478. package/lib/languages/ur.js +0 -163
  479. package/lib/languages/vi.d.ts +0 -17
  480. package/lib/languages/zh-Hans.d.ts +0 -11
  481. package/lib/languages/zh-Hant.d.ts +0 -11
  482. package/lib/n2words.d.ts +0 -53
  483. package/lib/n2words.js +0 -122
  484. package/lib/utils/parse-numeric.d.ts +0 -17
  485. /package/{lib → src}/utils/is-plain-object.d.ts +0 -0
  486. /package/{lib → src}/utils/is-plain-object.js +0 -0
  487. /package/{lib → src}/utils/validate-options.d.ts +0 -0
  488. /package/{lib → src}/utils/validate-options.js +0 -0
@@ -1,13 +1,9 @@
1
1
  /**
2
- * French language converter - Functional Implementation
2
+ * French (France) language converter
3
3
  *
4
- * A performance-optimized number-to-words converter using precomputed lookup tables.
5
- * Self-contained module with its own input validation, ready for subpath exports.
4
+ * CLDR: fr-FR | French as used in France
6
5
  *
7
- * Key optimization: Precompute all segment values (0-999) at module load.
8
- * This eliminates all per-call string manipulation for segment conversion.
9
- *
10
- * French-specific rules (handled in precomputation):
6
+ * French-specific rules:
11
7
  * - Vigesimal patterns: 70 = soixante-dix, 80 = quatre-vingts, 90 = quatre-vingt-dix
12
8
  * - "et" conjunction: vingt et un (21), soixante et onze (71), but NOT quatre-vingt-un
13
9
  * - Pluralization: "cents" loses 's' when followed by more digits
@@ -15,8 +11,10 @@
15
11
  * - Omit "un" before mille
16
12
  */
17
13
 
18
- import { parseNumericValue } from '../utils/parse-numeric.js'
19
- import { validateOptions } from '../utils/validate-options.js'
14
+ import { parseCardinalValue } from './utils/parse-cardinal.js'
15
+ import { parseCurrencyValue } from './utils/parse-currency.js'
16
+ import { parseOrdinalValue } from './utils/parse-ordinal.js'
17
+ import { validateOptions } from './utils/validate-options.js'
20
18
 
21
19
  // ============================================================================
22
20
  // Vocabulary (module-level constants)
@@ -37,7 +35,26 @@ const NEGATIVE = 'moins'
37
35
  const DECIMAL_SEP = 'virgule'
38
36
 
39
37
  // ============================================================================
40
- // Precomputed Lookup Tables (built once at module load)
38
+ // Ordinal Vocabulary
39
+ // ============================================================================
40
+
41
+ // Ordinal suffix
42
+ const ORDINAL_SUFFIX = 'ième'
43
+
44
+ // Special ordinals
45
+ const PREMIER = 'premier'
46
+
47
+ // ============================================================================
48
+ // Currency Vocabulary (Euro)
49
+ // ============================================================================
50
+
51
+ const EURO = 'euro'
52
+ const EUROS = 'euros'
53
+ const CENTIME = 'centime'
54
+ const CENTIMES = 'centimes'
55
+
56
+ // ============================================================================
57
+ // Segment Building
41
58
  // ============================================================================
42
59
 
43
60
  /**
@@ -48,7 +65,7 @@ function buildSegment (n) {
48
65
  if (n === 0) return { word: '', endsWithCents: false, endsWithVingts: false }
49
66
 
50
67
  const tensOnes = n % 100
51
- const hundreds = Math.floor(n / 100)
68
+ const hundreds = Math.trunc(n / 100)
52
69
 
53
70
  const parts = []
54
71
  let endsWithCents = false
@@ -88,7 +105,7 @@ function buildSegment (n) {
88
105
  parts.push(TEENS[tensOnes - 10])
89
106
  } else if (tensOnes < 70) {
90
107
  // 20-69: standard tens + ones
91
- const t = Math.floor(tensOnes / 10)
108
+ const t = Math.trunc(tensOnes / 10)
92
109
  const o = tensOnes % 10
93
110
  if (o === 0) {
94
111
  parts.push(TENS[t])
@@ -128,18 +145,6 @@ function buildSegment (n) {
128
145
  return { word: parts.join(' '), endsWithCents, endsWithVingts }
129
146
  }
130
147
 
131
- // Precompute all 1000 segment words (0-999)
132
- const SEGMENTS = new Array(1000)
133
- const SEGMENTS_ENDS_CENTS = new Array(1000)
134
- const SEGMENTS_ENDS_VINGTS = new Array(1000)
135
-
136
- for (let i = 0; i < 1000; i++) {
137
- const result = buildSegment(i)
138
- SEGMENTS[i] = result.word
139
- SEGMENTS_ENDS_CENTS[i] = result.endsWithCents
140
- SEGMENTS_ENDS_VINGTS[i] = result.endsWithVingts
141
- }
142
-
143
148
  // ============================================================================
144
149
  // Helper Functions
145
150
  // ============================================================================
@@ -183,9 +188,9 @@ function getScaleWord (scaleIndex, segment) {
183
188
  function integerToWords (n, withHyphen = false) {
184
189
  if (n === 0n) return ZERO
185
190
 
186
- // Fast path: numbers < 1000 (direct lookup)
191
+ // Fast path: numbers < 1000
187
192
  if (n < 1000n) {
188
- const word = SEGMENTS[Number(n)]
193
+ const { word } = buildSegment(Number(n))
189
194
  return withHyphen ? word.replace(/ /g, '-') : word
190
195
  }
191
196
 
@@ -200,15 +205,17 @@ function integerToWords (n, withHyphen = false) {
200
205
  result = THOUSAND
201
206
  } else {
202
207
  // Check if segment ends with "cents" or "vingts" - need to strip 's' before mille
203
- let thousandsWord = SEGMENTS[thousands]
204
- if (SEGMENTS_ENDS_CENTS[thousands] || SEGMENTS_ENDS_VINGTS[thousands]) {
205
- thousandsWord = thousandsWord.slice(0, -1) // Remove trailing 's'
208
+ const { word: thousandsWord, endsWithCents, endsWithVingts } = buildSegment(thousands)
209
+ let adjustedWord = thousandsWord
210
+ if (endsWithCents || endsWithVingts) {
211
+ adjustedWord = thousandsWord.slice(0, -1) // Remove trailing 's'
206
212
  }
207
- result = thousandsWord + (withHyphen ? '-' : ' ') + THOUSAND
213
+ result = adjustedWord + (withHyphen ? '-' : ' ') + THOUSAND
208
214
  }
209
215
 
210
216
  if (remainder > 0) {
211
- result += (withHyphen ? '-' : ' ') + SEGMENTS[remainder]
217
+ const { word: remainderWord } = buildSegment(remainder)
218
+ result += (withHyphen ? '-' : ' ') + remainderWord
212
219
  }
213
220
 
214
221
  if (withHyphen) {
@@ -257,26 +264,27 @@ function buildLargeNumberWords (n, withHyphen) {
257
264
 
258
265
  if (segment !== 0) {
259
266
  const scaleWord = scaleIndex > 0 ? getScaleWord(scaleIndex, BigInt(segment)) : ''
267
+ const { word: segWords, endsWithCents, endsWithVingts } = buildSegment(segment)
260
268
 
261
269
  if (scaleIndex === 0) {
262
270
  // Units segment
263
- parts.push(SEGMENTS[segment])
271
+ parts.push(segWords)
264
272
  } else if (scaleIndex === 1) {
265
273
  // Thousands: "mille" not "un mille"
266
274
  if (segment === 1) {
267
275
  parts.push(THOUSAND)
268
276
  } else {
269
- let segWords = SEGMENTS[segment]
270
277
  // Strip 's' from cents/vingts before mille
271
- if (SEGMENTS_ENDS_CENTS[segment] || SEGMENTS_ENDS_VINGTS[segment]) {
272
- segWords = segWords.slice(0, -1)
278
+ let adjustedWord = segWords
279
+ if (endsWithCents || endsWithVingts) {
280
+ adjustedWord = segWords.slice(0, -1)
273
281
  }
274
- parts.push(segWords)
282
+ parts.push(adjustedWord)
275
283
  parts.push(scaleWord)
276
284
  }
277
285
  } else {
278
286
  // Million and above
279
- parts.push(SEGMENTS[segment])
287
+ parts.push(segWords)
280
288
  parts.push(scaleWord)
281
289
  }
282
290
  }
@@ -337,26 +345,171 @@ function decimalPartToWords (decimalPart, withHyphen) {
337
345
  * @throws {Error} If value is not a valid number format
338
346
  *
339
347
  * @example
340
- * toWords(21) // 'vingt et un'
341
- * toWords(80) // 'quatre-vingts'
342
- * toWords(1000000) // 'un million'
348
+ * toCardinal(21) // 'vingt et un'
349
+ * toCardinal(80) // 'quatre-vingts'
350
+ * toCardinal(1000000) // 'un million'
343
351
  */
344
- function toWords (value, options) {
352
+ function toCardinal (value, options) {
345
353
  options = validateOptions(options)
346
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
347
- const withHyphen = options.withHyphenSeparator || false
354
+ const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
355
+
356
+ // Apply option defaults
357
+ const { withHyphenSeparator = false } = options
348
358
 
349
359
  let result = ''
350
- const sep = withHyphen ? '-' : ' '
360
+ const sep = withHyphenSeparator ? '-' : ' '
351
361
 
352
362
  if (isNegative) {
353
363
  result = NEGATIVE + sep
354
364
  }
355
365
 
356
- result += integerToWords(integerPart, withHyphen)
366
+ result += integerToWords(integerPart, withHyphenSeparator)
357
367
 
358
368
  if (decimalPart) {
359
- result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, withHyphen)
369
+ result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, withHyphenSeparator)
370
+ }
371
+
372
+ return result
373
+ }
374
+
375
+ // ============================================================================
376
+ // ORDINAL: toOrdinal(value)
377
+ // ============================================================================
378
+
379
+ /**
380
+ * Converts a cardinal number word to its ordinal form.
381
+ * Rules:
382
+ * - 1 → premier (special case)
383
+ * - Drop final -e before adding -ième (quatre → quatrième)
384
+ * - cinq → cinquième (add -u- before -ième)
385
+ * - neuf → neuvième (f → v before -ième)
386
+ *
387
+ * @param {string} cardinalWord - Cardinal word to convert
388
+ * @returns {string} Ordinal form
389
+ */
390
+ function cardinalToOrdinal (cardinalWord) {
391
+ // Handle special endings
392
+ if (cardinalWord.endsWith('cinq')) {
393
+ // cinq → cinquième (add 'u')
394
+ return cardinalWord + 'u' + ORDINAL_SUFFIX
395
+ }
396
+
397
+ if (cardinalWord.endsWith('neuf')) {
398
+ // neuf → neuvième (f → v)
399
+ return cardinalWord.slice(0, -1) + 'v' + ORDINAL_SUFFIX
400
+ }
401
+
402
+ // Drop plural -s from cents/vingts/millions/etc. (quatre-vingts → quatre-vingtième)
403
+ // Note: "trois", "six" also end in s but that's not a plural
404
+ if (cardinalWord.endsWith('cents') ||
405
+ cardinalWord.endsWith('vingts') ||
406
+ cardinalWord.endsWith('millions') ||
407
+ cardinalWord.endsWith('milliards') ||
408
+ cardinalWord.endsWith('billions') ||
409
+ cardinalWord.endsWith('billiards') ||
410
+ cardinalWord.endsWith('trillions') ||
411
+ cardinalWord.endsWith('trilliards') ||
412
+ cardinalWord.endsWith('quadrillions') ||
413
+ cardinalWord.endsWith('quadrilliards')) {
414
+ return cardinalWord.slice(0, -1) + ORDINAL_SUFFIX
415
+ }
416
+
417
+ // Drop final -e before adding -ième (quatre → quatrième)
418
+ if (cardinalWord.endsWith('e')) {
419
+ return cardinalWord.slice(0, -1) + ORDINAL_SUFFIX
420
+ }
421
+
422
+ // Default: just add -ième
423
+ return cardinalWord + ORDINAL_SUFFIX
424
+ }
425
+
426
+ /**
427
+ * Converts a positive integer to French ordinal words.
428
+ *
429
+ * @param {bigint} n - Positive integer
430
+ * @returns {string} French ordinal words
431
+ */
432
+ function integerToOrdinal (n) {
433
+ // Special case: 1 → premier
434
+ if (n === 1n) {
435
+ return PREMIER
436
+ }
437
+
438
+ // Get cardinal form and convert to ordinal
439
+ const cardinalWord = integerToWords(n, false)
440
+ return cardinalToOrdinal(cardinalWord)
441
+ }
442
+
443
+ /**
444
+ * Converts a numeric value to French ordinal words.
445
+ *
446
+ * French ordinals: premier (1st), then cardinal + ième.
447
+ * Special rules: quatre→quatrième, cinq→cinquième, neuf→neuvième.
448
+ *
449
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
450
+ * @returns {string} The number as ordinal words
451
+ * @throws {TypeError} If value is not a valid numeric type
452
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
453
+ *
454
+ * @example
455
+ * toOrdinal(1) // 'premier'
456
+ * toOrdinal(2) // 'deuxième'
457
+ * toOrdinal(4) // 'quatrième'
458
+ * toOrdinal(5) // 'cinquième'
459
+ * toOrdinal(9) // 'neuvième'
460
+ * toOrdinal(21) // 'vingt et unième'
461
+ * toOrdinal(100) // 'centième'
462
+ * toOrdinal(1000) // 'millième'
463
+ */
464
+ function toOrdinal (value) {
465
+ const integerPart = parseOrdinalValue(value)
466
+ return integerToOrdinal(integerPart)
467
+ }
468
+
469
+ // ============================================================================
470
+ // CURRENCY: toCurrency(value, options?)
471
+ // ============================================================================
472
+
473
+ /**
474
+ * Converts a numeric value to French currency words (Euro).
475
+ *
476
+ * @param {number | string | bigint} value - The currency amount to convert
477
+ * @param {Object} [options] - Optional configuration
478
+ * @param {boolean} [options.and=true] - Use "et" between euros and centimes
479
+ * @returns {string} The amount in French currency words
480
+ * @throws {TypeError} If value is not a valid numeric type
481
+ * @throws {Error} If value is not a valid number format
482
+ *
483
+ * @example
484
+ * toCurrency(42.50) // 'quarante-deux euros et cinquante centimes'
485
+ * toCurrency(1) // 'un euro'
486
+ * toCurrency(0.99) // 'quatre-vingt-dix-neuf centimes'
487
+ * toCurrency(0.01) // 'un centime'
488
+ * toCurrency(42.50, { and: false }) // 'quarante-deux euros cinquante centimes'
489
+ */
490
+ function toCurrency (value, options) {
491
+ options = validateOptions(options)
492
+ const { isNegative, dollars: euros, cents: centimes } = parseCurrencyValue(value)
493
+ const { and: useAnd = true } = options
494
+
495
+ // Build result
496
+ let result = ''
497
+ if (isNegative) result = NEGATIVE + ' '
498
+
499
+ // Euros part
500
+ if (euros > 0n || centimes === 0n) {
501
+ result += integerToWords(euros, false)
502
+ // In French, 0 and 1 are singular: "zéro euro", "un euro"
503
+ result += ' ' + (euros <= 1n ? EURO : EUROS)
504
+ }
505
+
506
+ // Centimes part
507
+ if (centimes > 0n) {
508
+ if (euros > 0n) {
509
+ result += useAnd ? ' et ' : ' '
510
+ }
511
+ result += integerToWords(centimes, false)
512
+ result += ' ' + (centimes === 1n ? CENTIME : CENTIMES)
360
513
  }
361
514
 
362
515
  return result
@@ -366,4 +519,4 @@ function toWords (value, options) {
366
519
  // Public API
367
520
  // ============================================================================
368
521
 
369
- export { toWords }
522
+ export { toCardinal, toOrdinal, toCurrency }
package/src/gu-IN.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Converts a numeric value to Gujarati words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Gujarati words
6
+ */
7
+ export function toCardinal(value: number | string | bigint): string;
8
+ /**
9
+ * Converts a numeric value to Gujarati ordinal words.
10
+ *
11
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
12
+ * @returns {string} The number as ordinal words
13
+ * @throws {TypeError} If value is not a valid numeric type
14
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
15
+ *
16
+ * @example
17
+ * toOrdinal(1) // 'પહેલું'
18
+ * toOrdinal(2) // 'બીજું'
19
+ * toOrdinal(10) // 'દસમું'
20
+ */
21
+ export function toOrdinal(value: number | string | bigint): string;
22
+ /**
23
+ * Converts a numeric value to Gujarati currency words (Indian Rupee).
24
+ *
25
+ * @param {number | string | bigint} value - The currency amount to convert
26
+ * @returns {string} The amount in Gujarati currency words
27
+ * @throws {TypeError} If value is not a valid numeric type
28
+ * @throws {Error} If value is not a valid number format
29
+ *
30
+ * @example
31
+ * toCurrency(42.50) // 'બેતાળીસ રૂપિયા પચાસ પૈસા'
32
+ * toCurrency(1) // 'એક રૂપિયો'
33
+ * toCurrency(0.01) // 'એક પૈસો'
34
+ */
35
+ export function toCurrency(value: number | string | bigint): string;
package/src/gu-IN.js ADDED
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Gujarati (India) language converter
3
+ *
4
+ * CLDR: gu-IN | Gujarati as used in India
5
+ *
6
+ * Key features:
7
+ * - Indian numbering system (હજાર, લાખ, કરોડ)
8
+ * - Gujarati script
9
+ * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)
10
+ * - Complete word forms for 0-99
11
+ * - Per-digit decimal reading
12
+ */
13
+
14
+ import { parseCardinalValue } from './utils/parse-cardinal.js'
15
+ import { parseCurrencyValue } from './utils/parse-currency.js'
16
+ import { parseOrdinalValue } from './utils/parse-ordinal.js'
17
+
18
+ // ============================================================================
19
+ // Vocabulary
20
+ // ============================================================================
21
+
22
+ const ZERO = 'શૂન્ય'
23
+ const NEGATIVE = 'ઋણ'
24
+ const DECIMAL_SEP = 'દશાંશ'
25
+ const HUNDRED = 'સો'
26
+
27
+ // ============================================================================
28
+ // Ordinal Vocabulary
29
+ // ============================================================================
30
+
31
+ // Ordinal suffix (adds to cardinal for numbers >= 7)
32
+ const ORDINAL_SUFFIX = 'મું'
33
+
34
+ // Special ordinals for first few numbers (1-6 have irregular forms)
35
+ const ORDINAL_SPECIAL = ['', 'પહેલું', 'બીજું', 'ત્રીજું', 'ચોથું', 'પાંચમું', 'છઠ્ઠું']
36
+
37
+ // ============================================================================
38
+ // Currency Vocabulary (Indian Rupee)
39
+ // ============================================================================
40
+
41
+ // Rupee: singular/plural
42
+ const RUPEE = 'રૂપિયો'
43
+ const RUPEES = 'રૂપિયા'
44
+
45
+ // Paisa: singular/plural
46
+ const PAISA = 'પૈસો'
47
+ const PAISE = 'પૈસા'
48
+
49
+ const BELOW_HUNDRED = [
50
+ 'શૂન્ય', 'એક', 'બે', 'ત્રણ', 'ચાર', 'પાંચ', 'છ', 'સાત', 'આઠ', 'નવ',
51
+ 'દસ', 'અગિયાર', 'બાર', 'તેર', 'ચૌદ', 'પંદર', 'સોળ', 'સત્તર', 'અઢાર', 'ઓગણીસ',
52
+ 'વીસ', 'એકવીસ', 'બાવીસ', 'ત્રેવીસ', 'ચોવીસ', 'પચીસ', 'છવ્વીસ', 'સત્તાવીસ', 'અઠ્ઠાવીસ', 'ઓગણત્રીસ',
53
+ 'ત્રીસ', 'એકત્રીસ', 'બત્રીસ', 'તેત્રીસ', 'ચોત્રીસ', 'પાંત્રીસ', 'છત્રીસ', 'સાડત્રીસ', 'અડત્રીસ', 'ઓગણચાલીસ',
54
+ 'ચાલીસ', 'એકતાલીસ', 'બેતાળીસ', 'ત્રેતાળીસ', 'ચુંમાલીસ', 'પિસ્તાલીસ', 'છેતાળીસ', 'સુડતાળીસ', 'અડતાળીસ', 'ઓગણપચાસ',
55
+ 'પચાસ', 'એકાવન', 'બાવન', 'ત્રેપન', 'ચોપન', 'પંચાવન', 'છપ્પન', 'સત્તાવન', 'અઠ્ઠાવન', 'ઓગણસાઠ',
56
+ 'સાઠ', 'એકસઠ', 'બાસઠ', 'ત્રેસઠ', 'ચોસઠ', 'પાંસઠ', 'છાસઠ', 'સડસઠ', 'અડસઠ', 'અગણોસિત્તેર',
57
+ 'સિત્તેર', 'એકોતેર', 'બોતેર', 'તોતેર', 'ચુમોતેર', 'પંચોતેર', 'છોતેર', 'સિત્યોતેર', 'ઇઠ્યોતેર', 'ઓગણાએંસી',
58
+ 'એંસી', 'એક્યાસી', 'બ્યાસી', 'ત્યાસી', 'ચોર્યાસી', 'પંચાસી', 'છ્યાસી', 'સિત્યાસી', 'અઠ્યાસી', 'નેવ્યાસી',
59
+ 'નેવું', 'એકાણું', 'બાણું', 'ત્રાણું', 'ચોરાણું', 'પંચાણું', 'છન્નું', 'સત્તાણું', 'અઠ્ઠાણું', 'નવ્વાણું'
60
+ ]
61
+
62
+ // Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.
63
+ const SCALE_WORDS = ['', 'હજાર', 'લાખ', 'કરોડ', 'અબજ', 'ખરબ', 'નીલ', 'પદ્મ', 'શંખ']
64
+
65
+ // ============================================================================
66
+ // Segment Building
67
+ // ============================================================================
68
+
69
+ /**
70
+ * Builds words for a 0-999 segment.
71
+ */
72
+ function buildSegment (n) {
73
+ if (n === 0) return ''
74
+ if (n < 100) return BELOW_HUNDRED[n]
75
+
76
+ const hundreds = Math.trunc(n / 100)
77
+ const remainder = n % 100
78
+
79
+ if (remainder === 0) {
80
+ return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED
81
+ }
82
+ return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]
83
+ }
84
+
85
+ // ============================================================================
86
+ // Conversion Functions
87
+ // ============================================================================
88
+
89
+ /**
90
+ * Converts a non-negative integer to Gujarati words.
91
+ *
92
+ * Uses BigInt modulo for segment extraction (faster than string slicing).
93
+ * South Asian 3-2-2 grouping: first 3 digits, then groups of 2.
94
+ *
95
+ * @param {bigint} n - Non-negative integer to convert
96
+ * @returns {string} Gujarati words
97
+ */
98
+ function integerToWords (n) {
99
+ if (n === 0n) return ZERO
100
+
101
+ // Fast path: numbers < 1000 (direct lookup)
102
+ if (n < 1000n) {
103
+ return buildSegment(Number(n))
104
+ }
105
+
106
+ // Extract segments using BigInt modulo
107
+ const segments = []
108
+ segments.push(Number(n % 1000n))
109
+ let temp = n / 1000n
110
+
111
+ while (temp > 0n) {
112
+ segments.push(Number(temp % 100n))
113
+ temp = temp / 100n
114
+ }
115
+
116
+ // Build result string (process from most-significant to least)
117
+ const words = []
118
+ for (let i = segments.length - 1; i >= 0; i--) {
119
+ const segment = segments[i]
120
+ if (segment === 0) continue
121
+
122
+ if (i === 0) {
123
+ words.push(buildSegment(segment))
124
+ } else {
125
+ words.push(BELOW_HUNDRED[segment])
126
+ }
127
+
128
+ if (i > 0 && SCALE_WORDS[i]) {
129
+ words.push(SCALE_WORDS[i])
130
+ }
131
+ }
132
+
133
+ return words.join(' ')
134
+ }
135
+
136
+ function decimalPartToWords (decimalPart) {
137
+ // Per-digit decimal reading
138
+ const digits = []
139
+ for (const char of decimalPart) {
140
+ const d = parseInt(char, 10)
141
+ digits.push(d === 0 ? ZERO : BELOW_HUNDRED[d])
142
+ }
143
+ return digits.join(' ')
144
+ }
145
+
146
+ /**
147
+ * Converts a numeric value to Gujarati words.
148
+ *
149
+ * @param {number | string | bigint} value - The numeric value to convert
150
+ * @returns {string} The number in Gujarati words
151
+ */
152
+ function toCardinal (value) {
153
+ const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
154
+
155
+ let result = ''
156
+
157
+ if (isNegative) {
158
+ result = NEGATIVE + ' '
159
+ }
160
+
161
+ result += integerToWords(integerPart)
162
+
163
+ if (decimalPart) {
164
+ result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
165
+ }
166
+
167
+ return result
168
+ }
169
+
170
+ // ============================================================================
171
+ // ORDINAL: toOrdinal(value)
172
+ // ============================================================================
173
+
174
+ /**
175
+ * Converts a positive integer to Gujarati ordinal words.
176
+ *
177
+ * Gujarati ordinals: First 6 are irregular, then add -મું suffix.
178
+ *
179
+ * @param {bigint} n - Positive integer to convert
180
+ * @returns {string} Gujarati ordinal words
181
+ */
182
+ function integerToOrdinal (n) {
183
+ // Special ordinals for 1-6
184
+ if (n >= 1n && n <= 6n) {
185
+ return ORDINAL_SPECIAL[Number(n)]
186
+ }
187
+
188
+ // For 7 and above, add suffix to cardinal
189
+ const cardinal = integerToWords(n)
190
+ return cardinal + ORDINAL_SUFFIX
191
+ }
192
+
193
+ /**
194
+ * Converts a numeric value to Gujarati ordinal words.
195
+ *
196
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
197
+ * @returns {string} The number as ordinal words
198
+ * @throws {TypeError} If value is not a valid numeric type
199
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
200
+ *
201
+ * @example
202
+ * toOrdinal(1) // 'પહેલું'
203
+ * toOrdinal(2) // 'બીજું'
204
+ * toOrdinal(10) // 'દસમું'
205
+ */
206
+ function toOrdinal (value) {
207
+ const integerPart = parseOrdinalValue(value)
208
+ return integerToOrdinal(integerPart)
209
+ }
210
+
211
+ // ============================================================================
212
+ // CURRENCY: toCurrency(value, options?)
213
+ // ============================================================================
214
+
215
+ /**
216
+ * Converts a numeric value to Gujarati currency words (Indian Rupee).
217
+ *
218
+ * @param {number | string | bigint} value - The currency amount to convert
219
+ * @returns {string} The amount in Gujarati currency words
220
+ * @throws {TypeError} If value is not a valid numeric type
221
+ * @throws {Error} If value is not a valid number format
222
+ *
223
+ * @example
224
+ * toCurrency(42.50) // 'બેતાળીસ રૂપિયા પચાસ પૈસા'
225
+ * toCurrency(1) // 'એક રૂપિયો'
226
+ * toCurrency(0.01) // 'એક પૈસો'
227
+ */
228
+ function toCurrency (value) {
229
+ const { isNegative, dollars: rupees, cents: paise } = parseCurrencyValue(value)
230
+
231
+ // Build result
232
+ let result = ''
233
+ if (isNegative) result = NEGATIVE + ' '
234
+
235
+ // Rupees part - show if non-zero, or if no paise
236
+ if (rupees > 0n || paise === 0n) {
237
+ result += integerToWords(rupees)
238
+ // Singular for 1 rupee, plural otherwise
239
+ result += ' ' + (rupees === 1n ? RUPEE : RUPEES)
240
+ }
241
+
242
+ // Paise part
243
+ if (paise > 0n) {
244
+ if (rupees > 0n) {
245
+ result += ' '
246
+ }
247
+ result += integerToWords(paise)
248
+ // Singular for 1 paisa, plural otherwise
249
+ result += ' ' + (paise === 1n ? PAISA : PAISE)
250
+ }
251
+
252
+ return result
253
+ }
254
+
255
+ // ============================================================================
256
+ // Exports
257
+ // ============================================================================
258
+
259
+ export { toCardinal, toOrdinal, toCurrency }
package/src/ha-NG.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Converts a numeric value to Hausa words.
3
+ *
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @returns {string} The number in Hausa words
6
+ */
7
+ export function toCardinal(value: number | string | bigint): string;
8
+ /**
9
+ * Converts a numeric value to Hausa ordinal words.
10
+ *
11
+ * @param {number | string | bigint} value - The numeric value to convert (positive integer)
12
+ * @returns {string} The number as ordinal words
13
+ * @throws {TypeError} If value is not a valid numeric type
14
+ * @throws {RangeError} If value is negative, zero, or has a decimal part
15
+ *
16
+ * @example
17
+ * toOrdinal(1) // 'na farko'
18
+ * toOrdinal(2) // 'na biyu'
19
+ * toOrdinal(10) // 'na goma'
20
+ */
21
+ export function toOrdinal(value: number | string | bigint): string;
22
+ /**
23
+ * Converts a numeric value to Hausa currency words (Nigerian Naira).
24
+ *
25
+ * Uses naira and kobo (100 kobo = 1 naira).
26
+ *
27
+ * @param {number | string | bigint} value - The currency amount to convert
28
+ * @returns {string} The amount in Hausa currency words
29
+ * @throws {TypeError} If value is not a valid numeric type
30
+ * @throws {Error} If value is not a valid number format
31
+ *
32
+ * @example
33
+ * toCurrency(42) // 'arba'in da biyu naira'
34
+ * toCurrency(1.50) // 'ɗaya naira da hamsin kobo'
35
+ * toCurrency(-5) // 'babu biyar naira'
36
+ */
37
+ export function toCurrency(value: number | string | bigint): string;