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 +1 @@
1
- {"version":3,"file":"n2words.js","mappings":"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OACL,CAAC,GAAI,OACL,CAAC,GAAI,SAoBPC,WAAAA,CAAaC,EAAUC,GACrB,MAAMC,EAAWhD,OAAOiD,KAAKH,GAAU,GACjCI,EAAalD,OAAOmD,OAAOL,GAAU,GACrCM,EAAYpD,OAAOiD,KAAKF,GAAW,GACnCM,EAAcrD,OAAOmD,OAAOJ,GAAW,GAG7C,OAAmB,KAAfG,GAAqBG,EAAc,KAC9B,CAAE,CAACD,GAAYC,GAIpBH,EAAa,MAAQA,EAAaG,EAC7B,CAAE,CAAC,GAAGL,KAAYI,KAAcF,EAAaG,GAIlDH,GAAc,MAAQG,EAAc,KAC/B,CAAE,CAAC,GAAGL,SAAgBI,KAAcF,EAAaG,GAItDA,EAAcH,EACT,CAAE,CAAC,GAAGF,KAAYI,KAAcF,EAAaG,GAG/C,CAAE,CAAC,GAAGL,KAAYI,KAAcF,EAAaG,EACtD,EAgBa,SAASC,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAI6B,EAAQ7B,GAAS4C,eAAezE,EAC7C,C,kDCxHA,MAAM0E,UAAcC,EAAAA,EAClBf,aAAe,QACfC,qBAAuB,QACvBC,SAAW,QACXc,YAAc,KACdC,aAAe,CACb,QACA,KACA,KACA,MACA,MACA,OACA,KACA,MACA,KACA,KACA,KACA,SACA,OACA,OACA,OACA,SACA,OACA,QACA,QACA,SACA,MACA,SACA,OACA,OACA,QACA,SACA,SACA,UACA,UACA,QACA,MACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,UACA,QACA,UACA,SACA,UACA,SACA,WACA,UACA,WACA,WACA,QACA,OACA,UACA,OACA,QACA,OACA,OACA,QACA,UACA,UACA,OACA,MACA,OACA,OACA,QACA,QACA,QACA,SACA,QACA,QACA,UACA,QACA,UACA,SACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,QACA,UACA,QACA,SACA,SACA,QACA,SACA,UACA,UACA,QACA,QACA,WACA,QACA,UACA,UACA,SACA,UACA,WACA,WACA,aAGFC,WAAa,CACX,GACA,QACA,MACA,QACA,MACA,MACA,MACA,OACA,OAIW,SAA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MACA,KACA,MACA,MACA,MACA,MACA,SACA,QACA,QACA,QACA,SACA,QACA,SACA,SACA,OACA,MACA,OACA,MACA,MACA,OACA,OACA,OACA,OACA,OACA,QACA,MACA,QACA,OACA,OACA,QACA,QACA,OACA,QACA,QACA,SACA,OACA,SACA,QACA,UACA,SACA,SACA,QACA,UACA,SACA,QACA,QACA,SACA,QACA,SACA,UACA,UACA,QACA,UACA,SACA,QACA,MACA,QACA,OACA,OACA,QACA,QACA,QACA,OACA,OACA,SACA,OACA,SACA,QACA,QACA,SACA,UACA,SACA,QACA,QACA,QACA,OACA,SACA,QACA,SACA,UACA,QACA,QACA,SACA,QACA,QACA,OACA,UACA,SACA,UACA,WACA,WACA,UACA,UACA,UACA,YAGFC,WAAa,CACX,GACA,QACA,MACA,OACA,MACA,MACA,MACA,MACA,QAIW,SAASL,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAI4K,EAAQ5K,GAAS4C,eAAezE,EAC7C,C,qDCtFA,MAAM2E,UAA2BwC,EAAAA,EAM/BtC,aAOAD,YAQAE,WAqBA4H,aAAAA,CAAelF,GACb,MAAMmF,EAASnF,EAAO/E,WAEtB,GAAIkK,EAAO5N,QAAU,EACnB,MAAO,CAACyJ,OAAOmE,IAGjB,MAAMC,EAAS,GACTC,EAAQF,EAAOtL,OAAO,GAC5BuL,EAAOE,QAAQtE,OAAOqE,IAEtB,IAAIE,EAAYJ,EAAOtL,MAAM,GAAI,GACjC,KAAO0L,EAAUhO,OAAS,GAAG,CAC3B,MAAMqM,EAAQ2B,EAAU1L,OAAO,GAC/BuL,EAAOE,QAAQtE,OAAO4C,IACtB2B,EAAYA,EAAU1L,MAAM,GAAI,EAClC,CAEA,OAAOuL,CACT,CASAI,oBAAAA,CAAsBxF,GACpB,GAAe,IAAXA,EAAc,MAAO,GACzB,GAAIA,EAAS,IAAK,OAAO5H,KAAKiF,aAAa2C,GAE3C,MAAMnC,EAAWY,KAAKE,MAAMqB,EAAS,KAC/ByF,EAAYzF,EAAS,IACrB0F,EAAQ,GAYd,OAViB,IAAb7H,EACF6H,EAAMlF,KAAKp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BACVxG,EAAa,EAAQ,KAErBhB,EAAO3H,EAAY,GAAG2H,MAE1BlK,EAAOD,QAAU,SAAU4R,EAAQC,GACjC,IAGIC,EAHA1I,EAAIsI,EAAgBE,GACpB7D,EAAI,EACJxL,EAAS,GAEb,IAAKuP,KAAO1I,GAAI1G,EAAOyI,EAAY2G,IAAQpP,EAAO0G,EAAG0I,IAAQ3H,EAAK5H,EAAQuP,GAE1E,KAAOD,EAAM3Q,OAAS6M,GAAOrL,EAAO0G,EAAG0I,EAAMD,EAAM9D,SAChD4D,EAAQpP,EAAQuP,IAAQ3H,EAAK5H,EAAQuP,IAExC,OAAOvP,CACT,C,mDClBA,MAAMwP,UAAajL,EAAAA,EACjBf,aAAe,OACfC,qBAAuB,UACvBC,SAAW,MACXc,YAAc,KACdC,aAAe,CACb,MACA,MACA,KACA,MACA,MACA,OACA,KACA,MACA,MACA,KACA,KACA,QACA,OACA,OACA,OACA,QACA,OACA,OACA,SACA,OACA,MACA,OACA,QACA,QACA,QACA,OACA,QACA,SACA,UACA,QACA,MACA,QACA,OACA,SACA,SACA,SACA,QACA,SACA,QACA,UACA,QACA,UACA,SACA,WACA,SACA,WACA,SACA,WACA,UACA,QACA,OACA,QACA,OACA,OACA,MACA,OACA,OACA,QACA,SACA,QACA,OACA,QACA,QACA,QACA,SACA,SACA,UACA,QACA,QACA,QACA,MACA,QACA,OACA,OACA,QACA,QACA,QACA,OACA,SACA,QACA,MACA,SACA,QACA,SACA,SACA,QACA,SACA,QACA,SACA,QACA,MACA,SACA,QACA,SACA,UACA,SACA,UACA,SACA,UACA,UAGFC,WAAa,CACX,GACA,OACA,OACA,OACA,MACA,OACA,MACA,MACA,QAIW,SAASL,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAI+N,EAAK/N,GAAS4C,eAAezE,EAC1C,C,cC5HA,IAAI2B,EAAc,EAAQ,KACtBT,EAAiB,EAAQ,MAE7BpD,EAAOD,QAAU,SAAUyB,EAAQsC,EAAMiO,GAGvC,OAFIA,EAAW9O,KAAKY,EAAYkO,EAAW9O,IAAKa,EAAM,CAAEE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,MACH,EAAG,MACH,EAAG,SACH,EAAG,OACH,EAAG,QACH,EAAG,OACH,EAAG,SACH,EAAG,UAGLmF,aAAe,CACb,EAAG,OACH,EAAG,MACH,EAAG,MACH,EAAG,SACH,EAAG,OACH,EAAG,QACH,EAAG,OACH,EAAG,SACH,EAAG,UAGLhI,KAAO,CACL,EAAG,SACH,EAAG,cACH,EAAG,aACH,EAAG,aACH,EAAG,eACH,EAAG,aACH,EAAG,cACH,EAAG,aACH,EAAG,eACH,EAAG,gBAGL0E,SAAW,CACT,EAAG,WACH,EAAG,WACH,EAAG,QACH,EAAG,YACH,EAAG,aACH,EAAG,YACH,EAAG,cACH,EAAG,aAGL1G,SAAW,CACT,EAAG,MACH,EAAG,SACH,EAAG,SACH,EAAG,YACH,EAAG,UACH,EAAG,WACH,EAAG,UACH,EAAG,YACH,EAAG,aAGLiC,UAAY,CACV,EAAG,CAAC,SAAU,SAAU,SACxB,EAAG,CAAC,UAAW,WAAY,aAC3B,EAAG,CAAC,WAAY,YAAa,cAC7B,EAAG,CAAC,WAAY,YAAa,cAC7B,EAAG,CAAC,cAAe,eAAgB,iBACnC,EAAG,CAAC,cAAe,eAAgB,iBACnC,EAAG,CAAC,cAAe,eAAgB,iBACnC,EAAG,CAAC,aAAc,cAAe,gBACjC,EAAG,CAAC,YAAa,aAAc,eAC/B,GAAI,CAAC,YAAa,aAAc,gBAarB,SAAS7C,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAIuU,EAAQvU,GAAS4C,eAAezE,EAC7C,C,mDCjHA,MAAMqW,UAAgB1R,EAAAA,EACpBf,aAAe,SACfC,qBAAuB,QACvBC,SAAW,QACXc,YAAc,KACdC,aAAe,CACb,QACA,KACA,MACA,MACA,MACA,OACA,MACA,MACA,KACA,MACA,KACA,QACA,OACA,OACA,QACA,QACA,MACA,QACA,QACA,OACA,MACA,OACA,OACA,OACA,SACA,QACA,UACA,QACA,OACA,UACA,QACA,UACA,SACA,UACA,UACA,YACA,SACA,YACA,UACA,WACA,SACA,WACA,aACA,YACA,aACA,cACA,WACA,YACA,WACA,WACA,SACA,SACA,UACA,YACA,WACA,WACA,YACA,UACA,SACA,QACA,MACA,UACA,UACA,UACA,UACA,YACA,UACA,WACA,UACA,UACA,QACA,UACA,WACA,WACA,YACA,WACA,YACA,WACA,UACA,QACA,MACA,QACA,SACA,SACA,SACA,SACA,UACA,SACA,QACA,UACA,QACA,WACA,YACA,YACA,YACA,YACA,aACA,YACA,WACA,aAGFC,WAAa,CACX,GACA,QACA,MACA,OACA,MACA,MACA,MACA,OACA,QAIW,SAASL,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAIwU,EAAQxU,GAAS4C,eAAezE,EAC7C,C,mDC1GA,MAAMsW,UAAyB3R,EAAAA,EAC7Bf,aAAe,KACfC,qBAAuB,QACvBC,SAAW,QACXc,YAAc,KACd6G,yBAA0B,EAE1B5G,aAAe,CACb,QACA,KACA,KACA,OACA,MACA,OACA,IACA,MACA,KACA,KACA,KACA,SACA,MACA,MACA,MACA,OACA,MACA,QACA,OACA,QACA,MACA,QACA,QACA,UACA,QACA,OACA,SACA,WACA,WACA,WACA,QACA,UACA,SACA,UACA,UACA,WACA,SACA,WACA,UACA,WACA,QACA,UACA,UACA,YACA,WACA,YACA,UACA,WACA,UACA,UACA,OACA,QACA,OACA,SACA,OACA,SACA,QACA,UACA,UACA,SACA,MACA,OACA,OACA,SACA,OACA,QACA,OACA,OACA,OACA,cACA,UACA,SACA,QACA,QACA,UACA,UACA,QACA,YACA,WACA,WACA,OACA,UACA,SACA,SACA,WACA,SACA,SACA,WACA,UACA,WACA,QACA,SACA,QACA,UACA,UACA,UACA,SACA,WACA,WACA,YAGFC,WAAa,CACX,GACA,OACA,MACA,OACA,MACA,MACA,MACA,OACA,OAeW,SAASL,EAAgBzE,EAAO6B,EAAU,CAAC,GACxD,OAAO,IAAIyU,EAAiBzU,GAAS4C,eAAezE,EACtD,C,2DCzJA,MAAMuW,UAAepP,EAAAA,EACnBvD,aAAe,QACfC,qBAAuB,UACvBC,SAAW,SACX2H,yBAA0B,EAC1B5G,aAAe,CACb,SACA,OACA,QACA,OACA,SACA,MACA,MACA,MACA,UACA,WACA,MACA,UACA,WACA,SACA,YACA,UACA,SACA,UACA,cACA,aACA,OACA,cACA,aACA,YACA,cACA,WACA,WACA,WACA,eACA,gBACA,SACA,cACA,eACA,cACA,gBACA,aACA,aACA,aACA,iBACA,kBACA,OACA,YACA,aACA,YACA,cACA,WACA,WACA,WACA,eACA,gBACA,OACA,YACA,aACA,YACA,cACA,WACA,WACA,WACA,eACA,gBACA,OACA,YACA,aACA,YACA,cACA,WACA,WACA,WACA,eACA,gBACA,SACA,cACA,eACA,cACA,gBACA,aACA,aACA,aACA,iBACA,kBACA,OACA,YACA,aACA,YACA,cACA,WACA,WACA,WACA,eACA,gBACA,QACA,aACA,cACA,aACA,eACA,YACA,YACA,YACA,gBACA,kBAGFQ,SAAW,CACT,GACA,MACA,cACA,aACA,eACA,YACA,YACA,YACA,gBACA,kBAIFmR,OAAS,CACP,OACA,QACA,OACA,SACA,MACA,MACA,MACA,UACA,YAGFC,OAAS,CACP,GACA,SACA,OACA,OACA,OACA,OACA,OACA,OACA,QASFC,mBAAAA,CAAqBlP,GACnB,OAAO5H,KAAKiF,aAAa2C,EAC3B,CAQAwF,oBAAAA,CAAsBxF,GACpB,GAAe,IAAXA,EAAc,MAAO,GACzB,GAAIA,EAAS,IAAK,OAAO5H,KAAK8W,oBAAoBlP,GAElD,MAAMnC,EAAWY,KAAKE,MAAMqB,EAAS,KAC/ByF,EAAYzF,EAAS,IACrB0F,EAAQ,CAACtN,KAAKyF,SAASA,IAM7B,OAJI4H,EAAY,GACdC,EAAMlF,KAAKpI,KAAK8W,oBAAoBzJ,IAG/BC,EAAM3L,KAAK,KAAKgK,MACzB,CAQAoL,WAAAA,CAAanP,GACX,MAAMmF,EAASnF,EAAO/E,WACtB,GAAIkK,EAAO5N,QAAU,EAAG,MAAO,CAACyJ,OAAOmE,IAEvC,MAAMC,EAAS,GACTC,EAAQF,EAAOtL,OAAO,GAC5BuL,EAAOE,QAAQtE,OAAOqE,IAEtB,IAAIE,EAAYJ,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","sources":["webpack://n2words/webpack/universalModuleDefinition","webpack://n2words/./node_modules/core-js/internals/is-object.js","webpack://n2words/./node_modules/core-js/internals/get-iterator.js","webpack://n2words/./node_modules/core-js/modules/es.iterator.find.js","webpack://n2words/./node_modules/core-js/internals/make-built-in.js","webpack://n2words/./node_modules/core-js/internals/function-name.js","webpack://n2words/./node_modules/core-js/internals/html.js","webpack://n2words/./node_modules/core-js/internals/hidden-keys.js","webpack://n2words/./node_modules/core-js/internals/iterate-simple.js","webpack://n2words/./node_modules/core-js/internals/function-bind-native.js","webpack://n2words/./lib/languages/en.js","webpack://n2words/./lib/languages/hi.js","webpack://n2words/./node_modules/core-js/internals/an-instance.js","webpack://n2words/./node_modules/core-js/internals/iterator-helper-throws-on-invalid-iterator.js","webpack://n2words/./lib/languages/pt.js","webpack://n2words/./node_modules/core-js/internals/math-trunc.js","webpack://n2words/./node_modules/core-js/internals/is-symbol.js","webpack://n2words/./node_modules/core-js/internals/get-iterator-method.js","webpack://n2words/./node_modules/core-js/internals/object-keys.js","webpack://n2words/./lib/languages/vi.js","webpack://n2words/./node_modules/core-js/internals/internal-state.js","webpack://n2words/./node_modules/core-js/internals/to-integer-or-infinity.js","webpack://n2words/./lib/languages/ar.js","webpack://n2words/./lib/languages/mr.js","webpack://n2words/./node_modules/core-js/internals/iterator-close-all.js","webpack://n2words/./lib/languages/lv.js","webpack://n2words/./lib/languages/pa-Guru.js","webpack://n2words/./lib/classes/south-asian-language.js","webpack://n2words/./lib/languages/he.js","webpack://n2words/./node_modules/core-js/internals/object-is-prototype-of.js","webpack://n2words/./node_modules/core-js/modules/es.set.union.v2.js","webpack://n2words/./node_modules/core-js/modules/es.iterator.map.js","webpack://n2words/./lib/languages/uk.js","webpack://n2words/./node_modules/core-js/internals/get-iterator-direct.js","webpack://n2words/./node_modules/core-js/internals/object-keys-internal.js","webpack://n2words/./lib/languages/ur.js","webpack://n2words/./node_modules/core-js/internals/define-built-in-accessor.js","webpack://n2words/./node_modules/core-js/internals/to-string-tag-support.js","webpack://n2words/./node_modules/core-js/internals/classof-raw.js","webpack://n2words/./lib/languages/fr.js","webpack://n2words/./node_modules/core-js/internals/correct-prototype-getter.js","webpack://n2words/./node_modules/core-js/internals/object-create.js","webpack://n2words/./lib/languages/ms.js","webpack://n2words/./node_modules/core-js/modules/es.set.is-superset-of.v2.js","webpack://n2words/./node_modules/core-js/internals/create-iter-result-object.js","webpack://n2words/./lib/languages/az.js","webpack://n2words/./lib/languages/sr-Latn.js","webpack://n2words/./node_modules/core-js/internals/iterate.js","webpack://n2words/./node_modules/core-js/internals/to-primitive.js","webpack://n2words/./node_modules/core-js/internals/object-get-prototype-of.js","webpack://n2words/./node_modules/core-js/internals/is-forced.js","webpack://n2words/./node_modules/core-js/internals/environment-user-agent.js","webpack://n2words/./lib/languages/ru.js","webpack://n2words/./lib/languages/bn.js","webpack://n2words/./lib/languages/gu.js","webpack://n2words/./lib/languages/te.js","webpack://n2words/./node_modules/core-js/internals/uid.js","webpack://n2words/./node_modules/core-js/internals/set-difference.js","webpack://n2words/./lib/languages/el.js","webpack://n2words/./node_modules/core-js/internals/set-symmetric-difference.js","webpack://n2words/./node_modules/core-js/internals/inspect-source.js","webpack://n2words/./node_modules/core-js/internals/object-get-own-property-symbols.js","webpack://n2words/./node_modules/core-js/internals/descriptors.js","webpack://n2words/./node_modules/core-js/internals/get-set-record.js","webpack://n2words/./node_modules/core-js/internals/set-is-subset-of.js","webpack://n2words/./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js","webpack://n2words/./lib/languages/de.js","webpack://n2words/./lib/classes/turkic-language.js","webpack://n2words/./lib/languages/id.js","webpack://n2words/./node_modules/core-js/internals/document-create-element.js","webpack://n2words/./lib/classes/greedy-scale-language.js","webpack://n2words/./lib/languages/th.js","webpack://n2words/./node_modules/core-js/modules/es.array.push.js","webpack://n2words/./node_modules/core-js/internals/is-null-or-undefined.js","webpack://n2words/./node_modules/core-js/internals/set-union.js","webpack://n2words/./node_modules/core-js/internals/is-array-iterator-method.js","webpack://n2words/./node_modules/core-js/internals/ordinary-to-primitive.js","webpack://n2words/./node_modules/core-js/internals/is-array.js","webpack://n2words/./node_modules/core-js/internals/set-helpers.js","webpack://n2words/./lib/languages/it.js","webpack://n2words/./node_modules/core-js/internals/set-is-disjoint-from.js","webpack://n2words/./lib/languages/ro.js","webpack://n2words/./node_modules/core-js/internals/symbol-constructor-detection.js","webpack://n2words/./node_modules/core-js/internals/array-set-length.js","webpack://n2words/./node_modules/core-js/internals/iterator-helper-without-closing-on-early-error.js","webpack://n2words/./node_modules/core-js/internals/global-this.js","webpack://n2words/./lib/languages/nl.js","webpack://n2words/./node_modules/core-js/internals/create-property.js","webpack://n2words/./node_modules/core-js/internals/is-callable.js","webpack://n2words/./node_modules/core-js/internals/object-define-property.js","webpack://n2words/./node_modules/core-js/internals/set-method-accept-set-like.js","webpack://n2words/./lib/languages/fil.js","webpack://n2words/./node_modules/core-js/modules/es.set.symmetric-difference.v2.js","webpack://n2words/./node_modules/core-js/internals/own-keys.js","webpack://n2words/./node_modules/core-js/internals/set-size.js","webpack://n2words/./lib/languages/ja.js","webpack://n2words/./node_modules/core-js/internals/to-indexed-object.js","webpack://n2words/./node_modules/core-js/internals/to-absolute-index.js","webpack://n2words/./lib/languages/tr.js","webpack://n2words/./node_modules/core-js/internals/shared.js","webpack://n2words/./lib/languages/pl.js","webpack://n2words/./lib/languages/fa.js","webpack://n2words/./node_modules/core-js/modules/es.set.is-subset-of.v2.js","webpack://n2words/./node_modules/core-js/internals/ie8-dom-define.js","webpack://n2words/./node_modules/core-js/internals/get-method.js","webpack://n2words/./node_modules/core-js/internals/function-bind-context.js","webpack://n2words/./lib/languages/hr.js","webpack://n2words/./node_modules/core-js/internals/shared-key.js","webpack://n2words/./node_modules/core-js/internals/length-of-array-like.js","webpack://n2words/./node_modules/core-js/internals/iterators.js","webpack://n2words/./node_modules/core-js/internals/define-built-ins.js","webpack://n2words/./lib/classes/abstract-language.js","webpack://n2words/./node_modules/core-js/internals/call-with-safe-iteration-closing.js","webpack://n2words/./lib/languages/sv.js","webpack://n2words/./node_modules/core-js/internals/is-pure.js","webpack://n2words/./lib/languages/fr-BE.js","webpack://n2words/./node_modules/core-js/internals/add-to-unscopables.js","webpack://n2words/./node_modules/core-js/internals/export.js","webpack://n2words/./lib/languages/cs.js","webpack://n2words/./node_modules/core-js/internals/create-non-enumerable-property.js","webpack://n2words/./node_modules/core-js/internals/function-uncurry-this-accessor.js","webpack://n2words/./node_modules/core-js/internals/object-define-properties.js","webpack://n2words/./node_modules/core-js/internals/try-to-string.js","webpack://n2words/./node_modules/core-js/internals/does-not-exceed-safe-integer.js","webpack://n2words/./node_modules/core-js/internals/define-built-in.js","webpack://n2words/./lib/languages/nb.js","webpack://n2words/./node_modules/core-js/internals/classof.js","webpack://n2words/./node_modules/core-js/internals/to-property-key.js","webpack://n2words/./node_modules/core-js/internals/create-property-descriptor.js","webpack://n2words/./node_modules/core-js/internals/use-symbol-as-uid.js","webpack://n2words/./node_modules/core-js/internals/indexed-object.js","webpack://n2words/./node_modules/core-js/internals/a-set.js","webpack://n2words/./lib/classes/slavic-language.js","webpack://n2words/./node_modules/core-js/internals/object-get-own-property-descriptor.js","webpack://n2words/./node_modules/core-js/internals/function-uncurry-this-clause.js","webpack://n2words/./node_modules/core-js/internals/array-to-reversed.js","webpack://n2words/./node_modules/core-js/internals/shared-store.js","webpack://n2words/./node_modules/core-js/modules/es.set.difference.v2.js","webpack://n2words/./node_modules/core-js/internals/iterators-core.js","webpack://n2words/./node_modules/core-js/internals/copy-constructor-properties.js","webpack://n2words/./node_modules/core-js/internals/require-object-coercible.js","webpack://n2words/./node_modules/core-js/internals/get-built-in.js","webpack://n2words/./lib/languages/da.js","webpack://n2words/./node_modules/core-js/modules/es.set.intersection.v2.js","webpack://n2words/./node_modules/core-js/internals/to-length.js","webpack://n2words/./node_modules/core-js/modules/es.iterator.constructor.js","webpack://n2words/./node_modules/core-js/internals/well-known-symbol.js","webpack://n2words/./lib/languages/ko.js","webpack://n2words/./lib/languages/sw.js","webpack://n2words/./node_modules/core-js/internals/set-iterate.js","webpack://n2words/./node_modules/core-js/internals/object-get-own-property-names.js","webpack://n2words/./node_modules/core-js/internals/set-is-superset-of.js","webpack://n2words/./node_modules/core-js/internals/an-object.js","webpack://n2words/./node_modules/core-js/internals/weak-map-basic-detection.js","webpack://n2words/./lib/languages/es.js","webpack://n2words/./node_modules/core-js/internals/v8-prototype-define-bug.js","webpack://n2words/./node_modules/core-js/internals/enum-bug-keys.js","webpack://n2words/./node_modules/core-js/internals/set-intersection.js","webpack://n2words/./node_modules/core-js/internals/object-property-is-enumerable.js","webpack://n2words/./node_modules/core-js/internals/to-object.js","webpack://n2words/./node_modules/core-js/internals/fails.js","webpack://n2words/./node_modules/core-js/internals/set-clone.js","webpack://n2words/./node_modules/core-js/internals/has-own-property.js","webpack://n2words/./node_modules/core-js/internals/a-callable.js","webpack://n2words/./lib/languages/kn.js","webpack://n2words/./lib/languages/lt.js","webpack://n2words/./node_modules/core-js/internals/define-global-property.js","webpack://n2words/./node_modules/core-js/internals/iterator-create-proxy.js","webpack://n2words/./node_modules/core-js/internals/function-uncurry-this.js","webpack://n2words/./node_modules/core-js/internals/environment-v8-version.js","webpack://n2words/./node_modules/core-js/internals/iterator-close.js","webpack://n2words/./node_modules/core-js/internals/function-call.js","webpack://n2words/./node_modules/core-js/internals/array-includes.js","webpack://n2words/./node_modules/core-js/modules/es.array.to-reversed.js","webpack://n2words/./lib/languages/ta.js","webpack://n2words/./lib/languages/zh-Hans.js","webpack://n2words/./lib/languages/hu.js","webpack://n2words/./node_modules/core-js/internals/set-method-get-keys-before-cloning-detection.js","webpack://n2words/webpack/bootstrap","webpack://n2words/webpack/runtime/define property getters","webpack://n2words/webpack/runtime/hasOwnProperty shorthand","webpack://n2words/./lib/n2words.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"n2words\"] = factory();\n\telse\n\t\troot[\"n2words\"] = factory();\n})(globalThis, () => {\nreturn ","'use strict';\nvar isCallable = require('../internals/is-callable');\n\nmodule.exports = function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar aCallable = require('../internals/a-callable');\nvar anObject = require('../internals/an-object');\nvar tryToString = require('../internals/try-to-string');\nvar getIteratorMethod = require('../internals/get-iterator-method');\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (argument, usingIterator) {\n var iteratorMethod = arguments.length < 2 ? getIteratorMethod(argument) : usingIterator;\n if (aCallable(iteratorMethod)) return anObject(call(iteratorMethod, argument));\n throw new $TypeError(tryToString(argument) + ' is not iterable');\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar call = require('../internals/function-call');\nvar iterate = require('../internals/iterate');\nvar aCallable = require('../internals/a-callable');\nvar anObject = require('../internals/an-object');\nvar getIteratorDirect = require('../internals/get-iterator-direct');\nvar iteratorClose = require('../internals/iterator-close');\nvar iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');\n\nvar findWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('find', TypeError);\n\n// `Iterator.prototype.find` method\n// https://tc39.es/ecma262/#sec-iterator.prototype.find\n$({ target: 'Iterator', proto: true, real: true, forced: findWithoutClosingOnEarlyError }, {\n find: function find(predicate) {\n anObject(this);\n try {\n aCallable(predicate);\n } catch (error) {\n iteratorClose(this, 'throw', error);\n }\n\n if (findWithoutClosingOnEarlyError) return call(findWithoutClosingOnEarlyError, this, predicate);\n\n var record = getIteratorDirect(this);\n var counter = 0;\n return iterate(record, function (value, stop) {\n if (predicate(value, counter++)) return stop(value);\n }, { IS_RECORD: true, INTERRUPTED: true }).result;\n }\n});\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\nvar hasOwn = require('../internals/has-own-property');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar CONFIGURABLE_FUNCTION_NAME = require('../internals/function-name').CONFIGURABLE;\nvar inspectSource = require('../internals/inspect-source');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar hasOwn = require('../internals/has-own-property');\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\n\nmodule.exports = getBuiltIn('document', 'documentElement');\n","'use strict';\nmodule.exports = {};\n","'use strict';\nvar call = require('../internals/function-call');\n\nmodule.exports = function (record, fn, ITERATOR_INSTEAD_OF_RECORD) {\n var iterator = ITERATOR_INSTEAD_OF_RECORD ? record : record.iterator;\n var next = record.next;\n var step, result;\n while (!(step = call(next, iterator)).done) {\n result = fn(step.value);\n if (result !== undefined) return result;\n }\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * English language converter.\n *\n * Converts numbers to English words, supporting:\n * - Negative numbers (prepended with \"minus\")\n * - Decimal numbers (word \"point\" between whole and fractional parts)\n * - Numbers up to octillions\n *\n * Merge rules:\n * - Hyphenated for compound tens (e.g., \"twenty-three\")\n * - \"and\" after hundreds (e.g., \"one hundred and one\")\n * - Space-separated for larger composites (e.g., \"one thousand twenty-three\")\n */\nexport class English extends GreedyScaleLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'point'\n zeroWord = 'zero'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'octillion'],\n [1_000_000_000_000_000_000_000_000n, 'septillion'],\n [1_000_000_000_000_000_000_000n, 'sextillion'],\n [1_000_000_000_000_000_000n, 'quintillion'],\n [1_000_000_000_000_000n, 'quadrillion'],\n [1_000_000_000_000n, 'trillion'],\n [1_000_000_000n, 'billion'],\n [1_000_000n, 'million'],\n [1000n, 'thousand'],\n [100n, 'hundred'],\n [90n, 'ninety'],\n [80n, 'eighty'],\n [70n, 'seventy'],\n [60n, 'sixty'],\n [50n, 'fifty'],\n [40n, 'forty'],\n [30n, 'thirty'],\n [20n, 'twenty'],\n [19n, 'nineteen'],\n [18n, 'eighteen'],\n [17n, 'seventeen'],\n [16n, 'sixteen'],\n [15n, 'fifteen'],\n [14n, 'fourteen'],\n [13n, 'thirteen'],\n [12n, 'twelve'],\n [11n, 'eleven'],\n [10n, 'ten'],\n [9n, 'nine'],\n [8n, 'eight'],\n [7n, 'seven'],\n [6n, 'six'],\n [5n, 'five'],\n [4n, 'four'],\n [3n, 'three'],\n [2n, 'two'],\n [1n, 'one'],\n [0n, 'zero']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to English grammar rules.\n *\n * English-specific rules:\n * - Implicit \"one\": `mergeScales({ 'one': 1n }, { 'hundred': 100n })` → `{ 'one hundred': 100n }`\n * - Hyphenated compounds: `mergeScales({ 'twenty': 20n }, { 'three': 3n })` → `{ 'twenty-three': 23n }`\n * - \"and\" after hundreds: `mergeScales({ 'one hundred': 100n }, { 'one': 1n })` → `{ 'one hundred and one': 101n }`\n * - Multiplication: `mergeScales({ 'one': 1n }, { 'thousand': 1000n })` → `{ 'one thousand': 1000n }`\n *\n * @param {Object} leftPair Left word-set as `{ word: BigInt }`.\n * @param {Object} rightPair Right word-set as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'one': 1n }, { 'hundred': 100n }); // { 'one hundred': 100n }\n * mergeScales({ 'twenty': 20n }, { 'three': 3n }); // { 'twenty-three': 23n }\n */\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const leftNumber = Object.values(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const rightNumber = Object.values(rightPair)[0]\n\n // Rule 1: Implicit \"one\" - omit when multiplying (\"one hundred\" → \"hundred\")\n if (leftNumber === 1n && rightNumber < 100n) {\n return { [rightWord]: rightNumber }\n }\n\n // Rule 2: Hyphenate compounds under 100 (\"twenty-three\")\n if (leftNumber < 100n && leftNumber > rightNumber) {\n return { [`${leftWord}-${rightWord}`]: leftNumber + rightNumber }\n }\n\n // Rule 3: Add \"and\" before units after hundreds (\"one hundred and one\")\n if (leftNumber >= 100n && rightNumber < 100n) {\n return { [`${leftWord} and ${rightWord}`]: leftNumber + rightNumber }\n }\n\n // Rule 4: Multiply when right > left (\"one thousand\")\n if (rightNumber > leftNumber) {\n return { [`${leftWord} ${rightWord}`]: leftNumber * rightNumber }\n }\n\n return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }\n }\n}\n\n/**\n * Converts a number to English cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see English class options).\n * @returns {string} The number expressed in English words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'forty-two'\n * convertToWords('1.5'); // 'one point five'\n */\nexport default function convertToWords (value, options = {}) {\n return new English(options).convertToWords(value)\n}\n","import SouthAsianLanguage from '../classes/south-asian-language.js'\n\nclass Hindi extends SouthAsianLanguage {\n negativeWord = 'माइनस'\n decimalSeparatorWord = 'दशमलव'\n zeroWord = 'शून्य'\n hundredWord = 'सौ'\n belowHundred = [\n 'शून्य',\n 'एक',\n 'दो',\n 'तीन',\n 'चार',\n 'पाँच',\n 'छह',\n 'सात',\n 'आठ',\n 'नौ',\n 'दस',\n 'ग्यारह',\n 'बारह',\n 'तेरह',\n 'चौदह',\n 'पंद्रह',\n 'सोलह',\n 'सत्रह',\n 'अठारह',\n 'उन्नीस',\n 'बीस',\n 'इक्कीस',\n 'बाईस',\n 'तेईस',\n 'चौबीस',\n 'पच्चीस',\n 'छब्बीस',\n 'सत्ताईस',\n 'अट्ठाईस',\n 'उनतीस',\n 'तीस',\n 'इकतीस',\n 'बत्तीस',\n 'तैंतीस',\n 'चौंतीस',\n 'पैंतीस',\n 'छत्तीस',\n 'सैंतीस',\n 'अड़तीस',\n 'उनतालीस',\n 'चालीस',\n 'इकतालीस',\n 'बयालीस',\n 'तेतालीस',\n 'चवालीस',\n 'पैंतालीस',\n 'छियालीस',\n 'सैंतालीस',\n 'अड़तालीस',\n 'उनचास',\n 'पचास',\n 'इक्यावन',\n 'बावन',\n 'तिरपन',\n 'चौवन',\n 'पचपन',\n 'छप्पन',\n 'सत्तावन',\n 'अट्ठावन',\n 'उनसठ',\n 'साठ',\n 'इकसठ',\n 'बासठ',\n 'तिरसठ',\n 'चौंसठ',\n 'पैंसठ',\n 'छियासठ',\n 'सड़सठ',\n 'अड़सठ',\n 'उनहत्तर',\n 'सत्तर',\n 'इकहत्तर',\n 'बहत्तर',\n 'तिहत्तर',\n 'चौहत्तर',\n 'पचहत्तर',\n 'छिहत्तर',\n 'सतहत्तर',\n 'अठहत्तर',\n 'उन्यासी',\n 'अस्सी',\n 'इक्यासी',\n 'बयासी',\n 'तिरासी',\n 'चौरासी',\n 'पचासी',\n 'छियासी',\n 'सत्तासी',\n 'अट्ठासी',\n 'नवासी',\n 'नब्बे',\n 'इक्यानवे',\n 'बानवे',\n 'तिरानवे',\n 'चौरानवे',\n 'पचानवे',\n 'छियानवे',\n 'सत्तानवे',\n 'अट्ठानवे',\n 'निन्यानवे'\n ]\n\n scaleWords = [\n '',\n 'हज़ार',\n 'लाख',\n 'करोड़',\n 'अरब',\n 'खरब',\n 'नील',\n 'पद्म',\n 'शंख'\n ]\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Hindi(options).convertToWords(value)\n}\n","'use strict';\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (it, Prototype) {\n if (isPrototypeOf(Prototype, it)) return it;\n throw new $TypeError('Incorrect invocation');\n};\n","'use strict';\n// Should throw an error on invalid iterator\n// https://issues.chromium.org/issues/336839115\nmodule.exports = function (methodName, argument) {\n // eslint-disable-next-line es/no-iterator -- required for testing\n var method = typeof Iterator == 'function' && Iterator.prototype[methodName];\n if (method) try {\n method.call({ next: null }, argument).next();\n } catch (error) {\n return true;\n }\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * (European) Portuguese language converter.\n *\n * Features:\n * - Gender-aware hundreds (hundredos, duzentos, etc.)\n * - Million/Billion pluralization\n * - \"e\" (and) conjunction for number combinations\n * - Post-processing to normalize word flow\n */\nexport class Portuguese extends GreedyScaleLanguage {\n negativeWord = 'menos'\n decimalSeparatorWord = 'vírgula'\n zeroWord = 'zero'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000n, 'quatrilião'],\n [1_000_000_000_000_000_000n, 'trilião'],\n [1_000_000_000_000n, 'bilião'],\n [1_000_000n, 'milião'],\n [1000n, 'mil'],\n [100n, 'cem'],\n [90n, 'noventa'],\n [80n, 'oitenta'],\n [70n, 'setenta'],\n [60n, 'sessenta'],\n [50n, 'cinquenta'],\n [40n, 'quarenta'],\n [30n, 'trinta'],\n [20n, 'vinte'],\n [19n, 'dezanove'],\n [18n, 'dezoito'],\n [17n, 'dezassete'],\n [16n, 'dezasseis'],\n [15n, 'quinze'],\n [14n, 'catorze'],\n [13n, 'treze'],\n [12n, 'doze'],\n [11n, 'onze'],\n [10n, 'dez'],\n [9n, 'nove'],\n [8n, 'oito'],\n [7n, 'sete'],\n [6n, 'seis'],\n [5n, 'cinco'],\n [4n, 'quatro'],\n [3n, 'três'],\n [2n, 'dois'],\n [1n, 'um'],\n [0n, 'zero']\n ]\n\n hundreds = {\n 1: 'cento',\n 2: 'duzentos',\n 3: 'trezentos',\n 4: 'quatrocentos',\n 5: 'quinhentos',\n 6: 'seiscentos',\n 7: 'setecentos',\n 8: 'oitocentos',\n 9: 'novecentos'\n }\n\n // Pre-compiled regex patterns for postClean - avoid recompilation\n static POSTCLEAN_REGEX = / e (.*entos?) (?=.*e)/g\n\n finalizeWords (words) {\n return words.replaceAll(Portuguese.POSTCLEAN_REGEX, ' $1 ')\n }\n\n /**\n * Merges two adjacent word-number pairs according to Portuguese grammar rules.\n *\n * Portuguese-specific rules:\n * - Implicit \"um\": `mergeScales({ 'um': 1n }, { 'mil': 1000n })` → `{ 'mil': 1000n }`\n * - \"e\" (and) between most combinations: `mergeScales({ 'vinte': 20n }, { 'três': 3n })` → `{ 'vinte e três': 23n }`\n * - Special handling: \"cem\" (100) becomes \"cento\" when followed by non-thousands\n * - Gender-aware hundreds: \"duzentos\", \"trezentos\", etc.\n * - Million pluralization: \"milhões\" instead of \"milhão\" when coefficient > 1\n * - Post-processing with postClean() to normalize word flow\n *\n * @param {Object} current The left operand as `{ word: BigInt }`.\n * @param {Object} next The right operand as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'um': 1n }, { 'mil': 1000n }); // { 'mil': 1000n }\n * mergeScales({ 'vinte': 20n }, { 'dois': 2n }); // { 'vinte e dois': 22n }\n */\n mergeScales (current, next) {\n // Extract words and numeric values\n let cText = Object.keys(current)[0]\n let nText = Object.keys(next)[0]\n const cNumber = Object.values(current)[0] // BigInt\n const nNumber = Object.values(next)[0] // BigInt\n\n // Implicit \"um\": omit before millions (\"um milhão\" → \"milhão\")\n if (cNumber === 1n) {\n if (nNumber < 1_000_000n) return { [nText]: nNumber }\n cText = 'um'\n } else if (cNumber === 100n && nNumber % 1000n !== 0n) {\n // Special handling: \"cem\" (100) becomes \"cento\" when followed by non-thousands\n cText = 'cento'\n }\n\n if (nNumber < cNumber) {\n return { [`${cText} e ${nText}`]: cNumber + nNumber }\n }\n\n // Handle \"milião\" -> \"milhão\" conversion\n if (nText === 'milião') nText = 'milhão'\n\n // Pluralization logic for large numbers\n if (cNumber > 1n) {\n if (nNumber % 1_000_000_000n === 0n) {\n nText = nText.replace('bilião', 'biliões')\n } else if (nNumber % 1_000_000n === 0n) {\n nText = nText.replace('milhão', 'milhões')\n }\n }\n\n if (nNumber === 100n) {\n cText = this.hundreds[cNumber]\n return { [`${cText}`]: cNumber * nNumber }\n }\n\n return { [`${cText} ${nText}`]: cNumber * nNumber }\n }\n}\n\n/**\n * Converts a number to Portuguese cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Portuguese class options).\n * @returns {string} The number expressed in Portuguese words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'quarenta e dois'\n * convertToWords('100.5'); // 'cem vírgula cinco'\n */\nexport default function convertToWords (value, options = {}) {\n return new Portuguese(options).convertToWords(value)\n}\n","'use strict';\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar isCallable = require('../internals/is-callable');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n","'use strict';\nvar classof = require('../internals/classof');\nvar getMethod = require('../internals/get-method');\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\nvar Iterators = require('../internals/iterators');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar ITERATOR = wellKnownSymbol('iterator');\n\nmodule.exports = function (it) {\n if (!isNullOrUndefined(it)) return getMethod(it, ITERATOR)\n || getMethod(it, '@@iterator')\n || Iterators[classof(it)];\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * Vietnamese language converter.\n *\n * Converts numbers to Vietnamese words following Vietnamese number naming:\n * - Base-10 grouping system (trăm = hundred, nghìn = thousand, triệu = million, tỷ = billion)\n * - Special pronunciation rules for 5 and 15 (lăm instead of năm)\n * - Special pronunciation for final 1 in compound numbers (mốt instead of một)\n * - \"Lẻ\" (odd/extra) used when tens place is zero but units exist\n *\n * Key Features:\n * - Base number mapping for 0-19 (with special forms)\n * - Tens mapping (hai mươi, ba mươi, etc.)\n * - Group-based algorithm:\n * 1. Split number into groups of 3 digits\n * 2. For each group, build words using special pronunciation rules:\n * - \"Mốt\" instead of \"một\" for final 1 (e.g., 21 → hai mươi mốt)\n * - \"Lăm\" instead of \"năm\" for 15 and mid-group 5 (e.g., 15, 105)\n * - \"Lẻ\" prefix when tens=0 but units>0 (e.g., 101 → một trăm lẻ một)\n * 3. Append magnitude word (nghìn/triệu/tỷ)\n * 4. Join all groups with spaces\n * - Support for large numbers up to vigintillions\n *\n * Features:\n * - Natural Vietnamese number flow\n * - Proper handling of special cases (mốt, lăm)\n * - Contextual pronunciation adjustments\n */\nexport class Vietnamese extends AbstractLanguage {\n negativeWord = 'âm'\n decimalSeparatorWord = 'phẩy'\n zeroWord = 'không'\n base = {\n 0: 'không',\n 1: 'một',\n 2: 'hai',\n 3: 'ba',\n 4: 'bốn',\n 5: 'năm',\n 6: 'sáu',\n 7: 'bảy',\n 8: 'tám',\n 9: 'chín',\n 10: 'mười',\n 11: 'mười một',\n 12: 'mười hai',\n 13: 'mười ba',\n 14: 'mười bốn',\n 15: 'mười lăm',\n 16: 'mười sáu',\n 17: 'mười bảy',\n 18: 'mười tám',\n 19: 'mười chín'\n }\n\n tens = {\n 20: 'hai mươi',\n 30: 'ba mươi',\n 40: 'bốn mươi',\n 50: 'năm mươi',\n 60: 'sáu mươi',\n 70: 'bảy mươi',\n 80: 'tám mươi',\n 90: 'chín mươi'\n }\n\n thousands = {\n 1: 'nghìn', // 10^1\n 2: 'triệu', // 10^2\n 3: 'tỷ', // 10^3\n 4: 'nghìn tỷ',\n 5: 'trăm nghìn tỷ',\n 6: 'Quintillion',\n 7: 'Sextillion',\n 8: 'Septillion',\n 9: 'Octillion',\n 10: 'Nonillion',\n 11: 'Decillion',\n 12: 'Undecillion',\n 13: 'Duodecillion',\n 14: 'Tredecillion',\n 15: 'Quattuordecillion',\n 16: 'Sexdecillion',\n 17: 'Septendecillion',\n 18: 'Octodecillion',\n 19: 'Novemdecillion',\n 20: 'Vigintillion'\n }\n\n /**\n * Convert numbers less than 100 to Vietnamese words.\n *\n * @param {number} number The number to convert (0-99).\n * @returns {string} The Vietnamese representation.\n */\n convertLess100 (number) {\n const unitsPart = number % 10\n const tensPart = number - unitsPart\n const tensPartText = this.tens[tensPart]\n if (unitsPart === 0) {\n return tensPartText\n }\n const unitsPartText = this.base[unitsPart]\n let suffix = unitsPartText\n if (unitsPart === 1) {\n suffix = 'mốt'\n }\n if (unitsPart === 5) {\n suffix = 'lăm'\n }\n return tensPartText + ' ' + suffix\n }\n\n /**\n * Convert numbers less than 1000 to Vietnamese words.\n *\n * @param {number} number The number to convert (0-999).\n * @returns {string} The Vietnamese representation.\n */\n convertLess1000 (number) {\n const words = []\n const tensUnitsPart = number % 100\n const hundredsPart = number - tensUnitsPart\n if (hundredsPart > 0) {\n words.push(this.base[hundredsPart / 100], 'trăm')\n }\n if (tensUnitsPart > 0 && tensUnitsPart < 10) {\n if (words.length > 0) {\n words.push('lẻ')\n }\n if (tensUnitsPart === 5) {\n words.push('năm')\n } else {\n words.push(this.base[tensUnitsPart])\n }\n }\n if (tensUnitsPart >= 10) {\n words.push(this.convertWholePart(tensUnitsPart))\n }\n return words.join(' ')\n }\n\n /**\n * Convert numbers greater than 1000 to Vietnamese words.\n *\n * @param {bigint} number The number to convert (>= 1000).\n * @returns {string} The Vietnamese representation.\n */\n convertMore1000 (number) {\n const words = []\n let division = number / 1000n\n let power = 1\n while (division >= 1000n) {\n division = division / 1000n\n power = power + 1\n }\n const r = number - (division * BigInt(Math.pow(1000, power)))\n words.push(this.convertWholePart(division), this.thousands[power])\n if (r > 0n) {\n if (r <= 99n) {\n words.push('lẻ')\n }\n words.push(this.convertWholePart(r))\n }\n return words.join(' ')\n }\n\n convertWholePart (number) {\n if (number < 20n) {\n return this.base[Number(number)]\n } else {\n if (number < 100n) {\n return this.convertLess100(Number(number))\n } else {\n return (number < 1000n ? this.convertLess1000(Number(number)) : this.convertMore1000(number))\n }\n }\n }\n}\n\n/**\n * Converts a number to Vietnamese cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @returns {string} The number expressed in Vietnamese words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Vietnamese(options).convertToWords(value)\n}\n","'use strict';\nvar NATIVE_WEAK_MAP = require('../internals/weak-map-basic-detection');\nvar globalThis = require('../internals/global-this');\nvar isObject = require('../internals/is-object');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar hasOwn = require('../internals/has-own-property');\nvar shared = require('../internals/shared-store');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = globalThis.TypeError;\nvar WeakMap = globalThis.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw new TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n","'use strict';\nvar trunc = require('../internals/math-trunc');\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * @typedef {Object} ArabicOptions\n * @property {string} [negativeWord='ناقص'] Word for negative numbers (minus).\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Arabic language converter.\n *\n * Converts numbers to Arabic words with full grammatical support:\n * - Gender agreement (masculine/feminine forms)\n * - Complex pluralization rules (singular, dual, plural forms)\n * - Special handling for hundreds, thousands, millions, etc.\n * - Right-to-left text orientation\n * - Traditional Arabic number naming conventions\n *\n * Key Features:\n * - Gender-aware number forms (واحد masculine vs واحدة feminine)\n * - Dual forms: اثنان/اثنتان (two masculine/feminine)\n * - Complex rule system for numbers 3-10 (requiring feminine when referring to countables)\n * - Group-based algorithm: splits number by powers of 1000 (ones, thousands, millions, billions)\n * - Tanween (nunation) for indefinite numbers\n * - Sophisticated pluralization with singular, dual, and plural forms\n *\n * Algorithm:\n * 1. Break number into groups of 3 digits (right to left)\n * 2. For each non-zero group, convert to words using gender and plural rules\n * 3. Append the appropriate magnitude word (ألف/مليون/مليار) with proper plural form\n * 4. Join all groups with spaces\n *\n * Features:\n * - Support for gender-aware number forms\n * - Proper handling of Arabic dual forms (اثنان/اثنتان)\n * - Complex group processing for large numbers\n * - Right-to-left text orientation\n * - Traditional Arabic number naming conventions\n */\nexport class Arabic extends AbstractLanguage {\n decimalSeparatorWord = 'فاصلة'\n zeroWord = 'صفر'\n arabicTens = ['عشرون', 'ثلاثون', 'أربعون', 'خمسون', 'ستون', 'سبعون', 'ثمانون', 'تسعون']\n arabicHundreds = ['', 'مائة', 'مئتان', 'ثلاثمائة', 'أربعمائة', 'خمسمائة', 'ستمائة', 'سبعمائة', 'ثمانمائة', 'تسعمائة']\n arabicAppendedTwos = ['مئتا', 'ألفا', 'مليونا', 'مليارا', 'تريليونا', 'كوادريليونا', 'كوينتليونا', 'سكستيليونا']\n arabicTwos = ['مئتان', 'ألفان', 'مليونان', 'ملياران', 'تريليونان', 'كوادريليونان', 'كوينتليونان', 'سكستيليونان']\n arabicGroup = ['مائة', 'ألف', 'مليون', 'مليار', 'تريليون', 'كوادريليون', 'كوينتليون', 'سكستيليون']\n arabicAppendedGroup = ['', 'ألفاً', 'مليوناً', 'ملياراً', 'تريليوناً', 'كوادريليوناً', 'كوينتليوناً', 'سكستيليوناً']\n arabicPluralGroups = ['', 'آلاف', 'ملايين', 'مليارات', 'تريليونات', 'كوادريليونات', 'كوينتليونات', 'سكستيليونات']\n ones = {\n masculine: [\n 'واحد',\n 'اثنان',\n 'ثلاثة',\n 'أربعة',\n 'خمسة',\n 'ستة',\n 'سبعة',\n 'ثمانية',\n 'تسعة',\n 'عشرة',\n 'أحد عشر',\n 'اثنا عشر',\n 'ثلاثة عشر',\n 'أربعة عشر',\n 'خمسة عشر',\n 'ستة عشر',\n 'سبعة عشر',\n 'ثمانية عشر',\n 'تسعة عشر'\n ],\n feminine: [\n 'واحدة',\n 'اثنتان',\n 'ثلاث',\n 'أربع',\n 'خمس',\n 'ست',\n 'سبع',\n 'ثمان',\n 'تسع',\n 'عشر',\n 'إحدى عشرة',\n 'اثنتا عشرة',\n 'ثلاث عشرة',\n 'أربع عشرة',\n 'خمس عشرة',\n 'ست عشرة',\n 'سبع عشرة',\n 'ثماني عشرة',\n 'تسع عشرة'\n ]\n }\n\n /**\n * Initializes the Arabic converter with language-specific options.\n *\n * @param {ArabicOptions} [options={}] Configuration options.\n */\n constructor ({ negativeWord = 'ناقص', feminine = false } = {}) {\n super()\n\n this.feminine = feminine\n this.negativeWord = negativeWord\n\n this.selectedOnes = this.ones[this.feminine ? 'feminine' : 'masculine']\n }\n\n /**\n * Returns the feminine status of a given digit (1-9).\n *\n * @param {number} digit - The digit to check (1-9).\n * @returns {string} The word form of the digit based on feminine status.\n */\n digitFeminineStatus (digit) {\n return this.selectedOnes[digit - 1]\n }\n\n /**\n * Processes the Arabic group number and returns the corresponding Arabic representation.\n * @param {number} groupNumber - The number to process. (Range: 1-999)\n * @param {number} groupLevel - Group level to process. (See example)\n * @returns {string} The Arabic representation of the group number.\n * @example 12345678 is processed in blocks of 3: '678' (group 0), '345' (group 1), '12' (group 2).\n */\n processArabicGroup (groupNumber, groupLevel, fullNumber) {\n const tens = groupNumber % 100\n const hundredsRaw = groupNumber / 100\n const hundreds = Math.trunc(hundredsRaw)\n let returnValue = ''\n\n // Process hundreds\n if (hundreds > 0) {\n if (tens === 0 && hundreds === 2) {\n returnValue = this.arabicTwos[0]\n } else {\n const hundredsWord = this.arabicHundreds[hundreds]\n if (hundredsWord) {\n returnValue = hundredsWord\n if (tens !== 0) {\n returnValue += ' و'\n }\n }\n }\n }\n\n // Process tens and ones\n if (tens > 0) {\n if (tens < 20) { // 1 -> 19\n if (tens === 2 && hundreds === 0 && groupLevel > 0) {\n // Cache expensive log10 calculation\n const numValue = Number(fullNumber)\n const pow = Math.trunc(Math.log10(numValue))\n if (pow % 3 === 0 && fullNumber === BigInt(2 * Math.pow(10, pow))) {\n returnValue = groupNumber === 2 ? this.arabicTwos[groupLevel] : this.arabicAppendedTwos[groupLevel]\n } else {\n returnValue = this.arabicTwos[groupLevel]\n }\n } else if (tens === 1 && groupLevel > 0) {\n returnValue += this.arabicGroup[groupLevel]\n } else {\n returnValue += this.selectedOnes[tens - 1]\n }\n } else { // 20 -> 99\n const ones = tens % 10\n const tensIndex = Math.trunc(tens / 10) - 2\n\n if (ones > 0) {\n returnValue += this.selectedOnes[ones - 1]\n returnValue += ' و'\n }\n returnValue += this.arabicTens[tensIndex]\n }\n }\n\n return returnValue\n }\n\n /**\n * Converts a number to its cardinal representation in Arabic.\n * It process by blocks of 3 digits.\n * @param {bigint} number - The number to convert.\n * @returns {string} The cardinal representation of the number in Arabic.\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n let temp = number\n let group = 0\n let result = ''\n\n // Process each group of 3 digits (right to left)\n while (temp > 0n) {\n const numberToProcess = Number(temp % 1000n)\n temp = temp / 1000n\n\n if (numberToProcess > 0) {\n const groupDescription = this.processArabicGroup(numberToProcess, group, number)\n\n if (groupDescription) {\n // Add group name for thousands, millions, etc.\n if (group > 0) {\n if (result) {\n result = ' و' + result\n }\n\n if (numberToProcess > 2) {\n const remainder = numberToProcess % 100\n if (remainder === 1) {\n result = this.arabicGroup[group] + ' ' + result\n } else if (numberToProcess >= 3 && numberToProcess <= 10) {\n result = this.arabicPluralGroups[group] + ' ' + result\n } else {\n result = (result ? this.arabicAppendedGroup[group] : this.arabicGroup[group]) + ' ' + result\n }\n }\n }\n\n // Add group description (prepend for RTL)\n result = groupDescription + ' ' + result\n }\n }\n\n group++\n }\n\n return result.replace(/\\s+/g, ' ').trim()\n }\n}\n\n/**\n * Converts a number to Arabic cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {ArabicOptions} [options={}] Configuration options.\n * @returns {string} The number expressed in Arabic words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Arabic(options).convertToWords(value)\n}\n","/**\n * Marathi language implementation for n2words\n *\n * Marathi uses Indian-style number grouping (3 digits, then 2-2 from right).\n * Numbers: शून्य (0), एक (1), दोन (2), तीन (3), चार (4), पाच (5)...\n *\n * @module lib/languages/mr\n * @example\n * import mr from './lib/languages/mr.js'\n * mr(42) // 'बेचाळीस'\n * mr(1000) // 'एक हजार'\n */\n\nimport SouthAsianLanguage from '../classes/south-asian-language.js'\n\n/**\n * Marathi language implementation\n * Extends SouthAsianLanguage for Indian-style grouping\n */\nclass MarathiLanguage extends SouthAsianLanguage {\n negativeWord = 'उणे'\n decimalSeparatorWord = 'दशांश'\n zeroWord = 'शून्य'\n hundredWord = 'शंभर'\n convertDecimalsPerDigit = true\n\n belowHundred = [\n 'शून्य',\n 'एक',\n 'दोन',\n 'तीन',\n 'चार',\n 'पाच',\n 'सहा',\n 'सात',\n 'आठ',\n 'नऊ',\n 'दहा',\n 'अकरा',\n 'बारा',\n 'तेरा',\n 'चौदा',\n 'पंधरा',\n 'सोळा',\n 'सतरा',\n 'अठरा',\n 'एकोणीस',\n 'वीस',\n 'एकवीस',\n 'बावीस',\n 'तेवीस',\n 'चोवीस',\n 'पंचवीस',\n 'सव्वीस',\n 'सत्तावीस',\n 'अठ्ठावीस',\n 'एकोणतीस',\n 'तीस',\n 'एकतीस',\n 'बत्तीस',\n 'तेहेतीस',\n 'चौतीस',\n 'पस्तीस',\n 'छत्तीस',\n 'सदतीस',\n 'अडतीस',\n 'एकोणचाळीस',\n 'चाळीस',\n 'एकेचाळीस',\n 'बेचाळीस',\n 'त्रेचाळीस',\n 'चव्वेचाळीस',\n 'पंचेचाळीस',\n 'सेहेचाळीस',\n 'सत्तेचाळीस',\n 'अठ्ठेचाळीस',\n 'एकोणपन्नास',\n 'पन्नास',\n 'एक्काव्वन',\n 'बावन्न',\n 'त्रेपन्न',\n 'चोपन्न',\n 'पंचाव्वन',\n 'छप्पन्न',\n 'सत्तावन्न',\n 'अठ्ठावन्न',\n 'एकोणसाठ',\n 'साठ',\n 'एकसष्ठ',\n 'बासष्ठ',\n 'त्रेसष्ठ',\n 'चौसष्ठ',\n 'पासष्ठ',\n 'सहासष्ठ',\n 'सदुसष्ठ',\n 'अडुसष्ठ',\n 'एकोणसत्तर',\n 'सत्तर',\n 'एकाहत्तर',\n 'बाहत्तर',\n 'त्र्याहत्तर',\n 'चौऱ्याहत्तर',\n 'पंच्याहत्तर',\n 'शहात्तर',\n 'सत्याहत्तर',\n 'अठ्ठ्याहत्तर',\n 'एकोणऐंशी',\n 'ऐंशी',\n 'एक्याऐंशी',\n 'ब्याऐंशी',\n 'त्र्याऐंशी',\n 'चौऱ्याऐंशी',\n 'पंच्याऐंशी',\n 'शहाऐंशी',\n 'सत्याऐंशी',\n 'अठ्ठ्याऐंशी',\n 'एकोणनव्वद',\n 'नव्वद',\n 'एक्याण्णव',\n 'ब्याण्णव',\n 'त्र्याण्णव',\n 'चौऱ्याण्णव',\n 'पंच्याण्णव',\n 'शहाण्णव',\n 'सत्याण्णव',\n 'अठ्ठ्याण्णव',\n 'नव्याण्णव'\n ]\n\n scaleWords = [\n '',\n 'हजार',\n 'लाख',\n 'कोटी',\n 'अब्ज',\n 'खर्व',\n 'निखर्व',\n 'महापद्म',\n 'शंकू'\n ]\n}\n\n/**\n * Convert a number to Marathi words\n *\n * @param {number|string|bigint} value - The number to convert\n * @param {Object} [options={}] - Conversion options\n * @returns {string} The Marathi word representation\n * @example\n * convertToWords(42) // 'बेचाळीस'\n * convertToWords(1000) // 'एक हजार'\n * convertToWords(100000) // 'एक लाख'\n */\nexport default function convertToWords (value, options = {}) {\n return new MarathiLanguage(options).convertToWords(value)\n}\n","'use strict';\nvar iteratorClose = require('../internals/iterator-close');\n\nmodule.exports = function (iters, kind, value) {\n for (var i = iters.length - 1; i >= 0; i--) {\n if (iters[i] === undefined) continue;\n try {\n value = iteratorClose(iters[i].iterator, kind, value);\n } catch (error) {\n kind = 'throw';\n value = error;\n }\n }\n if (kind === 'throw') throw value;\n return value;\n};\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Latvian language converter.\n *\n * Implements Latvian number words using the Slavic language pattern:\n * - Latvian number words (viens, divi, trīs, četri, pieci...)\n * - Latvian-specific pluralization patterns\n * - Baltic grammatical structure\n * - Simplified gender handling compared to Lithuanian\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic/Baltic languages\n * * Form 1 (singular): 1 (e.g., \"tūkstotis\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"tūkstoši\")\n * * Form 3 (many): all other numbers (e.g., \"tūkstošu\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n *\n * Features:\n * - Latvian diacritical marks (ī, ā, ē, ū, etc.)\n * - Three-form pluralization (adapted for Latvian)\n * - Baltic number naming conventions\n * - Compound number formation (divdesmit, trīsdesmit)\n *\n * Inherits from SlavicLanguage for pluralization algorithms.\n */\nexport class Latvian extends SlavicLanguage {\n negativeWord = 'mīnus'\n decimalSeparatorWord = 'komats'\n zeroWord = 'nulle'\n ones = {\n 1: 'viens',\n 2: 'divi',\n 3: 'trīs',\n 4: 'četri',\n 5: 'pieci',\n 6: 'seši',\n 7: 'septiņi',\n 8: 'astoņi',\n 9: 'deviņi'\n }\n\n tens = {\n 0: 'desmit',\n 1: 'vienpadsmit',\n 2: 'divpadsmit',\n 3: 'trīspadsmit',\n 4: 'četrpadsmit',\n 5: 'piecpadsmit',\n 6: 'sešpadsmit',\n 7: 'septiņpadsmit',\n 8: 'astoņpadsmit',\n 9: 'deviņpadsmit'\n }\n\n twenties = {\n 2: 'divdesmit',\n 3: 'trīsdesmit',\n 4: 'četrdesmit',\n 5: 'piecdesmit',\n 6: 'sešdesmit',\n 7: 'septiņdesmit',\n 8: 'astoņdesmit',\n 9: 'deviņdesmit'\n }\n\n hundreds = ['simts', 'simti', 'simtu']\n\n thousands = {\n 1: ['tūkstotis', 'tūkstoši', 'tūkstošu'],\n 2: ['miljons', 'miljoni', 'miljonu'],\n 3: ['miljards', 'miljardi', 'miljardu'],\n 4: ['triljons', 'triljoni', 'triljonu'],\n 5: ['kvadriljons', 'kvadriljoni', 'kvadriljonu'],\n 6: ['kvintiljons', 'kvintiljoni', 'kvintiljonu'],\n 7: ['sikstiljons', 'sikstiljoni', 'sikstiljonu'],\n 8: ['septiljons', 'septiljoni', 'septiljonu'],\n 9: ['oktiljons', 'oktiljoni', 'oktiljonu'],\n 10: ['nontiljons', 'nontiljoni', 'nontiljonu']\n }\n\n pluralize (n, forms) {\n if (n === 0n) {\n return forms[2]\n }\n\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n if (lastDigit === 1n && lastTwoDigits !== 11n) {\n return forms[0]\n }\n\n return forms[1]\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n if (x === 0n) {\n continue\n }\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0n) {\n if (n3 === 1n && n2 === 0n && n1 > 0n) {\n words.push(this.hundreds[2])\n } else if (n3 > 1n) {\n words.push(this.ones[n3], this.hundreds[1])\n } else {\n words.push(this.hundreds[0])\n }\n }\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n && !(index > 0 && x === 1n)) {\n words.push(this.ones[n1])\n }\n if (index > 0) {\n words.push(this.pluralize(x, this.thousands[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Latvian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Latvian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Latvian(options).convertToWords(value)\n}\n","import SouthAsianLanguage from '../classes/south-asian-language.js'\n\nclass Punjabi extends SouthAsianLanguage {\n negativeWord = 'ਮਾਇਨਸ'\n decimalSeparatorWord = 'ਦਸ਼ਮਲਵ'\n zeroWord = 'ਸਿਫ਼ਰ'\n hundredWord = 'ਸੌ'\n belowHundred = [\n 'ਸਿਫ਼ਰ',\n 'ਇੱਕ',\n 'ਦੋ',\n 'ਤਿੰਨ',\n 'ਚਾਰ',\n 'ਪੰਜ',\n 'ਛੇ',\n 'ਸੱਤ',\n 'ਅੱਠ',\n 'ਨੌਂ',\n 'ਦੱਸ',\n 'ਗਿਆਰਾਂ',\n 'ਬਾਰਾਂ',\n 'ਤੇਰਾਂ',\n 'ਚੌਦਾਂ',\n 'ਪੰਦਰਾਂ',\n 'ਸੋਲਾਂ',\n 'ਸਤਾਰਾਂ',\n 'ਅਠਾਰਾਂ',\n 'ਉੱਨੀ',\n 'ਵੀਹ',\n 'ਇੱਕੀ',\n 'ਬਾਈ',\n 'ਤੇਈ',\n 'ਚੌਬੀ',\n 'ਪੱਚੀ',\n 'ਛੱਬੀ',\n 'ਸਤਾਈ',\n 'ਅਠਾਈ',\n 'ਉਨੱਤੀ',\n 'ਤੀਹ',\n 'ਇਕੱਤੀ',\n 'ਬੱਤੀ',\n 'ਤੇਤੀ',\n 'ਚੌਂਤੀ',\n 'ਪੈਂਤੀ',\n 'ਛੱਤੀ',\n 'ਸੈਂਤੀ',\n 'ਅਠੱਤੀ',\n 'ਉਨਤਾਲੀ',\n 'ਚਾਲੀ',\n 'ਇਕਤਾਲੀ',\n 'ਬਿਆਲੀ',\n 'ਤਿਰਤਾਲੀ',\n 'ਚੁਵਾਲੀ',\n 'ਪੰਤਾਲੀ',\n 'ਛਿਆਲੀ',\n 'ਸੈਂਤਾਲੀ',\n 'ਅਠਤਾਲੀ',\n 'ਉਨੰਜਾ',\n 'ਪੰਜਾਹ',\n 'ਇਕਵੰਜਾ',\n 'ਬਵੰਜਾ',\n 'ਤਰਵੰਜਾ',\n 'ਚੁਰਵੰਜਾ',\n 'ਪੰਜਵੰਜਾ',\n 'ਛਪੰਜਾ',\n 'ਸੱਤਵੰਜਾ',\n 'ਅਠਵੰਜਾ',\n 'ਉਨਾਹਠ',\n 'ਸੱਠ',\n 'ਇਕਾਹਠ',\n 'ਬਾਹਠ',\n 'ਤਰਸਠ',\n 'ਚੌਂਸਠ',\n 'ਪੈਂਸਠ',\n 'ਛਿਆਸਠ',\n 'ਸੜਸਠ',\n 'ਅੜਸਠ',\n 'ਉਣਹੱਤਰ',\n 'ਸਤੱਰ',\n 'ਇਕਹੱਤਰ',\n 'ਬਹੱਤਰ',\n 'ਤਹੱਤਰ',\n 'ਚੌਹੱਤਰ',\n 'ਪੰਝਹੱਤਰ',\n 'ਛਿਹੱਤਰ',\n 'ਸਤੱਤਰ',\n 'ਅਠੱਤਰ',\n 'ਉਨਾਸੀ',\n 'ਅੱਸੀ',\n 'ਇਕਿਆਸੀ',\n 'ਬਿਆਸੀ',\n 'ਤਰਿਆਸੀ',\n 'ਚੌਰਿਆਸੀ',\n 'ਪਚਾਸੀ',\n 'ਛਿਆਸੀ',\n 'ਸੱਤਾਸੀ',\n 'ਅਠਾਸੀ',\n 'ਨਵਾਸੀ',\n 'ਨੱਬੇ',\n 'ਇਕਾਨਵੇਂ',\n 'ਬਾਨਵੇਂ',\n 'ਤਰਾਨਵੇਂ',\n 'ਚੁਰਾਨਵੇਂ',\n 'ਪੰਚਾਨਵੇਂ',\n 'ਛਿਆਨਵੇਂ',\n 'ਸਤਾਨਵੇਂ',\n 'ਅਠਾਨਵੇਂ',\n 'ਨਿਨਾਨਵੇਂ'\n ]\n\n scaleWords = [\n '',\n 'ਹਜ਼ਾਰ',\n 'ਲੱਖ',\n 'ਕਰੋੜ',\n 'ਅਰਬ',\n 'ਖਰਬ',\n 'ਨੀਲ',\n 'ਪਦਮ',\n 'ਸ਼ੰਖ'\n ]\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Punjabi(options).convertToWords(value)\n}\n","import AbstractLanguage from './abstract-language.js'\n\n/**\n * @typedef {Array<string>} SouthAsianScaleWords\n * Array of scale words for the Indian numbering system, in ascending order.\n * - Index 0: Usually empty/unused (ones place)\n * - Index 1: Thousands (hazaar/হাজার/हजार)\n * - Index 2: Lakhs (lakh/লাখ/लाख)\n * - Index 3: Crores (crore/কোটি/करोड़)\n * - Index 4: Arabs (arab/আরব/अरब)\n * Each index i represents the scale word for groups at position i in the Indian system.\n */\n\n/**\n * @typedef {Array<string>} SouthAsianBelowHundred\n * Array of words for numbers 0-99, indexed directly.\n * belowHundred[0] = word for 0, belowHundred[42] = word for 42, etc.\n */\n\n/**\n * Base class for South Asian languages with shared grouping patterns.\n *\n * This class provides a reusable implementation for South Asian languages that share:\n * - Indian-style number grouping: last 3 digits, then 2-2 (1,23,45,67,89)\n * - Lakh (100,000), Crore (10,000,000), Arab (1,000,000,000) scale words\n * - Standard negative and decimal handling (inherits AbstractLanguage decimal logic,\n * including `convertDecimalsPerDigit` support when set by subclasses)\n *\n * Used by: Hindi (hi), Bengali (bn), Urdu (ur), Punjabi (pa), Marathi (mr), Gujarati (gu), Kannada (kn)\n *\n * Subclasses MUST define language-specific vocabulary via class properties:\n * - `belowHundred` array with digit and teen words (0-99)\n * - `hundredWord` string used inside `convertBelowThousand`\n * - `scaleWords` array with grouping words (hazaar, lakh, crore, etc.) indexed by grouping level\n * - `negativeWord`, `decimalSeparatorWord`, `zeroWord`, `wordSeparator`\n *\n * @abstract\n * @extends AbstractLanguage\n */\nclass SouthAsianLanguage extends AbstractLanguage {\n /**\n * Array of words for numbers 0-99 (digits and teens).\n * Index directly: belowHundred[0] through belowHundred[99].\n * @type {Array<string>}\n */\n belowHundred\n\n /**\n * Word for \"hundred\" in the language (e.g., 'सौ' in Hindi, 'শত' in Bengali).\n * Used to construct hundreds (e.g., \"1 hundred\", \"2 hundred\").\n * @type {string}\n */\n hundredWord\n\n /**\n * Array of scale words for Indian-style grouping (hazaar, lakh, crore, arab, etc.).\n * Index 0 is typically unused (ones place, no scale word).\n * Index 1 is for thousands, Index 2 for lakhs, Index 3 for crores, etc.\n * @type {Array<string>}\n */\n scaleWords\n\n /**\n * Split a number into Indian numbering system groups.\n *\n * The Indian system groups differently than Western (3-3-3) systems:\n * - First group (rightmost): Up to 3 digits (ones, tens, hundreds)\n * - Subsequent groups: Exactly 2 digits each (thousands, lakhs, crores, etc.)\n *\n * This creates the familiar Indian comma pattern: 1,23,45,67,890\n *\n * @protected\n * @param {bigint} number The number to split into groups\n * @returns {Array<number>} Array of groups from most significant to least significant\n *\n * @example\n * // splitToGroups(1234567n) → [12, 34, 567]\n * // Reads as: 12 lakhs, 34 thousands, 567 units\n * // splitToGroups(98765432n) → [9, 87, 65, 432]\n * // Reads as: 9 crores, 87 lakhs, 65 thousands, 432 units\n */\n splitToGroups (number) {\n const numStr = number.toString()\n\n if (numStr.length <= 3) {\n return [Number(numStr)]\n }\n\n const groups = []\n const last3 = numStr.slice(-3)\n groups.unshift(Number(last3))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n const group = remaining.slice(-2)\n groups.unshift(Number(group))\n remaining = remaining.slice(0, -2)\n }\n\n return groups\n }\n\n /**\n * Convert a number below 1000 to words (0-999).\n *\n * @protected\n * @param {number} number Value between 0 and 999\n * @returns {string} Language-specific word representation\n */\n convertBelowThousand (number) {\n if (number === 0) return ''\n if (number < 100) return this.belowHundred[number]\n\n const hundreds = Math.trunc(number / 100)\n const remainder = number % 100\n const parts = []\n\n if (hundreds === 1) {\n parts.push(this.belowHundred[1] + ' ' + this.hundredWord)\n } else {\n parts.push(this.belowHundred[hundreds] + ' ' + this.hundredWord)\n }\n\n if (remainder > 0) {\n parts.push(this.belowHundred[remainder])\n }\n\n return parts.join(' ')\n }\n\n /**\n * Convert whole number to cardinal words using South Asian grouping.\n *\n * @param {bigint} number Number to convert\n * @returns {string} Cardinal representation\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n\n const groups = this.splitToGroups(number)\n const groupCount = groups.length\n const words = []\n\n for (let i = 0; i < groupCount; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n const scaleIndex = groupCount - i - 1\n words.push(this.convertBelowThousand(groupValue))\n if (scaleIndex > 0 && this.scaleWords[scaleIndex]) {\n words.push(this.scaleWords[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n }\n}\n\nexport default SouthAsianLanguage\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} HebrewOptions\n * @property {string} [and='ו'] Conjunction character (typically 'ו' for and).\n * @property {boolean} [biblical=false] Use biblical scale words instead of modern ones.\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Hebrew language converter.\n *\n * Implements Hebrew number words using the Slavic language pattern:\n * - Hebrew alphabet and right-to-left text\n * - Hebrew number words (אחת, שתים, שלוש, ארבע...)\n * - Feminine number forms (default in Hebrew)\n * - Optional \"ve\" (ו, \"and\") conjunction between number groups\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"אלף\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"אלפים\")\n * * Form 3 (many): all other numbers (e.g., \"אלף\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n *\n * Features:\n * - Right-to-left text orientation\n * - Feminine grammatical gender for numbers\n * - Three-form pluralization (similar to Slavic pattern)\n * - Conjunction control via \"and\" option\n *\n * Inherits from SlavicLanguage for complex pluralization algorithms.\n */\nexport class Hebrew extends SlavicLanguage {\n negativeWord = 'מינוס'\n decimalSeparatorWord = 'נקודה'\n zeroWord = 'אפס'\n convertDecimalsPerDigit = true\n\n // Modern Hebrew (feminine forms)\n ones = {\n 1: 'אחת',\n 2: 'שתים',\n 3: 'שלש',\n 4: 'ארבע',\n 5: 'חמש',\n 6: 'שש',\n 7: 'שבע',\n 8: 'שמונה',\n 9: 'תשע'\n }\n\n tens = {\n 0: 'עשר',\n 1: 'אחת עשרה',\n 2: 'שתים עשרה',\n 3: 'שלש עשרה',\n 4: 'ארבע עשרה',\n 5: 'חמש עשרה',\n 6: 'שש עשרה',\n 7: 'שבע עשרה',\n 8: 'שמונה עשרה',\n 9: 'תשע עשרה'\n }\n\n twenties = {\n 2: 'עשרים',\n 3: 'שלשים',\n 4: 'ארבעים',\n 5: 'חמישים',\n 6: 'ששים',\n 7: 'שבעים',\n 8: 'שמונים',\n 9: 'תשעים'\n }\n\n hundreds = {\n 1: 'מאה',\n 2: 'מאתיים',\n 3: 'מאות'\n }\n\n thousands = {\n 1: 'אלף',\n 2: 'אלפיים',\n 3: 'שלשת אלפים',\n 4: 'ארבעת אלפים',\n 5: 'חמשת אלפים',\n 6: 'ששת אלפים',\n 7: 'שבעת אלפים',\n 8: 'שמונת אלפים',\n 9: 'תשעת אלפים'\n }\n\n scale = {\n 1: 'אלף', // thousand (singular)\n 2: 'מיליון', // million\n 3: 'מיליארד', // billion\n 4: 'טריליון', // trillion\n 5: 'קוודרליון', // quadrillion\n 6: 'קווינטיליון' // quintillion\n }\n\n scalePlural = {\n 1: 'אלפים', // thousands\n 2: 'מיליונים', // millions\n 3: 'מיליארדים', // billions\n 4: 'טריליונים', // trillions\n 5: 'קוודרליונים', // quadrillions\n 6: 'קווינטיליונים' // quintillions\n }\n\n // Biblical Hebrew (masculine forms)\n biblicalOnes = {\n 1: 'אחד',\n 2: 'שניים',\n 3: 'שלשה',\n 4: 'ארבעה',\n 5: 'חמשה',\n 6: 'ששה',\n 7: 'שבעה',\n 8: 'שמונה',\n 9: 'תשעה'\n }\n\n biblicalTens = {\n 0: 'עשרה',\n 1: 'אחד עשר',\n 2: 'שנים עשר',\n 3: 'שלשה עשר',\n 4: 'ארבעה עשר',\n 5: 'חמשה עשר',\n 6: 'ששה עשר',\n 7: 'שבעה עשר',\n 8: 'שמונה עשר',\n 9: 'תשעה עשר'\n }\n\n biblicalTwenties = {\n 2: 'עשרים',\n 3: 'שלשים',\n 4: 'ארבעים',\n 5: 'חמישים',\n 6: 'ששים',\n 7: 'שבעים',\n 8: 'שמונים',\n 9: 'תשעים'\n }\n\n biblicalHundreds = {\n 1: 'מאה',\n 2: 'מאתיים',\n 3: 'מאות'\n }\n\n biblicalThousands = {\n 1: 'אלף',\n 2: 'אלפיים',\n 3: 'שלשת אלפים',\n 4: 'ארבעת אלפים',\n 5: 'חמשת אלפים',\n 6: 'ששת אלפים',\n 7: 'שבעת אלפים',\n 8: 'שמונת אלפים',\n 9: 'תשעת אלפים'\n }\n\n biblicalScale = {\n 1: 'אלף',\n 2: 'מיליון',\n 3: 'מיליארד',\n 4: 'טריליון',\n 5: 'קוודרליון',\n 6: 'קווינטיליון'\n }\n\n biblicalScalePlural = {\n 1: 'אלפים',\n 2: 'מיליונים',\n 3: 'מיליארדים',\n 4: 'טריליונים',\n 5: 'קוודרליונים',\n 6: 'קווינטיליונים'\n }\n\n /**\n * Initializes the Hebrew converter with language-specific options.\n *\n * @param {HebrewOptions} [options={}] Configuration options.\n */\n constructor ({ and = 'ו', biblical = false, feminine = false } = {}) {\n super({ feminine })\n\n this.and = and\n this.feminine = feminine\n\n this.biblical = biblical\n if (this.biblical) {\n this.ones = this.biblicalOnes\n this.tens = this.biblicalTens\n this.twenties = this.biblicalTwenties\n this.hundreds = this.biblicalHundreds\n this.thousands = this.biblicalThousands\n this.scale = this.biblicalScale\n this.scalePlural = this.biblicalScalePlural\n }\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n if (x === 0n) {\n continue\n }\n\n const [n1, n2, n3] = this.getDigits(x)\n\n if (index > 0) {\n // For thousands and above, handle the full chunk value\n const chunkWords = []\n let hasHundreds = false\n\n // Process hundreds in this chunk\n if (n3 > 0n) {\n hasHundreds = true\n if (n3 <= 2n) {\n chunkWords.push(this.hundreds[n3])\n } else {\n chunkWords.push(this.ones[n3] + ' ' + this.hundreds[3])\n }\n }\n\n // Process tens in this chunk\n if (n2 > 1n) {\n // Add conjunction if there were hundreds before\n const tensWord = this.twenties[n2]\n chunkWords.push(hasHundreds ? this.and + tensWord : tensWord)\n }\n\n // Process ones in this chunk\n if (n2 === 1n) {\n // Add conjunction if there were hundreds before\n const onesWord = this.tens[n1]\n chunkWords.push(hasHundreds ? this.and + onesWord : onesWord)\n } else if (n1 > 0n) {\n // For \"one million\", \"one billion\", etc., don't add the word \"one\"\n if (x === 1n && index > 1) {\n // Skip adding \"one\" for millions/billions/etc.\n } else if (x <= 9n && chunkWords.length === 0 && index === 1) {\n // Use special forms for 1-9 thousand\n chunkWords.push(this.thousands[n1])\n } else {\n const onesWord = this.ones[n1]\n // Add conjunction if there were hundreds or tens before\n chunkWords.push((hasHundreds || n2 > 0n) ? this.and + onesWord : onesWord)\n }\n }\n\n // Add scale word (thousand, million, billion, etc.)\n if (x > 9n || index > 1) {\n // For numbers > 9 or higher scales, use appropriate scale word\n if (x === 1n) {\n // Singular form (e.g., \"one thousand\", \"one million\")\n chunkWords.push(this.scale[index])\n } else if (x === 2n && index === 1) {\n // Special dual form for \"two thousand\" (already in thousands[2])\n return [this.thousands[2], ...words].join(' ')\n } else if (x === 2n) {\n // For two million, two billion, etc. - use plural form\n chunkWords.push(this.scalePlural[index])\n } else if (index === 1) {\n // For thousands (10+), always use singular \"אלף\"\n chunkWords.push(this.scale[index])\n } else {\n // For millions/billions/etc. use plural form\n chunkWords.push(this.scalePlural[index])\n }\n }\n\n words.push(chunkWords.join(' '))\n continue\n }\n\n if (n3 > 0n) {\n if (n3 <= 2n) {\n words.push(this.hundreds[n3])\n } else {\n words.push(this.ones[n3] + ' ' + this.hundreds[3])\n }\n }\n\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n) {\n words.push(this.ones[n1])\n }\n }\n\n if (words.length > 1) {\n words[words.length - 1] = this.and + words.at(-1)\n }\n\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Hebrew cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {HebrewOptions} [options={}] Configuration options.\n * @returns {string} The number expressed in Hebrew words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Hebrew(options).convertToWords(value)\n}\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n","'use strict';\nvar $ = require('../internals/export');\nvar union = require('../internals/set-union');\nvar setMethodGetKeysBeforeCloning = require('../internals/set-method-get-keys-before-cloning-detection');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar FORCED = !setMethodAcceptSetLike('union') || !setMethodGetKeysBeforeCloning('union');\n\n// `Set.prototype.union` method\n// https://tc39.es/ecma262/#sec-set.prototype.union\n$({ target: 'Set', proto: true, real: true, forced: FORCED }, {\n union: union\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar call = require('../internals/function-call');\nvar aCallable = require('../internals/a-callable');\nvar anObject = require('../internals/an-object');\nvar getIteratorDirect = require('../internals/get-iterator-direct');\nvar createIteratorProxy = require('../internals/iterator-create-proxy');\nvar callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing');\nvar iteratorClose = require('../internals/iterator-close');\nvar iteratorHelperThrowsOnInvalidIterator = require('../internals/iterator-helper-throws-on-invalid-iterator');\nvar iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');\nvar IS_PURE = require('../internals/is-pure');\n\nvar MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('map', function () { /* empty */ });\nvar mapWithoutClosingOnEarlyError = !IS_PURE && !MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR\n && iteratorHelperWithoutClosingOnEarlyError('map', TypeError);\n\nvar FORCED = IS_PURE || MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR || mapWithoutClosingOnEarlyError;\n\nvar IteratorProxy = createIteratorProxy(function () {\n var iterator = this.iterator;\n var result = anObject(call(this.next, iterator));\n var done = this.done = !!result.done;\n if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true);\n});\n\n// `Iterator.prototype.map` method\n// https://tc39.es/ecma262/#sec-iterator.prototype.map\n$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {\n map: function map(mapper) {\n anObject(this);\n try {\n aCallable(mapper);\n } catch (error) {\n iteratorClose(this, 'throw', error);\n }\n\n if (mapWithoutClosingOnEarlyError) return call(mapWithoutClosingOnEarlyError, this, mapper);\n\n return new IteratorProxy(getIteratorDirect(this), {\n mapper: mapper\n });\n }\n});\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Ukrainian language converter.\n *\n * Implements Ukrainian number words using the Slavic language pattern:\n * - Ukrainian number words (один/одна, два/дві, три, чотири...)\n * - Gender-aware forms (masculine/feminine)\n * - Slavic three-form pluralization (тисяча/тисячі/тисяч)\n * - Ukrainian orthography and phonology\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"тисяча\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"тисячі\")\n * * Form 3 (many): all other numbers (e.g., \"тисяч\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n *\n * Features:\n * - Ukrainian-specific letters (і, ї, ґ, є)\n * - Apostrophe usage (п'ять, дев'ять)\n * - Close structural similarity to Russian with distinct vocabulary\n *\n * Inherits from SlavicLanguage for complex pluralization algorithms.\n */\nexport class Ukrainian extends SlavicLanguage {\n negativeWord = 'мiнус'\n decimalSeparatorWord = 'кома'\n zeroWord = 'нуль'\n ones = {\n 1: 'один',\n 2: 'два',\n 3: 'три',\n 4: 'чотири',\n 5: 'п\\'ять',\n 6: 'шiсть',\n 7: 'сiм',\n 8: 'вiсiм',\n 9: 'дев\\'ять'\n }\n\n onesFeminine = {\n 1: 'одна',\n 2: 'двi',\n 3: 'три',\n 4: 'чотири',\n 5: 'п\\'ять',\n 6: 'шiсть',\n 7: 'сiм',\n 8: 'вiсiм',\n 9: 'дев\\'ять'\n }\n\n tens = {\n 0: 'десять',\n 1: 'одинадцять',\n 2: 'дванадцять',\n 3: 'тринадцять',\n 4: 'чотирнадцять',\n 5: 'п\\'ятнадцять',\n 6: 'шiстнадцять',\n 7: 'сiмнадцять',\n 8: 'вiсiмнадцять',\n 9: 'дев\\'ятнадцять'\n }\n\n twenties = {\n 2: 'двадцять',\n 3: 'тридцять',\n 4: 'сорок',\n 5: 'п\\'ятдесят',\n 6: 'шiстдесят',\n 7: 'сiмдесят',\n 8: 'вiсiмдесят',\n 9: 'дев\\'яносто'\n }\n\n hundreds = {\n 1: 'сто',\n 2: 'двiстi',\n 3: 'триста',\n 4: 'чотириста',\n 5: 'п\\'ятсот',\n 6: 'шiстсот',\n 7: 'сiмсот',\n 8: 'вiсiмсот',\n 9: 'дев\\'ятсот'\n }\n\n thousands = {\n 1: ['тисяча', 'тисячi', 'тисяч'], // 10^ 3\n 2: ['мiльйон', 'мiльйони', 'мiльйонiв'], // 10^ 6\n 3: ['мiльярд', 'мiльярди', 'мiльярдiв'], // 10^ 9\n 4: ['трильйон', 'трильйони', 'трильйонiв'], // 10^ 12\n 5: ['квадрильйон', 'квадрильйони', 'квадрильйонiв'], // 10^ 15\n 6: ['квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'], // 10^ 18\n 7: ['секстильйон', 'секстильйони', 'секстильйонiв'], // 10^ 21\n 8: ['септильйон', 'септильйони', 'септильйонiв'], // 10^ 24\n 9: ['октильйон', 'октильйони', 'октильйонiв'], // 10^ 27\n 10: ['нонiльйон', 'нонiльйони', 'нонiльйонiв'] // 10^ 30\n }\n}\n\n/**\n * Converts a number to Ukrainian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Ukrainian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Ukrainian(options).convertToWords(value)\n}\n","'use strict';\n// `GetIteratorDirect(obj)` abstract operation\n// https://tc39.es/ecma262/#sec-getiteratordirect\nmodule.exports = function (obj) {\n return {\n iterator: obj,\n next: obj.next,\n done: false\n };\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar hasOwn = require('../internals/has-own-property');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar indexOf = require('../internals/array-includes').indexOf;\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n","import SouthAsianLanguage from '../classes/south-asian-language.js'\n\nclass Urdu extends SouthAsianLanguage {\n negativeWord = 'منفی'\n decimalSeparatorWord = 'اعشاریہ'\n zeroWord = 'صفر'\n hundredWord = 'سو'\n belowHundred = [\n 'صفر',\n 'ایک',\n 'دو',\n 'تین',\n 'چار',\n 'پانچ',\n 'چھ',\n 'سات',\n 'آٹھ',\n 'نو',\n 'دس',\n 'گیارہ',\n 'بارہ',\n 'تیرہ',\n 'چودہ',\n 'پندرہ',\n 'سولہ',\n 'سترہ',\n 'اٹھارہ',\n 'انیس',\n 'بیس',\n 'اکیس',\n 'بائیس',\n 'تیئیس',\n 'چوبیس',\n 'پچیس',\n 'چھبیس',\n 'ستائیس',\n 'اٹھائیس',\n 'انتیس',\n 'تیس',\n 'اکتیس',\n 'بتیس',\n 'تینتیس',\n 'چونتیس',\n 'پینتیس',\n 'چھتیس',\n 'سینتیس',\n 'اڑتیس',\n 'انتالیس',\n 'چالیس',\n 'اکتالیس',\n 'بیالیس',\n 'تینتالیس',\n 'چوالیس',\n 'پینتالیس',\n 'چھالیس',\n 'سینتالیس',\n 'اڑتالیس',\n 'انچاس',\n 'پچاس',\n 'اکاون',\n 'باون',\n 'ترپن',\n 'چون',\n 'پچپن',\n 'چھپن',\n 'ستاون',\n 'اٹھاون',\n 'انسٹھ',\n 'ساٹھ',\n 'اکسٹھ',\n 'باسٹھ',\n 'ترسٹھ',\n 'چونسٹھ',\n 'پینسٹھ',\n 'چھیاسٹھ',\n 'سڑسٹھ',\n 'اڑسٹھ',\n 'انہتر',\n 'ستر',\n 'اکہتر',\n 'بہتر',\n 'تہتر',\n 'چوہتر',\n 'پچھتر',\n 'چھہتر',\n 'ستتر',\n 'اٹھہتر',\n 'اناسی',\n 'اسی',\n 'اکیاسی',\n 'بیاسی',\n 'تریاسی',\n 'چوراسی',\n 'پچاسی',\n 'چھیاسی',\n 'ستاسی',\n 'اٹھاسی',\n 'نواسی',\n 'نوے',\n 'اکانوے',\n 'بانوے',\n 'ترانوے',\n 'چورانوے',\n 'پچانوے',\n 'چھیانوے',\n 'ستانوے',\n 'اٹھانوے',\n 'ننانوے'\n ]\n\n scaleWords = [\n '',\n 'ہزار',\n 'لاکھ',\n 'کروڑ',\n 'ارب',\n 'کھرب',\n 'نیل',\n 'پدم',\n 'شنکھ'\n ]\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Urdu(options).convertToWords(value)\n}\n","'use strict';\nvar makeBuiltIn = require('../internals/make-built-in');\nvar defineProperty = require('../internals/object-define-property');\n\nmodule.exports = function (target, name, descriptor) {\n if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true });\n if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true });\n return defineProperty.f(target, name, descriptor);\n};\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n// eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * @typedef {Object} FrenchOptions\n * @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds.\n */\n\n/**\n * French language converter.\n *\n * Special handling:\n * - Pluralization of \"cent\" (hundred) and other words\n * - \"et\" (and) before odd numbers in tens place\n * - Hyphenation for compound numbers\n * - Regional number word variations\n */\nexport class French extends GreedyScaleLanguage {\n negativeWord = 'moins'\n decimalSeparatorWord = 'virgule'\n zeroWord = 'zéro'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'quadrilliard'],\n [1_000_000_000_000_000_000_000_000n, 'quadrillion'],\n [1_000_000_000_000_000_000_000n, 'trilliard'],\n [1_000_000_000_000_000_000n, 'trillion'],\n [1_000_000_000_000_000n, 'billiard'],\n [1_000_000_000_000n, 'billion'],\n [1_000_000_000n, 'milliard'],\n [1_000_000n, 'million'],\n [1000n, 'mille'],\n [100n, 'cent'],\n [],\n [80n, 'quatre-vingts'],\n [],\n [60n, 'soixante'],\n [50n, 'cinquante'],\n [40n, 'quarante'],\n [30n, 'trente'],\n [20n, 'vingt'],\n [19n, 'dix-neuf'],\n [18n, 'dix-huit'],\n [17n, 'dix-sept'],\n [16n, 'seize'],\n [15n, 'quinze'],\n [14n, 'quatorze'],\n [13n, 'treize'],\n [12n, 'douze'],\n [11n, 'onze'],\n [10n, 'dix'],\n [9n, 'neuf'],\n [8n, 'huit'],\n [7n, 'sept'],\n [6n, 'six'],\n [5n, 'cinq'],\n [4n, 'quatre'],\n [3n, 'trois'],\n [2n, 'deux'],\n [1n, 'un'],\n [0n, 'zéro']\n ]\n\n /**\n * Initializes the French converter with language-specific options.\n *\n * @param {FrenchOptions} [options={}] Configuration options.\n */\n constructor ({ withHyphenSeparator = false } = {}) {\n super()\n\n this.withHyphenSeparator = withHyphenSeparator\n\n if (this.withHyphenSeparator) {\n this.wordSeparator = '-'\n }\n }\n\n /**\n * Merges two adjacent word-number pairs according to French grammar rules.\n *\n * French-specific rules:\n * - Removes trailing 's' from multiples of 80 or 100 when followed by smaller numbers\n * - Adds 's' to hundreds when appropriate\n * - Uses \"et\" (and) when joining odd numbers to tens (e.g., \"vingt et un\")\n * - Hyphens for compound tens (e.g., \"vingt-deux\")\n *\n * @param {Object} currentPair The left operand as `{ word: number }`.\n * @param {Object} nextPair The right operand as `{ word: number }`.\n * @returns {Object} Merged pair with combined word and resulting number.\n */\n mergeScales (currentPair, nextPair) {\n let currentWord = Object.keys(currentPair)[0]\n let nextWord = Object.keys(nextPair)[0]\n const currentNumber = Object.values(currentPair)[0]\n const nextNumber = Object.values(nextPair)[0]\n\n if (currentNumber === 1n) {\n if (nextNumber < 1_000_000n) {\n return nextPair\n }\n } else {\n if (\n ((currentNumber - 80n) % 100n === 0n || (currentNumber % 100n === 0n && currentNumber < 1000n)) &&\n nextNumber < 1_000_000n &&\n currentWord.at(-1) === 's'\n ) {\n currentWord = currentWord.slice(0, -1)\n }\n\n if (\n currentNumber < 1000n && nextNumber !== 1000n &&\n nextWord.at(-1) !== 's' &&\n nextNumber % 100n === 0n\n ) {\n nextWord += 's'\n }\n }\n\n if (nextNumber < currentNumber && currentNumber < 100n) {\n if (nextNumber % 10n === 1n && currentNumber !== 80n) {\n return { [`${currentWord}${this.wordSeparator}et${this.wordSeparator}${nextWord}`]: currentNumber + nextNumber }\n }\n return { [`${currentWord}-${nextWord}`]: currentNumber + nextNumber }\n }\n\n if (nextNumber > currentNumber) return { [`${currentWord}${this.wordSeparator}${nextWord}`]: currentNumber * nextNumber }\n return { [`${currentWord}${this.wordSeparator}${nextWord}`]: currentNumber + nextNumber }\n }\n}\n\n/**\n * Converts a number to French cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see FR class).\n * @returns {string} The number expressed in French words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42, { lang: 'fr' }); // 'quarante-deux'\n * convertToWords(81, { lang: 'fr' }); // 'quatre-vingt-un'\n */\nexport default function convertToWords (value, options = {}) {\n return new French(options).convertToWords(value)\n}\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n function F() { /* empty */ }\n F.prototype.constructor = null;\n // eslint-disable-next-line es/no-object-getprototypeof -- required for testing\n return Object.getPrototypeOf(new F()) !== F.prototype;\n});\n","'use strict';\n/* global ActiveXObject -- old IE, WSH */\nvar anObject = require('../internals/an-object');\nvar definePropertiesModule = require('../internals/object-define-properties');\nvar enumBugKeys = require('../internals/enum-bug-keys');\nvar hiddenKeys = require('../internals/hidden-keys');\nvar html = require('../internals/html');\nvar documentCreateElement = require('../internals/document-create-element');\nvar sharedKey = require('../internals/shared-key');\n\nvar GT = '>';\nvar LT = '<';\nvar PROTOTYPE = 'prototype';\nvar SCRIPT = 'script';\nvar IE_PROTO = sharedKey('IE_PROTO');\n\nvar EmptyConstructor = function () { /* empty */ };\n\nvar scriptTag = function (content) {\n return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;\n};\n\n// Create object with fake `null` prototype: use ActiveX Object with cleared prototype\nvar NullProtoObjectViaActiveX = function (activeXDocument) {\n activeXDocument.write(scriptTag(''));\n activeXDocument.close();\n var temp = activeXDocument.parentWindow.Object;\n // eslint-disable-next-line no-useless-assignment -- avoid memory leak\n activeXDocument = null;\n return temp;\n};\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar NullProtoObjectViaIFrame = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = documentCreateElement('iframe');\n var JS = 'java' + SCRIPT + ':';\n var iframeDocument;\n iframe.style.display = 'none';\n html.appendChild(iframe);\n // https://github.com/zloirock/core-js/issues/475\n iframe.src = String(JS);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(scriptTag('document.F=Object'));\n iframeDocument.close();\n return iframeDocument.F;\n};\n\n// Check for document.domain and active x support\n// No need to use active x approach when document.domain is not set\n// see https://github.com/es-shims/es5-shim/issues/150\n// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346\n// avoid IE GC bug\nvar activeXDocument;\nvar NullProtoObject = function () {\n try {\n activeXDocument = new ActiveXObject('htmlfile');\n } catch (error) { /* ignore */ }\n NullProtoObject = typeof document != 'undefined'\n ? document.domain && activeXDocument\n ? NullProtoObjectViaActiveX(activeXDocument) // old IE\n : NullProtoObjectViaIFrame()\n : NullProtoObjectViaActiveX(activeXDocument); // WSH\n var length = enumBugKeys.length;\n while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];\n return NullProtoObject();\n};\n\nhiddenKeys[IE_PROTO] = true;\n\n// `Object.create` method\n// https://tc39.es/ecma262/#sec-object.create\n// eslint-disable-next-line es/no-object-create -- safe\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n EmptyConstructor[PROTOTYPE] = anObject(O);\n result = new EmptyConstructor();\n EmptyConstructor[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = NullProtoObject();\n return Properties === undefined ? result : definePropertiesModule.f(result, Properties);\n};\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * Malay (Bahasa Melayu) language converter.\n *\n * Conventions:\n * - Base-10 structure\n * - \"Se-\" prefix for singular units (seratus, seribu, sejuta, sebilion, setrilion)\n * - Space-separated components (no conjunction like \"dan\" for tens/ones)\n * - Grouping by thousands (ribu, juta, bilion, trilion)\n */\nexport class Malay extends AbstractLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'perpuluhan'\n zeroWord = 'sifar'\n base = {\n 0: [],\n 1: ['satu'],\n 2: ['dua'],\n 3: ['tiga'],\n 4: ['empat'],\n 5: ['lima'],\n 6: ['enam'],\n 7: ['tujuh'],\n 8: ['lapan'],\n 9: ['sembilan']\n }\n\n thousands = {\n 3: 'ribu',\n 6: 'juta',\n 9: 'bilion',\n 12: 'trilion'\n }\n\n splitBy3 (number) {\n const blocks = []\n const stringNumber = number.toString()\n const length = stringNumber.length\n let firstBlock\n\n if (length < 3) {\n blocks.push([stringNumber])\n } else {\n const firstBlockLength = length % 3\n\n if (firstBlockLength > 0) {\n firstBlock = [stringNumber.slice(0, firstBlockLength)]\n blocks.push(firstBlock)\n }\n\n for (let index = firstBlockLength; index < length; index += 3) {\n const nextBlock = [stringNumber.slice(index, index + 3)]\n blocks.push(nextBlock)\n }\n }\n return blocks\n }\n\n spell (blocks) {\n let wordBlocks = []\n let spelling\n const firstBlock = blocks[0]\n if (firstBlock[0].length === 1) {\n spelling = firstBlock[0] === '0' ? ['sifar'] : this.base[Math.trunc(firstBlock[0])]\n } else if (firstBlock[0].length === 2) {\n spelling = this.getTens(firstBlock[0])\n } else {\n spelling = [...this.getHundreds(firstBlock[0][0]), ...this.getTens(firstBlock[0].slice(1, 3))]\n }\n wordBlocks = [...wordBlocks, [firstBlock[0], spelling]]\n for (let index = 1; index < blocks.length; index++) {\n let block = blocks[index]\n spelling = [...this.getHundreds(block[0][0]), ...this.getTens(block[0].slice(1, 3))]\n block = [...block, spelling]\n wordBlocks = [...wordBlocks, block]\n }\n return wordBlocks\n }\n\n getHundreds (number) { // 'ratus'\n if (number === '1') {\n return ['seratus']\n } else if (number === '0') {\n return []\n } else {\n return [...this.base[Math.trunc(number)], 'ratus']\n }\n }\n\n getTens (number) { // 'puluh' and 'belas'\n if (number[0] === '1') {\n if (number[1] === '0') {\n return ['sepuluh']\n } else if (number[1] === '1') {\n return ['sebelas']\n }\n return [...this.base[Math.trunc(number[1])], 'belas']\n }\n\n if (number[0] === '0') {\n return this.base[Math.trunc(number[1])]\n }\n\n return [...this.base[Math.trunc(number[0])], 'puluh', ...this.base[Math.trunc(number[1])]]\n }\n\n join (wordBlocks) {\n const wordList = []\n const length = wordBlocks.length - 1\n\n for (let index = 0; index <= length; index++) {\n const words = wordBlocks[index][1]\n const isLast = index === length\n const scaleWord = isLast ? null : this.thousands[(length - index) * 3]\n\n if (!isLast && words.length === 1 && words[0] === 'satu') {\n // Use se- prefix for singular scale units: seribu, sejuta, sebilion, setrilion\n wordList.push('se' + scaleWord)\n continue\n }\n\n // Add current block words\n for (const w of words) wordList.push(w)\n\n // Append scale word if applicable and current block contributed words\n if (!isLast && words.length > 0) {\n wordList.push(scaleWord)\n }\n }\n\n return wordList.join(' ')\n }\n\n convertWholePart (number) {\n return this.join(\n this.spell(\n this.splitBy3(number)\n )\n ).trim()\n }\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Malay(options).convertToWords(value)\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar isSupersetOf = require('../internals/set-is-superset-of');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar INCORRECT = !setMethodAcceptSetLike('isSupersetOf', function (result) {\n return !result;\n});\n\n// `Set.prototype.isSupersetOf` method\n// https://tc39.es/ecma262/#sec-set.prototype.issupersetof\n$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, {\n isSupersetOf: isSupersetOf\n});\n","'use strict';\n// `CreateIterResultObject` abstract operation\n// https://tc39.es/ecma262/#sec-createiterresultobject\nmodule.exports = function (value, done) {\n return { value: value, done: done };\n};\n","import TurkicLanguage from '../classes/turkic-language.js'\n\n/**\n * Azerbaijani language converter.\n *\n * Inherits from TurkicLanguage shared patterns:\n * - Space-separated number combinations\n * - Omits '1' before hundreds and thousands\n * - Supports flexible word spacing configuration\n */\nexport class Azerbaijani extends TurkicLanguage {\n negativeWord = 'mənfi'\n decimalSeparatorWord = 'nöqtə'\n zeroWord = 'sıfır'\n scaleWordPairs = [[1_000_000_000_000_000_000n, 'kentilyon'],\n [1_000_000_000_000_000n, 'katrilyon'],\n [1_000_000_000_000n, 'trilyon'],\n [1_000_000_000n, 'milyar'],\n [1_000_000n, 'milyon'],\n [1000n, 'min'],\n [100n, 'yüz'],\n [90n, 'doxsan'],\n [80n, 'səksən'],\n [70n, 'yetmiş'],\n [60n, 'altmış'],\n [50n, 'əlli'],\n [40n, 'qırx'],\n [30n, 'otuz'],\n [20n, 'iyirmi'],\n [10n, 'on'],\n [9n, 'doqquz'],\n [8n, 'səkkiz'],\n [7n, 'yeddi'],\n [6n, 'altı'],\n [5n, 'beş'],\n [4n, 'dörd'],\n [3n, 'üç'],\n [2n, 'iki'],\n [1n, 'bir'],\n [0n, 'sıfır']]\n}\n\n/**\n * Converts a number to Azerbaijani cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see AZ class).\n * @returns {string} The number expressed in Azerbaijani words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42, { lang: 'az' }); // 'qırx iki'\n * convertToWords(1000, { lang: 'az' }); // 'min'\n */\nexport default function convertToWords (value, options = {}) {\n return new Azerbaijani(options).convertToWords(value)\n}\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Serbian language converter.\n *\n * Implements Serbian number words using the Slavic language pattern:\n * - Serbian number words (jedan/jedna, dva/dve, tri, četiri...)\n * - Gender-aware forms (masculine/feminine)\n * - Slavic three-form pluralization (hiljada/hiljade/hiljada)\n * - Latin script representation\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"hiljada\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"hiljade\")\n * * Form 3 (many): all other numbers (e.g., \"hiljada\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via SCALE[] array with indexed [singular, few, many] forms\n * - Gender-specific number forms for 1 and 2 (masculine/feminine dual forms)\n *\n * Features:\n * - Dual gender forms for 1 and 2 (jedan/jedna, dva/dve)\n * - Similar structure to Croatian with different orthography\n * - Latin script (Serbian can use both Latin and Cyrillic)\n *\n * Inherits from SlavicLanguage for complex pluralization algorithms.\n */\nexport class Serbian extends SlavicLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'zapeta'\n zeroWord = 'nula'\n ones = {\n 1: ['jedan', 'jedna'],\n 2: ['dva', 'dve'],\n 3: ['tri', 'tri'],\n 4: ['četiri', 'četiri'],\n 5: ['pet', 'pet'],\n 6: ['šest', 'šest'],\n 7: ['sedam', 'sedam'],\n 8: ['osam', 'osam'],\n 9: ['devet', 'devet']\n }\n\n tens = {\n 0: 'deset',\n 1: 'jedanaest',\n 2: 'dvanaest',\n 3: 'trinaest',\n 4: 'četrnaest',\n 5: 'petnaest',\n 6: 'šesnaest',\n 7: 'sedamnaest',\n 8: 'osamnaest',\n 9: 'devetnaest'\n }\n\n twenties = {\n 2: 'dvadeset',\n 3: 'trideset',\n 4: 'četrdeset',\n 5: 'pedeset',\n 6: 'šezdeset',\n 7: 'sedamdeset',\n 8: 'osamdeset',\n 9: 'devedeset'\n }\n\n hundreds = {\n 1: 'sto',\n 2: 'dvesta',\n 3: 'trista',\n 4: 'četiristo',\n 5: 'petsto',\n 6: 'šesto',\n 7: 'sedamsto',\n 8: 'osamsto',\n 9: 'devetsto'\n }\n\n SCALE = [\n ['', '', '', false],\n ['hiljada', 'hiljade', 'hiljada', true], // 10 ^ 3\n ['milion', 'miliona', 'miliona', false], // 10 ^ 6\n ['milijarda', 'milijarde', 'milijarda', false], // 10 ^ 9\n ['bilion', 'biliona', 'biliona', false], // 10 ^ 12\n ['bilijarda', 'bilijarde', 'bilijarda', false], // 10 ^ 15\n ['trilion', 'triliona', 'triliona', false], // 10 ^ 18\n ['trilijarda', 'trilijarde', 'trilijarda', false], // 10 ^ 21\n ['kvadrilion', 'kvadriliona', 'kvadriliona', false], // 10 ^ 24\n ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda', false], // 10 ^ 27\n ['kvintilion', 'kvintiliona', 'kvintiliona', false] // 10 ^ 30\n ]\n\n pluralize (n, forms) {\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {\n return forms[0]\n }\n\n if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {\n return forms[1]\n }\n\n return forms[2]\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0) {\n words.push(this.hundreds[n3])\n }\n if (n2 > 1) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0) {\n const isFeminine = (this.feminine || this.SCALE[index][3])\n const genderIndex = isFeminine ? 1 : 0\n words.push(this.ones[n1][genderIndex])\n }\n if ((index > 0) && (x !== 0n)) {\n words.push(this.pluralize(x, this.SCALE[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Serbian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Serbian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Serbian(options).convertToWords(value)\n}\n","'use strict';\nvar bind = require('../internals/function-bind-context');\nvar call = require('../internals/function-call');\nvar anObject = require('../internals/an-object');\nvar tryToString = require('../internals/try-to-string');\nvar isArrayIteratorMethod = require('../internals/is-array-iterator-method');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar getIterator = require('../internals/get-iterator');\nvar getIteratorMethod = require('../internals/get-iterator-method');\nvar iteratorClose = require('../internals/iterator-close');\n\nvar $TypeError = TypeError;\n\nvar Result = function (stopped, result) {\n this.stopped = stopped;\n this.result = result;\n};\n\nvar ResultPrototype = Result.prototype;\n\nmodule.exports = function (iterable, unboundFunction, options) {\n var that = options && options.that;\n var AS_ENTRIES = !!(options && options.AS_ENTRIES);\n var IS_RECORD = !!(options && options.IS_RECORD);\n var IS_ITERATOR = !!(options && options.IS_ITERATOR);\n var INTERRUPTED = !!(options && options.INTERRUPTED);\n var fn = bind(unboundFunction, that);\n var iterator, iterFn, index, length, result, next, step;\n\n var stop = function (condition) {\n if (iterator) iteratorClose(iterator, 'normal');\n return new Result(true, condition);\n };\n\n var callFn = function (value) {\n if (AS_ENTRIES) {\n anObject(value);\n return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);\n } return INTERRUPTED ? fn(value, stop) : fn(value);\n };\n\n if (IS_RECORD) {\n iterator = iterable.iterator;\n } else if (IS_ITERATOR) {\n iterator = iterable;\n } else {\n iterFn = getIteratorMethod(iterable);\n if (!iterFn) throw new $TypeError(tryToString(iterable) + ' is not iterable');\n // optimisation for array iterators\n if (isArrayIteratorMethod(iterFn)) {\n for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) {\n result = callFn(iterable[index]);\n if (result && isPrototypeOf(ResultPrototype, result)) return result;\n } return new Result(false);\n }\n iterator = getIterator(iterable, iterFn);\n }\n\n next = IS_RECORD ? iterable.next : iterator.next;\n while (!(step = call(next, iterator)).done) {\n try {\n result = callFn(step.value);\n } catch (error) {\n iteratorClose(iterator, 'throw', error);\n }\n if (typeof result == 'object' && result && isPrototypeOf(ResultPrototype, result)) return result;\n } return new Result(false);\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar isObject = require('../internals/is-object');\nvar isSymbol = require('../internals/is-symbol');\nvar getMethod = require('../internals/get-method');\nvar ordinaryToPrimitive = require('../internals/ordinary-to-primitive');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n","'use strict';\nvar hasOwn = require('../internals/has-own-property');\nvar isCallable = require('../internals/is-callable');\nvar toObject = require('../internals/to-object');\nvar sharedKey = require('../internals/shared-key');\nvar CORRECT_PROTOTYPE_GETTER = require('../internals/correct-prototype-getter');\n\nvar IE_PROTO = sharedKey('IE_PROTO');\nvar $Object = Object;\nvar ObjectPrototype = $Object.prototype;\n\n// `Object.getPrototypeOf` method\n// https://tc39.es/ecma262/#sec-object.getprototypeof\n// eslint-disable-next-line es/no-object-getprototypeof -- safe\nmodule.exports = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) {\n var object = toObject(O);\n if (hasOwn(object, IE_PROTO)) return object[IE_PROTO];\n var constructor = object.constructor;\n if (isCallable(constructor) && object instanceof constructor) {\n return constructor.prototype;\n } return object instanceof $Object ? ObjectPrototype : null;\n};\n","'use strict';\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true\n : value === NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n","'use strict';\nvar globalThis = require('../internals/global-this');\n\nvar navigator = globalThis.navigator;\nvar userAgent = navigator && navigator.userAgent;\n\nmodule.exports = userAgent ? String(userAgent) : '';\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Russian language converter.\n *\n * Converts numbers to Russian words with full grammatical support:\n * - Gender agreement (masculine/feminine forms)\n * - Complex pluralization rules (one/few/many forms)\n * - Declension patterns for thousands, millions, billions, etc.\n * - Proper case endings for number words\n *\n * Features:\n * - Gender-aware forms (один/одна, два/две)\n * - Three-form pluralization (тысяча/тысячи/тысяч)\n * - Support for very large numbers (up to nonillions)\n * - Proper spacing and conjunction rules\n *\n * This class extends SlavicLanguage, which provides the conversion algorithm\n * shared by Czech, Polish, Ukrainian, Serbian, Croatian, Hebrew, Lithuanian, Latvian.\n */\nexport class Russian extends SlavicLanguage {\n negativeWord = 'минус'\n decimalSeparatorWord = 'запятая'\n zeroWord = 'ноль'\n\n ones = {\n 1: 'один',\n 2: 'два',\n 3: 'три',\n 4: 'четыре',\n 5: 'пять',\n 6: 'шесть',\n 7: 'семь',\n 8: 'восемь',\n 9: 'девять'\n }\n\n onesFeminine = {\n 1: 'одна',\n 2: 'две',\n 3: 'три',\n 4: 'четыре',\n 5: 'пять',\n 6: 'шесть',\n 7: 'семь',\n 8: 'восемь',\n 9: 'девять'\n }\n\n tens = {\n 0: 'десять',\n 1: 'одиннадцать',\n 2: 'двенадцать',\n 3: 'тринадцать',\n 4: 'четырнадцать',\n 5: 'пятнадцать',\n 6: 'шестнадцать',\n 7: 'семнадцать',\n 8: 'восемнадцать',\n 9: 'девятнадцать'\n }\n\n twenties = {\n 2: 'двадцать',\n 3: 'тридцать',\n 4: 'сорок',\n 5: 'пятьдесят',\n 6: 'шестьдесят',\n 7: 'семьдесят',\n 8: 'восемьдесят',\n 9: 'девяносто'\n }\n\n hundreds = {\n 1: 'сто',\n 2: 'двести',\n 3: 'триста',\n 4: 'четыреста',\n 5: 'пятьсот',\n 6: 'шестьсот',\n 7: 'семьсот',\n 8: 'восемьсот',\n 9: 'девятьсот'\n }\n\n thousands = {\n 1: ['тысяча', 'тысячи', 'тысяч'], // 10^ 3\n 2: ['миллион', 'миллиона', 'миллионов'], // 10^ 6\n 3: ['миллиард', 'миллиарда', 'миллиардов'], // 10^ 9\n 4: ['триллион', 'триллиона', 'триллионов'], // 10^ 12\n 5: ['квадриллион', 'квадриллиона', 'квадриллионов'], // 10^ 15\n 6: ['квинтиллион', 'квинтиллиона', 'квинтиллионов'], // 10^ 18\n 7: ['секстиллион', 'секстиллиона', 'секстиллионов'], // 10^ 21\n 8: ['септиллион', 'септиллиона', 'септиллионов'], // 10^ 24\n 9: ['октиллион', 'октиллиона', 'октиллионов'], // 10^ 27\n 10: ['нониллион', 'нониллиона', 'нониллионов'] // 10^ 30\n }\n}\n\n/**\n * Converts a number to Russian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {SlavicOptions} [options={}] Configuration options.\n * @returns {string} The number expressed in Russian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Russian(options).convertToWords(value)\n}\n","import SouthAsianLanguage from '../classes/south-asian-language.js'\n\nclass Bengali extends SouthAsianLanguage {\n negativeWord = 'মাইনাস'\n decimalSeparatorWord = 'দশমিক'\n zeroWord = 'শূন্য'\n hundredWord = 'শত'\n belowHundred = [\n 'শূন্য',\n 'এক',\n 'দুই',\n 'তিন',\n 'চার',\n 'পাঁচ',\n 'ছয়',\n 'সাত',\n 'আট',\n 'নয়',\n 'দশ',\n 'এগারো',\n 'বারো',\n 'তেরো',\n 'চৌদ্দ',\n 'পনেরো',\n 'ষোল',\n 'সতেরো',\n 'আঠারো',\n 'উনিশ',\n 'বিশ',\n 'একুশ',\n 'বাইশ',\n 'তেইশ',\n 'চব্বিশ',\n 'পঁচিশ',\n 'ছাব্বিশ',\n 'সাতাশ',\n 'আঠাশ',\n 'উনত্রিশ',\n 'ত্রিশ',\n 'একত্রিশ',\n 'বত্রিশ',\n 'তেত্রিশ',\n 'চৌত্রিশ',\n 'পঁয়ত্রিশ',\n 'ছত্রিশ',\n 'সাঁইত্রিশ',\n 'আটত্রিশ',\n 'উনচল্লিশ',\n 'চল্লিশ',\n 'একচল্লিশ',\n 'বেয়াল্লিশ',\n 'তেতাল্লিশ',\n 'চুয়াল্লিশ',\n 'পঁয়তাল্লিশ',\n 'ছেচল্লিশ',\n 'সাতচল্লিশ',\n 'আটচল্লিশ',\n 'উনপঞ্চাশ',\n 'পঞ্চাশ',\n 'একান্ন',\n 'বাহান্ন',\n 'তিপ্পান্ন',\n 'চুয়ান্ন',\n 'পঞ্চান্ন',\n 'ছাপ্পান্ন',\n 'সাতান্ন',\n 'আটান্ন',\n 'উনষাট',\n 'ষাট',\n 'একষট্টি',\n 'বাষট্টি',\n 'তেষট্টি',\n 'চৌষট্টি',\n 'পঁয়ষট্টি',\n 'ছেষট্টি',\n 'সাতষট্টি',\n 'আটষট্টি',\n 'ঊনসত্তর',\n 'সত্তর',\n 'একাত্তর',\n 'বাহাত্তর',\n 'তেহাত্তর',\n 'চুয়াত্তর',\n 'পঁচাত্তর',\n 'ছিয়াত্তর',\n 'সাতাত্তর',\n 'আটাত্তর',\n 'উনআশি',\n 'আশি',\n 'একাশি',\n 'বিরাশি',\n 'তিরাশি',\n 'চুরাশি',\n 'পঁচাশি',\n 'ছিয়াশি',\n 'সাতাশি',\n 'আটাশি',\n 'উননব্বই',\n 'নব্বই',\n 'একানব্বই',\n 'বিরানব্বই',\n 'তিরানব্বই',\n 'চুরানব্বই',\n 'পঁচানব্বই',\n 'ছিয়ানব্বই',\n 'সাতানব্বই',\n 'আটানব্বই',\n 'নিরানব্বই'\n ]\n\n scaleWords = [\n '',\n 'হাজার',\n 'লাখ',\n 'কোটি',\n 'আরব',\n 'খরব',\n 'নীল',\n 'পদ্ম',\n 'শঙ্খ'\n ]\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Bengali(options).convertToWords(value)\n}\n","/**\n * Gujarati language implementation for n2words\n *\n * Gujarati uses Indian-style number grouping (3 digits, then 2-2 from right).\n * Numbers: શૂન્ય (0), એક (1), બે (2), ત્રણ (3), ચાર (4), પાંચ (5)...\n *\n * @module lib/languages/gu\n * @example\n * import gu from './lib/languages/gu.js'\n * gu(42) // 'બેતાળીસ'\n * gu(1000) // 'એક હજાર'\n */\n\nimport SouthAsianLanguage from '../classes/south-asian-language.js'\n\n/**\n * Gujarati language implementation\n * Extends SouthAsianLanguage for Indian-style grouping\n */\nclass GujaratiLanguage extends SouthAsianLanguage {\n negativeWord = 'ઋણ'\n decimalSeparatorWord = 'દશાંશ'\n zeroWord = 'શૂન્ય'\n hundredWord = 'સો'\n convertDecimalsPerDigit = true\n\n belowHundred = [\n 'શૂન્ય',\n 'એક',\n 'બે',\n 'ત્રણ',\n 'ચાર',\n 'પાંચ',\n 'છ',\n 'સાત',\n 'આઠ',\n 'નવ',\n 'દસ',\n 'અગિયાર',\n 'બાર',\n 'તેર',\n 'ચૌદ',\n 'પંદર',\n 'સોળ',\n 'સત્તર',\n 'અઢાર',\n 'ઓગણીસ',\n 'વીસ',\n 'એકવીસ',\n 'બાવીસ',\n 'ત્રેવીસ',\n 'ચોવીસ',\n 'પચીસ',\n 'છવ્વીસ',\n 'સત્તાવીસ',\n 'અઠ્ઠાવીસ',\n 'ઓગણત્રીસ',\n 'ત્રીસ',\n 'એકત્રીસ',\n 'બત્રીસ',\n 'તેત્રીસ',\n 'ચોત્રીસ',\n 'પાંત્રીસ',\n 'છત્રીસ',\n 'સાડત્રીસ',\n 'અડત્રીસ',\n 'ઓગણચાલીસ',\n 'ચાલીસ',\n 'એકતાલીસ',\n 'બેતાળીસ',\n 'ત્રેતાળીસ',\n 'ચુંમાલીસ',\n 'પિસ્તાલીસ',\n 'છેતાળીસ',\n 'સુડતાળીસ',\n 'અડતાળીસ',\n 'ઓગણપચાસ',\n 'પચાસ',\n 'એકાવન',\n 'બાવન',\n 'ત્રેપન',\n 'ચોપન',\n 'પંચાવન',\n 'છપ્પન',\n 'સત્તાવન',\n 'અઠ્ઠાવન',\n 'ઓગણસાઠ',\n 'સાઠ',\n 'એકસઠ',\n 'બાસઠ',\n 'ત્રેસઠ',\n 'ચોસઠ',\n 'પાંસઠ',\n 'છાસઠ',\n 'સડસઠ',\n 'અડસઠ',\n 'અગણોસિત્તેર',\n 'સિત્તેર',\n 'એકોતેર',\n 'બોતેર',\n 'તોતેર',\n 'ચુમોતેર',\n 'પંચોતેર',\n 'છોતેર',\n 'સિત્યોતેર',\n 'ઇઠ્યોતેર',\n 'ઓગણાએંસી',\n 'એંસી',\n 'એક્યાસી',\n 'બ્યાસી',\n 'ત્યાસી',\n 'ચોર્યાસી',\n 'પંચાસી',\n 'છ્યાસી',\n 'સિત્યાસી',\n 'અઠ્યાસી',\n 'નેવ્યાસી',\n 'નેવું',\n 'એકાણું',\n 'બાણું',\n 'ત્રાણું',\n 'ચોરાણું',\n 'પંચાણું',\n 'છન્નું',\n 'સત્તાણું',\n 'અઠ્ઠાણું',\n 'નવ્વાણું'\n ]\n\n scaleWords = [\n '',\n 'હજાર',\n 'લાખ',\n 'કરોડ',\n 'અબજ',\n 'ખરબ',\n 'નીલ',\n 'પદ્મ',\n 'શંખ'\n ]\n}\n\n/**\n * Convert a number to Gujarati words\n *\n * @param {number|string|bigint} value - The number to convert\n * @param {Object} [options={}] - Conversion options\n * @returns {string} The Gujarati word representation\n * @example\n * convertToWords(42) // 'બેતાળીસ'\n * convertToWords(1000) // 'એક હજાર'\n * convertToWords(100000) // 'એક લાખ'\n */\nexport default function convertToWords (value, options = {}) {\n return new GujaratiLanguage(options).convertToWords(value)\n}\n","import AbstractLanguage from '../classes/abstract-language.js'\n\nclass Telugu extends AbstractLanguage {\n negativeWord = 'మైనస్'\n decimalSeparatorWord = 'పాయింట్'\n zeroWord = 'సున్నా'\n convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion\n belowHundred = [\n 'సున్నా',\n 'ఒకటి',\n 'రెండు',\n 'మూడు',\n 'నాలుగు',\n 'ఐదు',\n 'ఆరు',\n 'ఏడు',\n 'ఎనిమిది',\n 'తొమ్మిది',\n 'పది',\n 'పదకొండు',\n 'పన్నెండు',\n 'పదమూడు',\n 'పద్నాలుగు',\n 'పదిహేను',\n 'పదహారు',\n 'పదిహేడు',\n 'పద్దెనిమిది',\n 'పంతొమ్మిది',\n 'ఇరవై',\n 'ఇరవై ఒక్కటి',\n 'ఇరవై రెండు',\n 'ఇరవై మూడు',\n 'ఇరవై నాలుగు',\n 'ఇరవై ఐదు',\n 'ఇరవై ఆరు',\n 'ఇరవై ఏడు',\n 'ఇరవై ఎనిమిది',\n 'ఇరవై తొమ్మిది',\n 'ముప్పై',\n 'ముప్పై ఒకటి',\n 'ముప్పై రెండు',\n 'ముప్పై మూడు',\n 'ముప్పై నాలుగు',\n 'ముప్పై ఐదు',\n 'ముప్పై ఆరు',\n 'ముప్పై ఏడు',\n 'ముప్పై ఎనిమిది',\n 'ముప్పై తొమ్మిది',\n 'నలభై',\n 'నలభై ఒకటి',\n 'నలభై రెండు',\n 'నలభై మూడు',\n 'నలభై నాలుగు',\n 'నలభై ఐదు',\n 'నలభై ఆరు',\n 'నలభై ఏడు',\n 'నలభై ఎనిమిది',\n 'నలభై తొమ్మిది',\n 'యాభై',\n 'యాభై ఒకటి',\n 'యాభై రెండు',\n 'యాభై మూడు',\n 'యాభై నాలుగు',\n 'యాభై ఐదు',\n 'యాభై ఆరు',\n 'యాభై ఏడు',\n 'యాభై ఎనిమిది',\n 'యాభై తొమ్మిది',\n 'అరవై',\n 'అరవై ఒకటి',\n 'అరవై రెండు',\n 'అరవై మూడు',\n 'అరవై నాలుగు',\n 'అరవై ఐదు',\n 'అరవై ఆరు',\n 'అరవై ఏడు',\n 'అరవై ఎనిమిది',\n 'అరవై తొమ్మిది',\n 'డెబ్బై',\n 'డెబ్బై ఒకటి',\n 'డెబ్బై రెండు',\n 'డెబ్బై మూడు',\n 'డెబ్బై నాలుగు',\n 'డెబ్బై ఐదు',\n 'డెబ్బై ఆరు',\n 'డెబ్బై ఏడు',\n 'డెబ్బై ఎనిమిది',\n 'డెబ్బై తొమ్మిది',\n 'ఎనభై',\n 'ఎనభై ఒకటి',\n 'ఎనభై రెండు',\n 'ఎనభై మూడు',\n 'ఎనభై నాలుగు',\n 'ఎనభై ఐదు',\n 'ఎనభై ఆరు',\n 'ఎనభై ఏడు',\n 'ఎనభై ఎనిమిది',\n 'ఎనభై తొమ్మిది',\n 'తొంభై',\n 'తొంభై ఒకటి',\n 'తొంభై రెండు',\n 'తొంభై మూడు',\n 'తొంభై నాలుగు',\n 'తొంభై ఐదు',\n 'తొంభై ఆరు',\n 'తొంభై ఏడు',\n 'తొంభై ఎనిమిది',\n 'తొంభై తొమ్మిది'\n ]\n\n hundreds = [\n '',\n 'వంద',\n 'రెండు వందలు',\n 'మూడు వందలు',\n 'నాలుగు వందలు',\n 'ఐదు వందలు',\n 'ఆరు వందలు',\n 'ఏడు వందలు',\n 'ఎనిమిది వందలు',\n 'తొమ్మిది వందలు'\n ]\n\n // Digits map 1–9 for decimal reading\n digits = [\n 'ఒకటి',\n 'రెండు',\n 'మూడు',\n 'నాలుగు',\n 'ఐదు',\n 'ఆరు',\n 'ఏడు',\n 'ఎనిమిది',\n 'తొమ్మిది'\n ]\n\n scales = [\n '',\n 'వెయ్యి',\n 'లక్ష',\n 'కోటి',\n 'అరబ్',\n 'ఖరబ్',\n 'నిల్',\n 'పడ్మ',\n 'శంకు'\n ]\n\n /**\n * Convert numbers below 100 to Telugu words.\n *\n * @param {number} number The number to convert (0-99).\n * @returns {string} The Telugu representation.\n */\n convertBelowHundred (number) {\n return this.belowHundred[number]\n }\n\n /**\n * Convert numbers below 1000 to Telugu words.\n *\n * @param {number} number The number to convert (0-999).\n * @returns {string} The Telugu representation.\n */\n convertBelowThousand (number) {\n if (number === 0) return ''\n if (number < 100) return this.convertBelowHundred(number)\n\n const hundreds = Math.trunc(number / 100)\n const remainder = number % 100\n const parts = [this.hundreds[hundreds]]\n\n if (remainder > 0) {\n parts.push(this.convertBelowHundred(remainder))\n }\n\n return parts.join(' ').trim()\n }\n\n /**\n * Split a number using Indian-style grouping (3-2-2 digits from right).\n *\n * @param {bigint} number The number to split.\n * @returns {number[]} Array of number groups.\n */\n splitIndian (number) {\n const numStr = number.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const groups = []\n const last3 = numStr.slice(-3)\n groups.unshift(Number(last3))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n const group = remaining.slice(-2)\n groups.unshift(Number(group))\n remaining = remaining.slice(0, -2)\n }\n\n return groups\n }\n\n convertWholePart (number) {\n if (number === 0n) return this.zeroWord\n\n const groups = this.splitIndian(number)\n const groupCount = groups.length\n const words = []\n\n for (let i = 0; i < groupCount; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n const scaleIndex = groupCount - i - 1\n const groupWords = (groupValue === 1 && scaleIndex > 0) ? 'ఒక' : this.convertBelowThousand(groupValue)\n words.push(groupWords)\n if (scaleIndex > 0 && this.scales[scaleIndex]) {\n words.push(this.scales[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n }\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Telugu(options).convertToWords(value)\n}\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.1.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar SetHelpers = require('../internals/set-helpers');\nvar clone = require('../internals/set-clone');\nvar size = require('../internals/set-size');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSet = require('../internals/set-iterate');\nvar iterateSimple = require('../internals/iterate-simple');\n\nvar has = SetHelpers.has;\nvar remove = SetHelpers.remove;\n\n// `Set.prototype.difference` method\n// https://tc39.es/ecma262/#sec-set.prototype.difference\nmodule.exports = function difference(other) {\n var O = aSet(this);\n var otherRec = getSetRecord(other);\n var result = clone(O);\n if (size(O) <= otherRec.size) iterateSet(O, function (e) {\n if (otherRec.includes(e)) remove(result, e);\n });\n else iterateSimple(otherRec.getIterator(), function (e) {\n if (has(result, e)) remove(result, e);\n });\n return result;\n};\n","/**\n * Converts numbers to their word representation in Greek (Ελληνικά).\n * @module languages/el\n */\n\nimport GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Greek language implementation using scale-based number conversion.\n * @extends GreedyScaleLanguage\n */\nclass GreekLanguage extends GreedyScaleLanguage {\n negativeWord = 'μείον'\n decimalSeparatorWord = 'κόμμα'\n zeroWord = 'μηδέν'\n convertDecimalsPerDigit = true\n\n scaleWordPairs = [\n // Large numbers (limited set for now)\n [1_000_000_000n, 'δισεκατομμύριο'],\n [1_000_000n, 'εκατομμύριο'],\n [1000n, 'χίλια'],\n\n // Hundreds\n [900n, 'εννιακόσια'],\n [800n, 'οκτακόσια'],\n [700n, 'επτακόσια'],\n [600n, 'εξακόσια'],\n [500n, 'πεντακόσια'],\n [400n, 'τετρακόσια'],\n [300n, 'τριακόσια'],\n [200n, 'διακόσια'],\n [100n, 'εκατό'],\n\n // Tens\n [90n, 'ενενήντα'],\n [80n, 'ογδόντα'],\n [70n, 'εβδομήντα'],\n [60n, 'εξήντα'],\n [50n, 'πενήντα'],\n [40n, 'σαράντα'],\n [30n, 'τριάντα'],\n [20n, 'είκοσι'],\n [19n, 'δεκαεννέα'],\n [18n, 'δεκαοκτώ'],\n [17n, 'δεκαεπτά'],\n [16n, 'δεκαέξι'],\n [15n, 'δεκαπέντε'],\n [14n, 'δεκατέσσερα'],\n [13n, 'δεκατρία'],\n [12n, 'δώδεκα'],\n [11n, 'έντεκα'],\n [10n, 'δέκα'],\n\n // Singles\n [9n, 'εννέα'],\n [8n, 'οκτώ'],\n [7n, 'επτά'],\n [6n, 'έξι'],\n [5n, 'πέντε'],\n [4n, 'τέσσερα'],\n [3n, 'τρία'],\n [2n, 'δύο'],\n [1n, 'ένα'],\n [0n, 'μηδέν']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to Greek grammar rules.\n *\n * Greek-specific rules:\n * - Implicit \"one\": χίλια (thousand), not ένα χίλια\n * - Space-separated composites\n * - Multiplication for scales (e.g., δύο χίλια = two thousand)\n *\n * @param {Object} leftPair - Left word-number pair (e.g., { 'δύο': 2n })\n * @param {Object} rightPair - Right word-number pair (e.g., { 'χίλια': 1000n })\n * @returns {Object} Merged word-number pair\n */\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const leftNumber = Object.values(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const rightNumber = Object.values(rightPair)[0]\n\n // Implicit one: omit \"ένα\" before any following value (> 0)\n if (leftNumber === 1n) {\n return rightPair\n }\n\n // No special handling needed for trailing 'ένα';\n // nested merge will first collapse {1, 'ένα'} -> 'ένα'.\n\n // Multiplication: larger right scale multiplied by left number\n if (rightNumber > leftNumber) {\n return { [`${leftWord} ${rightWord}`]: leftNumber * rightNumber }\n }\n\n // Addition: smaller numbers added together\n return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }\n }\n}\n\n/**\n * Converts a number to its word representation in Greek.\n * @param {number|string|bigint} value - The number to convert\n * @param {Object} [options={}] - Conversion options\n * @returns {string} The word representation of the number\n * @example\n * convertToWords(42) // 'σαράντα δύο'\n * convertToWords(1000) // 'χίλια'\n * convertToWords(2000) // 'δύο χίλια'\n */\nexport default function convertToWords (value, options = {}) {\n return new GreekLanguage(options).convertToWords(value)\n}\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar SetHelpers = require('../internals/set-helpers');\nvar clone = require('../internals/set-clone');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSimple = require('../internals/iterate-simple');\n\nvar add = SetHelpers.add;\nvar has = SetHelpers.has;\nvar remove = SetHelpers.remove;\n\n// `Set.prototype.symmetricDifference` method\n// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference\nmodule.exports = function symmetricDifference(other) {\n var O = aSet(this);\n var keysIter = getSetRecord(other).getIterator();\n var result = clone(O);\n iterateSimple(keysIter, function (e) {\n if (has(O, e)) remove(result, e);\n else add(result, e);\n });\n return result;\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar isCallable = require('../internals/is-callable');\nvar store = require('../internals/shared-store');\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n","'use strict';\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n","'use strict';\nvar fails = require('../internals/fails');\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;\n});\n","'use strict';\nvar aCallable = require('../internals/a-callable');\nvar anObject = require('../internals/an-object');\nvar call = require('../internals/function-call');\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\nvar getIteratorDirect = require('../internals/get-iterator-direct');\n\nvar INVALID_SIZE = 'Invalid size';\nvar $RangeError = RangeError;\nvar $TypeError = TypeError;\nvar max = Math.max;\n\nvar SetRecord = function (set, intSize) {\n this.set = set;\n this.size = max(intSize, 0);\n this.has = aCallable(set.has);\n this.keys = aCallable(set.keys);\n};\n\nSetRecord.prototype = {\n getIterator: function () {\n return getIteratorDirect(anObject(call(this.keys, this.set)));\n },\n includes: function (it) {\n return call(this.has, this.set, it);\n }\n};\n\n// `GetSetRecord` abstract operation\n// https://tc39.es/proposal-set-methods/#sec-getsetrecord\nmodule.exports = function (obj) {\n anObject(obj);\n var numSize = +obj.size;\n // NOTE: If size is undefined, then numSize will be NaN\n // eslint-disable-next-line no-self-compare -- NaN check\n if (numSize !== numSize) throw new $TypeError(INVALID_SIZE);\n var intSize = toIntegerOrInfinity(numSize);\n if (intSize < 0) throw new $RangeError(INVALID_SIZE);\n return new SetRecord(obj, intSize);\n};\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar size = require('../internals/set-size');\nvar iterate = require('../internals/set-iterate');\nvar getSetRecord = require('../internals/get-set-record');\n\n// `Set.prototype.isSubsetOf` method\n// https://tc39.es/ecma262/#sec-set.prototype.issubsetof\nmodule.exports = function isSubsetOf(other) {\n var O = aSet(this);\n var otherRec = getSetRecord(other);\n if (size(O) > otherRec.size) return false;\n return iterate(O, function (e) {\n if (!otherRec.includes(e)) return false;\n }, true) !== false;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar isDisjointFrom = require('../internals/set-is-disjoint-from');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar INCORRECT = !setMethodAcceptSetLike('isDisjointFrom', function (result) {\n return !result;\n});\n\n// `Set.prototype.isDisjointFrom` method\n// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom\n$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, {\n isDisjointFrom: isDisjointFrom\n});\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * German language converter.\n *\n * Handles German grammatical features:\n * - \"eins\" vs \"ein\" and \"eine\" forms for 1\n * - Compound words without separators (e.g., \"einundzwanzig\" = 21)\n * - Million/Billion pluralization\n * - Special characters (e.g., \"ü\", \"ö\", \"ß\")\n */\nexport class German extends GreedyScaleLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'komma'\n zeroWord = 'null'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'Quadrilliarde'],\n [1_000_000_000_000_000_000_000_000n, 'Quadrillion'],\n [1_000_000_000_000_000_000_000n, 'Trilliarde'],\n [1_000_000_000_000_000_000n, 'Trillion'],\n [1_000_000_000_000_000n, 'Billiarde'],\n [1_000_000_000_000n, 'Billion'],\n [1_000_000_000n, 'Milliarde'],\n [1_000_000n, 'Million'],\n [1000n, 'tausend'],\n [100n, 'hundert'],\n [90n, 'neunzig'],\n [80n, 'achtzig'],\n [70n, 'siebzig'],\n [60n, 'sechzig'],\n [50n, 'fünfzig'],\n [40n, 'vierzig'],\n [30n, 'dreißig'],\n [20n, 'zwanzig'],\n [19n, 'neunzehn'],\n [18n, 'achtzehn'],\n [17n, 'siebzehn'],\n [16n, 'sechzehn'],\n [15n, 'fünfzehn'],\n [14n, 'vierzehn'],\n [13n, 'dreizehn'],\n [12n, 'zwölf'],\n [11n, 'elf'],\n [10n, 'zehn'],\n [9n, 'neun'],\n [8n, 'acht'],\n [7n, 'sieben'],\n [6n, 'sechs'],\n [5n, 'fünf'],\n [4n, 'vier'],\n [3n, 'drei'],\n [2n, 'zwei'],\n [1n, 'eins'],\n [0n, 'null']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to German grammar rules.\n *\n * German-specific rules:\n * - Implicit \"eins\": `mergeScales({ 'eins': 1n }, { 'hundert': 100n })` → `{ 'einhundert': 100n }`\n * - Compound words without separators (e.g., \"einundzwanzig\" = 21)\n * - Special handling for forms of 1 (eins/ein/eine) depending on context\n * - Pluralization of millions and higher: \"Millionen\", \"Milliarden\"\n * - Reordering of tens and units: `mergeScales({ 'zwanzig': 20n }, { 'eins': 1n })` → `{ 'einundzwanzig': 21n }`\n *\n * @param {Object} currentPair The left operand as `{ word: BigInt }`.\n * @param {Object} nextPair The right operand as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'eins': 1n }, { 'hundert': 100n }); // { 'einhundert': 100n }\n * mergeScales({ 'zwanzig': 20n }, { 'drei': 3n }); // { 'dreiundzwanzig': 23n }\n */\n mergeScales (currentPair, nextPair) {\n let currentWord = Object.keys(currentPair)[0]\n let nextWord = Object.keys(nextPair)[0]\n const currentNumber = Object.values(currentPair)[0]\n const nextNumber = Object.values(nextPair)[0]\n\n // Handle form of 1: \"eins\" → \"ein(e)\" in certain contexts\n if (currentNumber === 1n) {\n if (nextNumber === 100n || nextNumber === 1000n) {\n return { [`ein${nextWord}`]: nextNumber }\n }\n if (nextNumber < 1_000_000n) {\n return nextPair\n }\n currentWord = 'eine'\n }\n\n if (nextNumber > currentNumber) {\n // Multiply: apply pluralization rules for millions\n if (nextNumber >= 1_000_000n) {\n if (currentNumber > 1n) {\n nextWord += nextWord.at(-1) === 'e' ? 'n' : 'en'\n }\n currentWord += ' '\n }\n return { [`${currentWord}${nextWord}`]: currentNumber * nextNumber }\n }\n\n // Add: handle special case of tens + units\n if (nextNumber < 10n && currentNumber > 10n && currentNumber < 100n) {\n // German reverses tens and units (einundzwanzig = one and twenty)\n if (nextNumber === 1n) {\n nextWord = 'ein'\n }\n const temp = nextWord\n nextWord = currentWord\n currentWord = `${temp}und`\n } else if (currentNumber >= 1_000_000n) {\n currentWord += ' '\n }\n\n return { [`${currentWord}${nextWord}`]: currentNumber + nextNumber }\n }\n}\n\n/**\n * Converts a number to German cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see German class options).\n * @returns {string} The number expressed in German words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'zweiundvierzig'\n * convertToWords('1.5'); // 'eins komma fünf'\n */\nexport default function convertToWords (value, options = {}) {\n return new German(options).convertToWords(value)\n}\n","import GreedyScaleLanguage from './greedy-scale-language.js'\n\n/**\n * @typedef {Object} TurkicWordPair\n * @property {string} word - The Turkic word or phrase\n * @property {bigint} value - The numeric value represented by the word\n */\n\n/**\n * Base class for Turkic languages with shared grammar patterns.\n *\n * This class provides a reusable implementation for Turkic languages that share:\n * - Space-separated number combinations\n * - Implicit 'bir' (one) before hundreds and thousands\n * - Simple multiplication/addition logic\n * - Consistent magnitude handling\n * - Inherits decimal handling from AbstractLanguage via GreedyScaleLanguage\n * (supports both grouped and per-digit modes via the `convertDecimalsPerDigit` class property).\n *\n * Used by: Turkish (TR), Azerbaijani (AZ)\n *\n * Subclasses MUST define (from GreedyScaleLanguage requirements):\n * - `scaleWordPairs` array of [value, word] pairs as a class property (ordered descending by value).\n * Optionally, language-specific class properties (e.g., `negativeWord`, `zeroWord`, `decimalSeparatorWord`, `wordSeparator`).\n *\n * TurkicLanguage provides a default `mergeScales()` implementation; subclasses may override\n * if specialized merge logic is needed (unlikely for Turkic languages).\n *\n * @abstract\n * @extends GreedyScaleLanguage\n */\nclass TurkicLanguage extends GreedyScaleLanguage {\n /**\n * Merges two adjacent word-number pairs according to Turkic grammar rules.\n *\n * Shared Turkic patterns:\n * - Implicit 'bir' (one) before hundreds and thousands\n * - Space separator (wordSeparator property) for all combinations\n * - Multiplies when right > left (crossing magnitude boundary)\n * - Adds otherwise (combining same-magnitude components)\n *\n * @param {Object} leftPair The left operand as `{ word: bigint }`.\n * @param {Object} rightPair The right operand as `{ word: bigint }`.\n * @returns {Object} Merged pair with combined word and resulting number (bigint).\n */\n mergeScales (leftPair, rightPair) {\n const [[leftWord, leftNumber]] = Object.entries(leftPair)\n const [[rightWord, rightNumber]] = Object.entries(rightPair)\n\n // Implicit 'bir' (one) before certain magnitudes:\n // Omit '1' before hundreds (100n) and thousands (1000n) to form natural combinations\n if (leftNumber === 1n && (rightNumber <= 100n || rightNumber === 1000n)) {\n return rightPair // Return just the magnitude word (e.g., \"yüz\", not \"bir yüz\")\n }\n\n // Combine numbers with space separator (wordSeparator from GreedyScaleLanguage):\n // Multiply when crossing magnitude boundary, add otherwise\n const mergedNumber = rightNumber > leftNumber ? leftNumber * rightNumber : leftNumber + rightNumber\n return { [`${leftWord}${this.wordSeparator}${rightWord}`]: mergedNumber }\n }\n}\n\nexport default TurkicLanguage\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * Indonesian language converter.\n *\n * Converts numbers to Indonesian words following Indonesian conventions:\n * - Simple base-10 structure\n * - \"Se-\" prefix for one (e.g., \"seratus\" = one hundred, \"seribu\" = one thousand)\n * - Space-separated number components\n * - Straightforward grouping by thousands\n *\n * Key Features:\n * - Base number mapping (base) for single digits 0-9\n * - Magnitude scale (thousands) mapping powers of 10 to Indonesian words\n * - Group-based algorithm:\n * 1. Split number into groups of 3 digits\n * 2. For each group, convert ones/tens/hundreds using base and naming rules\n * 3. Apply \"se-\" prefix for 1 (seratus, seribu, sejuta)\n * 4. Combine with magnitude words\n * 5. Join all parts with spaces\n * - Regular patterns (puluh for tens, ratus for hundreds, ribu for thousands)\n * - Clear grouping: ribu (10³), juta (10⁶), miliar (10⁹), triliun (10¹²)\n *\n * Features:\n * - \"Se-\" prefix usage for singular units\n * - Support for very large numbers (up to decillions)\n */\nexport class Indonesian extends AbstractLanguage {\n negativeWord = 'min'\n decimalSeparatorWord = 'koma'\n zeroWord = 'nol'\n base = {\n 0: [],\n 1: ['satu'],\n 2: ['dua'],\n 3: ['tiga'],\n 4: ['empat'],\n 5: ['lima'],\n 6: ['enam'],\n 7: ['tujuh'],\n 8: ['delapan'],\n 9: ['sembilan']\n }\n\n thousands = {\n 3: 'ribu', // 10^3\n 6: 'juta', // 10^6\n 9: 'miliar', // 10^9\n 12: 'triliun',\n 15: 'kuadriliun',\n 18: 'kuantiliun',\n 21: 'sekstiliun',\n 24: 'septiliun',\n 27: 'oktiliun',\n 30: 'noniliun',\n 33: 'desiliun'\n }\n\n splitBy3 (number) {\n // Split to groups of 3 numbers: 1234567 -> [['1'], ['234'], ['567']]\n const blocks = []\n const stringNumber = number.toString()\n const length = stringNumber.length\n let firstBlock\n\n if (length < 3) {\n blocks.push([stringNumber])\n } else {\n const firstBlockLength = length % 3\n\n if (firstBlockLength > 0) {\n firstBlock = [stringNumber.slice(0, firstBlockLength)]\n blocks.push(firstBlock)\n }\n\n for (let index = firstBlockLength; index < length; index += 3) {\n const nextBlock = [stringNumber.slice(index, index + 3)]\n blocks.push(nextBlock)\n }\n }\n return blocks\n }\n\n spell (blocks) {\n let wordBlocks = []\n let spelling\n const firstBlock = blocks[0]\n if (firstBlock[0].length === 1) {\n spelling = firstBlock[0] === '0' ? ['nol'] : this.base[Math.trunc(firstBlock[0])]\n } else if (firstBlock[0].length === 2) {\n spelling = this.getTens(firstBlock[0])\n } else {\n spelling = [...this.getHundreds(firstBlock[0][0]), ...this.getTens(firstBlock[0].slice(1, 3))]\n }\n wordBlocks = [...wordBlocks, [firstBlock[0], spelling]]\n for (let index = 1; index < blocks.length; index++) {\n let block = blocks[index]\n spelling = [...this.getHundreds(block[0][0]), ...this.getTens(block[0].slice(1, 3))]\n block = [...block, spelling]\n wordBlocks = [...wordBlocks, block]\n }\n return wordBlocks\n }\n\n getHundreds (number) {\n if (number === '1') {\n return ['seratus']\n } else if (number === '0') {\n return []\n } else {\n return [...this.base[Math.trunc(number)], 'ratus']\n }\n }\n\n getTens (number) {\n if (number[0] === '1') {\n if (number[1] === '0') {\n return ['sepuluh']\n } else if (number[1] === '1') {\n return ['sebelas']\n }\n return [...this.base[Math.trunc(number[1])], 'belas']\n }\n\n if (number[0] === '0') {\n return this.base[Math.trunc(number[1])]\n }\n\n return [...this.base[Math.trunc(number[0])], 'puluh', ...this.base[Math.trunc(number[1])]]\n }\n\n join (wordBlocks) {\n let wordList = []\n const length = wordBlocks.length - 1\n const firstBlock = [wordBlocks[0]]\n let start = 0\n if (length === 1 && firstBlock[0][0] === '1') {\n wordList.push('seribu')\n start = 1\n }\n for (let index = start; index < length + 1; index++) {\n wordList = [...wordList, ...wordBlocks[index][1]]\n if (wordBlocks[index][1].length === 0) {\n continue\n }\n if (index === length) {\n break\n }\n wordList = [...wordList, this.thousands[(length - index) * 3]]\n }\n return wordList.join(' ')\n }\n\n convertWholePart (number) {\n return this.join(\n this.spell(\n this.splitBy3(number)\n )\n ).trim()\n }\n}\n\n/**\n * Converts a number to Indonesian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @returns {string} The number expressed in Indonesian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Indonesian(options).convertToWords(value)\n}\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar isObject = require('../internals/is-object');\n\nvar document = globalThis.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n","import AbstractLanguage from './abstract-language.js'\n\n/**\n * @typedef {Object} WordSet\n * @property {string} word - The language word or phrase\n * @property {bigint} value - The numeric value represented by the word\n */\n\n/**\n * @typedef {Array.<Array.<(bigint|string)>>} ScaleWordPairs\n * Array of scale word pairs in descending order. Each pair contains:\n * - [0]: BigInt numeric value\n * - [1]: String word representation\n * Must be ordered largest to smallest for the greedy algorithm.\n */\n\n/**\n * Greedy scale language converter implementing the \"highest-matching scale word\" algorithm.\n *\n * Responsibilities:\n * - Decompose a whole-number value into a sequence of scale word-sets.\n * - Provide helpers to merge and post-process matched word-sets.\n * - Inherits decimal handling from AbstractLanguage (supports grouped and per-digit\n * modes via the `convertDecimalsPerDigit` class property).\n *\n * Subclass requirements:\n * - Define `scaleWordPairs` (ordered descending) as `[BigInt, string]` tuples.\n * - Implement `mergeScales(leftWordSet, rightWordSet)` to combine adjacent word-sets\n * per language grammar.\n *\n * Scale words specification:\n * - `scaleWordPairs` is an Array of 2-tuples: `[BigInt, string]` where the first element\n * is the numeric value (BigInt) and the second is the word used for that value.\n * - Scale words MUST be ordered from largest to smallest (descending) for the algorithm\n * to function correctly.\n *\n * @abstract\n * @extends AbstractLanguage\n * @example\n * // Example `scaleWordPairs` for English (descending order):\n * // [[1000000000n, 'billion'], [1000000n, 'million'], [1000n, 'thousand'], [100n, 'hundred'], ..., [1n, 'one']]\n */\n\nclass GreedyScaleLanguage extends AbstractLanguage {\n /**\n * Array of scale word pairs mapping numeric values to their word representations.\n *\n * Each element is a 2-tuple: `[BigInt, string]` where the first element is the\n * numeric value and the second is the word for that value. The array MUST be\n * ordered from largest to smallest (descending) for the greedy algorithm to work correctly.\n *\n * @type {Array.<Array.<(bigint|string)>>}\n * @example\n * // English scale words (descending order):\n * // [[1000000000n, 'billion'], [1000000n, 'million'], [1000n, 'thousand'], [100n, 'hundred'], ..., [1n, 'one']]\n */\n scaleWordPairs\n\n /**\n * Return the word associated with an exact scale word-set numeric value.\n *\n * @param {bigint|number} scaleValue Numeric word-set object key (prefer BigInt for exact matching).\n * @returns {string|undefined} The word for the provided scale value, or `undefined`.\n */\n getScaleWord (scaleValue) {\n const matchingPair = this.scaleWordPairs.find((pair) => pair[0] === scaleValue)\n return matchingPair?.[1]\n }\n\n /**\n * Decompose a whole-number into a sequence of scale word-sets.\n *\n * This internal helper returns a nested structure that represents quantities and\n * their matching scale words (e.g. `[{ 'one': 1n }, { 'hundred': 100n }, ...]`).\n * The result is designed to be reduced by `mergeWordSets()` using language-specific `mergeScales()`.\n *\n * For quantities > 1, the multiplier is recursively decomposed. For quantity = 1,\n * the implicit \"one\" is represented with `{ 'one': 1n }` and typically omitted during mergeScales().\n *\n * @protected\n * @param {bigint} wholeNumber The integer value to decompose (BigInt preferred).\n * @returns {Array<Object|Array>} An array of word-set objects and possibly nested arrays.\n */\n decomposeToScales (wholeNumber) {\n const decomposeWordSets = []\n let remainingValue = wholeNumber\n\n do {\n const matchingScaleWordPair = this.scaleWordPairs.find((scaleWordPair) => remainingValue >= scaleWordPair[0])\n if (!matchingScaleWordPair) break\n\n const multiplier = remainingValue === 0n ? 1n : remainingValue / matchingScaleWordPair[0]\n\n if (multiplier === 1n) {\n decomposeWordSets.push({ [this.getScaleWord(1n)]: 1n })\n } else {\n decomposeWordSets.push(this.decomposeToScales(multiplier))\n }\n\n decomposeWordSets.push({ [matchingScaleWordPair[1]]: matchingScaleWordPair[0] })\n\n remainingValue = remainingValue === 0n ? 0n : remainingValue % matchingScaleWordPair[0]\n } while (remainingValue > 0n)\n\n return decomposeWordSets\n }\n\n /**\n * Reduce a nested array of word-sets into a single merged word-set object.\n *\n * This method repeatedly applies the subclass `mergeScales()` operation until a single\n * object remains. It normalizes nested arrays by recursively merging them.\n *\n * @protected\n * @param {Array<Object|Array>} mergeWordSetsList Array of word-set objects and nested arrays.\n * @returns {Object} Merged word-set where the single object key is the language string\n * and its value is the numeric BigInt result for that string.\n */\n mergeWordSets (mergeWordSetsList) {\n while (mergeWordSetsList.length > 1) {\n const [firstWordSet, secondWordSet, ...remainingWordSets] = mergeWordSetsList\n\n if (!Array.isArray(firstWordSet) && !Array.isArray(secondWordSet)) {\n const merged = this.mergeScales(firstWordSet, secondWordSet)\n mergeWordSetsList = remainingWordSets.length > 0 ? [merged, remainingWordSets] : [merged]\n continue\n }\n\n const normalizedWordSets = mergeWordSetsList.map((wordSetElement) => {\n if (!Array.isArray(wordSetElement)) return wordSetElement\n return wordSetElement.length === 1 ? wordSetElement[0] : this.mergeWordSets(wordSetElement)\n })\n\n mergeWordSetsList = normalizedWordSets\n }\n\n return mergeWordSetsList[0]\n }\n\n /**\n * Combine two adjacent word-sets into a single merged word-set.\n *\n * This is the core language-specific method that must be implemented by subclasses\n * to define how adjacent word-sets are combined according to the language's grammar.\n * For example, English combines \"twenty\" + \"three\" → \"twenty-three\", while\n * French might combine \"quatre-vingts\" + \"dix\" → \"quatre-vingt-dix\".\n *\n * @abstract\n * @protected\n * @param {Object} leftWordSet Left operand as `{ word: bigint }` pair.\n * @param {Object} rightWordSet Right operand as `{ word: bigint }` pair.\n * @returns {Object} Single merged word-set object with combined text and numeric value.\n *\n * @example\n * // English implementation might handle:\n * // mergeScales({ 'twenty': 20n }, { 'three': 3n }) → { 'twenty-three': 23n }\n * // mergeScales({ 'one': 1n }, { 'hundred': 100n }) → { 'one hundred': 100n }\n */\n mergeScales (leftWordSet, rightWordSet) {\n throw new Error('mergeScales() must be implemented by subclass')\n }\n\n /**\n * Final string post-processing hook.\n *\n * Subclasses may override to apply language-specific whitespace, punctuation or\n * orthographic corrections.\n *\n * @protected\n * @param {string} output Merged language string produced by `convertWholePart` flow.\n * @returns {string} Final formatted string.\n */\n finalizeWords (output) {\n return output.trimEnd()\n }\n\n /**\n * Convert an integer value to its language-specific cardinal words.\n *\n * This method orchestrates decomposition, merging and final formatting. It does\n * not handle decimals or sign; those concerns are implemented in\n * `AbstractLanguage.convertToWords` which calls this helper for the whole-number part.\n *\n * @param {bigint|number} wholeNumber Whole-number value to convert (BigInt is preferred).\n * @returns {string} The cardinal representation for `value` in the language.\n */\n convertWholePart (wholeNumber) {\n const decomposeWordSets = this.decomposeToScales(wholeNumber)\n const mergedWordSet = this.mergeWordSets(decomposeWordSets)\n const resultString = Object.keys(mergedWordSet)[0]\n return this.finalizeWords(resultString)\n }\n}\n\nexport default GreedyScaleLanguage\n","import AbstractLanguage from '../classes/abstract-language.js'\n\nclass Thai extends AbstractLanguage {\n negativeWord = 'ลบ'\n decimalSeparatorWord = 'จุด'\n zeroWord = 'ศูนย์'\n wordSeparator = ''\n convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion\n\n // Digits map 1–9\n digits = ['หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า']\n\n /**\n * Convert numbers below one million to Thai words.\n *\n * @param {number} number The number to convert (0-999999).\n * @returns {string} The Thai representation.\n */\n convertBelowMillion (number) {\n if (number === 0) return ''\n\n let value = number\n const parts = []\n\n const hundredThousands = Math.trunc(value / 100000)\n value %= 100000\n const tenThousands = Math.trunc(value / 10000)\n value %= 10000\n const thousands = Math.trunc(value / 1000)\n value %= 1000\n const hundreds = Math.trunc(value / 100)\n value %= 100\n const tens = Math.trunc(value / 10)\n const ones = value % 10\n\n if (hundredThousands > 0) {\n parts.push(this.digits[hundredThousands - 1] + 'แสน')\n }\n\n if (tenThousands > 0) {\n if (tenThousands === 1) {\n parts.push('หนึ่งหมื่น')\n } else {\n parts.push(this.digits[tenThousands - 1] + 'หมื่น')\n }\n }\n\n if (thousands > 0) {\n parts.push(this.digits[thousands - 1] + 'พัน')\n }\n\n if (hundreds > 0) {\n parts.push(this.digits[hundreds - 1] + 'ร้อย')\n }\n\n if (tens > 0) {\n if (tens === 1) {\n parts.push('สิบ')\n } else if (tens === 2) {\n parts.push('ยี่สิบ')\n } else {\n parts.push(this.digits[tens - 1] + 'สิบ')\n }\n }\n\n if (ones > 0) {\n const hasHigher = hundredThousands > 0 || tenThousands > 0 || thousands > 0 || hundreds > 0 || tens > 0\n if (ones === 1 && (tens > 0 || hasHigher)) {\n parts.push('เอ็ด')\n } else {\n parts.push(this.digits[ones - 1])\n }\n }\n\n return parts.join('')\n }\n\n /**\n * Split a number into million-sized groups for processing.\n *\n * @param {bigint} number The number to split.\n * @returns {number[]} Array of number groups.\n */\n splitMillionGroups (number) {\n const groups = []\n let remaining = number\n\n const million = 1_000_000n\n while (remaining > 0n) {\n const chunk = Number(remaining % million)\n groups.unshift(chunk)\n remaining = remaining / million\n }\n\n return groups\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n\n const groups = this.splitMillionGroups(number)\n const parts = []\n\n for (let i = 0; i < groups.length; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n parts.push(this.convertBelowMillion(groupValue))\n const remaining = groups.length - i - 1\n if (remaining > 0) {\n parts.push('ล้าน'.repeat(remaining))\n }\n }\n\n return parts.join('')\n }\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Thai(options).convertToWords(value)\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar toObject = require('../internals/to-object');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar setArrayLength = require('../internals/array-set-length');\nvar doesNotExceedSafeInteger = require('../internals/does-not-exceed-safe-integer');\nvar fails = require('../internals/fails');\n\nvar INCORRECT_TO_LENGTH = fails(function () {\n return [].push.call({ length: 0x100000000 }, 1) !== 4294967297;\n});\n\n// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError\n// https://bugs.chromium.org/p/v8/issues/detail?id=12681\nvar properErrorOnNonWritableLength = function () {\n try {\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n Object.defineProperty([], 'length', { writable: false }).push();\n } catch (error) {\n return error instanceof TypeError;\n }\n};\n\nvar FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength();\n\n// `Array.prototype.push` method\n// https://tc39.es/ecma262/#sec-array.prototype.push\n$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, {\n // eslint-disable-next-line no-unused-vars -- required for `.length`\n push: function push(item) {\n var O = toObject(this);\n var len = lengthOfArrayLike(O);\n var argCount = arguments.length;\n doesNotExceedSafeInteger(len + argCount);\n for (var i = 0; i < argCount; i++) {\n O[len] = arguments[i];\n len++;\n }\n setArrayLength(O, len);\n return len;\n }\n});\n","'use strict';\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar add = require('../internals/set-helpers').add;\nvar clone = require('../internals/set-clone');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSimple = require('../internals/iterate-simple');\n\n// `Set.prototype.union` method\n// https://tc39.es/ecma262/#sec-set.prototype.union\nmodule.exports = function union(other) {\n var O = aSet(this);\n var keysIter = getSetRecord(other).getIterator();\n var result = clone(O);\n iterateSimple(keysIter, function (it) {\n add(result, it);\n });\n return result;\n};\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar Iterators = require('../internals/iterators');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar ArrayPrototype = Array.prototype;\n\n// check on default Array iterator\nmodule.exports = function (it) {\n return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar isCallable = require('../internals/is-callable');\nvar isObject = require('../internals/is-object');\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n};\n","'use strict';\nvar classof = require('../internals/classof-raw');\n\n// `IsArray` abstract operation\n// https://tc39.es/ecma262/#sec-isarray\n// eslint-disable-next-line es/no-array-isarray -- safe\nmodule.exports = Array.isArray || function isArray(argument) {\n return classof(argument) === 'Array';\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\n// eslint-disable-next-line es/no-set -- safe\nvar SetPrototype = Set.prototype;\n\nmodule.exports = {\n // eslint-disable-next-line es/no-set -- safe\n Set: Set,\n add: uncurryThis(SetPrototype.add),\n has: uncurryThis(SetPrototype.has),\n remove: uncurryThis(SetPrototype['delete']),\n proto: SetPrototype\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Italian language converter.\n *\n * Converts numbers to Italian words following Italian conventions:\n * - Phonetic contractions (removes duplicate vowels: \"ventotto\" not \"ventiotto\")\n * - Accentuation rules for \"tre\" in compounds (\"ventitré\" not \"ventitre\")\n * - Special handling for \"uno\" and vowel agreement\n * - Complex composition patterns for large numbers\n *\n * Architecture Note:\n * Unlike other GreedyScaleLanguage subclasses, Italian uses a custom algorithm\n * rather than the standard highest-matching-scale approach. This is necessary\n * because Italian's word formation rules are irregular and context-dependent.\n * See tensToCardinal(), hundredsToCardinal(), and bigNumberToCardinal().\n *\n * Features:\n * - Vowel elision (e.g., \"ventotto\" not \"ventiotto\")\n * - Accentuation of final \"tre\" (ventitré, trentacinque - note: accent on compound tres)\n * - Exponent-based large number naming (milione, miliardo, trilione)\n * - Custom word construction for hundreds and thousands\n */\nexport class Italian extends GreedyScaleLanguage {\n negativeWord = 'meno'\n decimalSeparatorWord = 'virgola'\n zeroWord = 'zero'\n cardinalWords = [\n this.zeroWord, 'uno', 'due', 'tre', 'quattro', 'cinque', 'sei', 'sette', 'otto',\n 'nove', 'dieci', 'undici', 'dodici', 'tredici', 'quattordici', 'quindici',\n 'sedici', 'diciassette', 'diciotto', 'diciannove'\n ]\n\n strTens = { 2: 'venti', 3: 'trenta', 4: 'quaranta', 6: 'sessanta' }\n\n exponentPrefixes = [this.zeroWord, 'm', 'b', 'tr', 'quadr', 'quint', 'sest', 'sett', 'ott', 'nov', 'dec']\n\n accentuate (string) {\n const splittedString = string.split(' ')\n\n const result = splittedString.map(word => {\n return word.slice(-3) === 'tre' && word.length > 3 ? word.replaceAll('tré', 'tre').slice(0, -3) + 'tré' : word.replaceAll('tré', 'tre')\n })\n return result.join(' ')\n }\n\n omitIfZero (numberToString) {\n return numberToString === this.zeroWord ? '' : numberToString\n }\n\n phoneticContraction (string) {\n return string.replaceAll('oo', 'o').replaceAll('ao', 'o').replaceAll('io', 'o').replaceAll('au', 'u').replaceAll('iu', 'u')\n }\n\n tensToCardinal (number) {\n const tens = Math.floor(number / 10)\n const units = number % 10\n const prefix = Object.prototype.hasOwnProperty.call(this.strTens, tens) ? this.strTens[tens] : this.cardinalWords[tens].slice(0, -1) + 'anta'\n const postfix = this.omitIfZero(this.cardinalWords[units])\n return this.phoneticContraction(prefix + postfix)\n }\n\n hundredsToCardinal (number) {\n const hundreds = Math.floor(number / 100)\n let prefix = 'cento'\n if (hundreds !== 1) {\n prefix = this.cardinalWords[hundreds] + prefix\n }\n const postfix = this.omitIfZero(this.convertWholePart(number % 100))\n return this.phoneticContraction(prefix + postfix)\n }\n\n thousandsToCardinal (number) {\n const thousands = Math.floor(number / 1000)\n const prefix = thousands === 1 ? 'mille' : this.convertWholePart(thousands) + 'mila'\n const postfix = this.omitIfZero(this.convertWholePart(number % 1000))\n return prefix + postfix\n }\n\n exponentLengthToString (exponentLength) {\n const prefix = this.exponentPrefixes[Math.floor(exponentLength / 6)]\n return exponentLength % 6 === 0 ? prefix + 'ilione' : prefix + 'iliardo'\n }\n\n bigNumberToCardinal (number) {\n const digits = [...number.toString()]\n\n let preDigits = digits.length % 3\n if (preDigits === 0) {\n preDigits = 3\n }\n\n const multiplier = digits.slice(0, preDigits) // first `preDigits` elements\n const exponent = digits.slice(preDigits) // without the first `preDigits` elements\n\n let prefix, postfix\n let infix = this.exponentLengthToString(exponent.length)\n\n if (multiplier.join('') === '1') {\n prefix = 'un '\n } else {\n prefix = this.convertWholePart(Math.trunc(Number(multiplier.join(''))))\n infix = ' ' + infix.slice(0, -1) + 'i' // without last element\n }\n\n const isSetsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value))\n if (isSetsEqual(new Set(exponent), new Set(['0']))) {\n postfix = ''\n } else {\n postfix = this.convertWholePart(Math.trunc(exponent.join('')))\n\n infix += (postfix.includes(' e ') ? ', ' : ' e ')\n }\n\n return prefix + infix + postfix\n }\n\n convertWholePart (number) {\n let words = ''\n\n if (number < 20) {\n words = this.cardinalWords[number]\n } else if (number < 100) {\n words = this.tensToCardinal(Number(number))\n } else if (number < 1000) {\n words = this.hundredsToCardinal(Number(number))\n } else if (number < 1_000_000) {\n words = this.thousandsToCardinal(Number(number))\n } else {\n words = this.bigNumberToCardinal(number)\n }\n\n return this.accentuate(words)\n }\n}\n\n/**\n * Converts a number to Italian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @returns {string} The number expressed in Italian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Italian(options).convertToWords(value)\n}\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar has = require('../internals/set-helpers').has;\nvar size = require('../internals/set-size');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSet = require('../internals/set-iterate');\nvar iterateSimple = require('../internals/iterate-simple');\nvar iteratorClose = require('../internals/iterator-close');\n\n// `Set.prototype.isDisjointFrom` method\n// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom\nmodule.exports = function isDisjointFrom(other) {\n var O = aSet(this);\n var otherRec = getSetRecord(other);\n if (size(O) <= otherRec.size) return iterateSet(O, function (e) {\n if (otherRec.includes(e)) return false;\n }, true) !== false;\n var iterator = otherRec.getIterator();\n return iterateSimple(iterator, function (e) {\n if (has(O, e)) return iteratorClose(iterator, 'normal', false);\n }) !== false;\n};\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * @typedef {Object} RomanianOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Romanian language converter.\n *\n * Converts numbers to Romanian words with full grammatical support:\n * - Gender agreement (masculine/feminine forms)\n * - Complex pluralization (singular/plural forms)\n * - \"De\" preposition insertion for groups >= 20\n * - Special feminine handling for thousands\n * - Proper case and agreement patterns\n *\n * Key Features:\n * - Gender-aware number forms (unu/una, doi/două, doisprezece/douăsprezece)\n * - Group-based algorithm:\n * 1. Split number into groups of 3 digits\n * 2. Convert each group using gender rules and special forms\n * 3. Insert \"de\" preposition for groups >= 20 (e.g., \"douăzeci de mii\")\n * 4. Append magnitude word with proper singular/plural form (mie/mii, milion/milioane)\n * 5. Join with spaces\n * - Special feminine units for thousands group\n * - Automatic \"de\" insertion rules (nouăsprezece mii vs douăzeci de mii)\n * - Proper singular/plural forms (mie/mii, milion/milioane)\n * - Support for very large numbers (up to decillions)\n *\n * Features:\n * - Feminine units for thousands group\n * - Support for very large numbers (up to decillions)\n */\nexport class Romanian extends AbstractLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'virgulă'\n zeroWord = 'zero'\n\n ones = {\n 1: 'unu',\n 2: 'doi',\n 3: 'trei',\n 4: 'patru',\n 5: 'cinci',\n 6: 'șase',\n 7: 'șapte',\n 8: 'opt',\n 9: 'nouă'\n }\n\n onesFeminine = {\n 1: 'una',\n 2: 'două',\n 3: 'trei',\n 4: 'patru',\n 5: 'cinci',\n 6: 'șase',\n 7: 'șapte',\n 8: 'opt',\n 9: 'nouă'\n }\n\n tens = {\n 0: 'zece',\n 1: 'unsprezece',\n 2: 'douăsprezece',\n 3: 'treisprezece',\n 4: 'paisprezece',\n 5: 'cincisprezece',\n 6: 'șaisprezece',\n 7: 'șaptesprezece',\n 8: 'optsprezece',\n 9: 'nouăsprezece'\n }\n\n tensMasculine = {\n 0: 'zece',\n 1: 'unsprezece',\n 2: 'doisprezece',\n 3: 'treisprezece',\n 4: 'paisprezece',\n 5: 'cincisprezece',\n 6: 'șaisprezece',\n 7: 'șaptesprezece',\n 8: 'optsprezece',\n 9: 'nouăsprezece'\n }\n\n twenties = {\n 2: 'douăzeci',\n 3: 'treizeci',\n 4: 'patruzeci',\n 5: 'cincizeci',\n 6: 'șaizeci',\n 7: 'șaptezeci',\n 8: 'optzeci',\n 9: 'nouăzeci'\n }\n\n hundreds = {\n 1: 'o sută',\n 2: 'două sute',\n 3: 'trei sute',\n 4: 'patru sute',\n 5: 'cinci sute',\n 6: 'șase sute',\n 7: 'șapte sute',\n 8: 'opt sute',\n 9: 'nouă sute'\n }\n\n /**\n * Romanian big units.\n * For each power group we keep: singular, plural, feminineUnits?, needsDe?\n * - 10^3: mie/mii (feminine units in chunk; \"de\" for chunk >= 20)\n * - 10^6: milion/milioane (\"de\" for chunk >= 20)\n * - 10^9: miliard/miliarde (\"de\" for chunk >= 20)\n */\n thousands = {\n 1: { singular: 'mie', plural: 'mii', feminine: true, needsDe: true }, // 10^3\n 2: { singular: 'milion', plural: 'milioane', feminine: false, needsDe: true }, // 10^6\n 3: { singular: 'miliard', plural: 'miliarde', feminine: false, needsDe: true }, // 10^9\n 4: { singular: 'trilion', plural: 'trilioane', feminine: false, needsDe: true }, // 10^12\n 5: { singular: 'cvadrilion', plural: 'cvadrilioane', feminine: false, needsDe: true }, // 10^15\n 6: { singular: 'cvintilion', plural: 'cvintilioane', feminine: false, needsDe: true }, // 10^18\n 7: { singular: 'sextilion', plural: 'sextilioane', feminine: false, needsDe: true }, // 10^21\n 8: { singular: 'septilion', plural: 'septilioane', feminine: false, needsDe: true }, // 10^24\n 9: { singular: 'octilion', plural: 'octilioane', feminine: false, needsDe: true }, // 10^27\n 10: { singular: 'decilion', plural: 'decilioane', feminine: false, needsDe: true } // 10^33\n }\n\n /**\n * Initializes the Romanian converter with language-specific options.\n *\n * @param {RomanianOptions} [options={}] Configuration options.\n */\n constructor ({ feminine = false } = {}) {\n super()\n\n this.feminine = feminine\n }\n\n /**\n * Split numeric string into BigInt groups of size x from left to right.\n * @param {string} n - The numeric string to split\n * @param {number} x - The size of each group\n * @returns {bigint[]} Array of BigInt groups\n */\n splitByX (n, x) {\n const results = []\n const l = n.length\n let result\n\n if (l > x) {\n const start = l % x\n if (start > 0) {\n result = n.slice(0, start)\n results.push(BigInt(result))\n }\n for (let index = start; index < l; index += x) {\n result = n.slice(index, index + x)\n results.push(BigInt(result))\n }\n } else {\n results.push(BigInt(n))\n }\n return results\n }\n\n getDigits (value) {\n const stringValue = value.toString().padStart(3, '0').slice(-3)\n const a = [...stringValue].toReversed()\n return a.map(BigInt)\n }\n\n /**\n * Romanian pluralization & \"de\" rule for big units.\n * - 1 → singular with article (\"o mie\", \"un milion\", \"un miliard\", …)\n * - otherwise → spell chunk + (optional \"de\") + plural\n * \"de\" is inserted when chunk >= 20 (e.g., \"douăzeci de mii/milioane/miliarde\").\n * @param {bigint} chunk - The chunk value\n * @param {object} form - The form object with singular, plural, feminine, needsDe properties\n * @returns {string} The pluralized form\n */\n romanianPluralize (chunk, form) {\n const n = Number(chunk)\n\n if (n === 1) {\n // article differs for feminine \"mie\" (o mie) vs the rest (un milion/miliard…)\n const article = form.feminine ? 'o' : 'un'\n return `${article} ${form.singular}`\n }\n\n // For 21 with big units, use feminine \"una\" with plural nouns\n if (n === 21 && form.needsDe) {\n return `douăzeci și una de ${form.plural}`\n }\n\n // spell the chunk itself (use feminine units for big numbers)\n const words = this.spellUnder1000(n, true)\n\n // \"de\" after >= 20 (covers 20, 21, 100, 101, 999, etc.)\n const needsDe = form.needsDe && n >= 20\n const de = needsDe ? ' de ' : ' '\n\n return `${words}${de}${form.plural}`\n }\n\n spellUnder100 (n, feminineUnits = false) {\n if (n < 10) {\n return (feminineUnits ? this.onesFeminine : this.ones)[n]\n }\n if (n < 20) {\n return this.tens[n - 10]\n }\n const t = Math.floor(n / 10)\n const u = n % 10\n return u\n ? `${this.twenties[t]} și ${(feminineUnits ? this.onesFeminine : this.ones)[u]}`\n : this.twenties[t]\n }\n\n spellUnder1000 (n, feminineUnits = false) {\n if (n < 100) return this.spellUnder100(n, feminineUnits)\n const h = Math.floor(n / 100)\n const r = n % 100\n const hundredWords = this.hundreds[h]\n if (!r) return hundredWords\n // Standard readable form: \"o sută unu\" (for units) or \"o sută cincizeci\" (for tens)\n const separator = ' '\n return `${hundredWords}${separator}${this.spellUnder100(r, feminineUnits)}`\n }\n\n /**\n * Override decimalDigitsToWords to use masculine forms for decimal places\n * @param {string} decimal Decimal string to convert\n * @returns {string} Value in written format\n */\n decimalDigitsToWords (decimal) {\n const words = []\n\n const chars = [...decimal]\n\n // Loop through characters adding leading zeros to words array\n let index = 0\n while (index < chars.length && chars[index] === '0') {\n words.push(this.zeroWord)\n index++\n }\n\n // Prevent further processing if entire string was zeros\n if (index === chars.length) {\n return words\n }\n\n // Convert and add remaining using masculine forms for decimal places\n const decimalNumber = BigInt(decimal)\n const masculineWords = this.toCardinalWithMasculine(decimalNumber)\n return [...words, masculineWords]\n }\n\n /**\n * Convert number to cardinal form using masculine units\n * @param {bigint} number Number to convert\n * @returns {string} Value in written format\n */\n toCardinalWithMasculine (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n\n for (const x of chunks) {\n let onesMap = []\n index = index - 1\n\n if (x === 0n) continue\n\n const [n1, n2, n3] = this.getDigits(x) // units, tens, hundreds (as BigInt)\n\n // hundreds\n if (n3 > 0n) {\n words.push(this.hundreds[Number(n3)])\n }\n\n // tens & teens\n if (n2 > 1n) {\n words.push(this.twenties[Number(n2)])\n }\n\n if (n2 === 1n) {\n words.push(this.tensMasculine[Number(n1)])\n } else if (n1 > 0n) {\n // Always use masculine units for decimal places\n onesMap = this.ones\n\n // if there is a twenty/treizeci/etc AND ones > 0 → add \"și\"\n if (n2 > 1n) words.push('și')\n words.push(onesMap[Number(n1)])\n }\n\n // big unit name (mie/mii, milion/milioane, …)\n if (index > 0) {\n const form = this.thousands[index]\n if (form) {\n words.push(this.romanianPluralize(x, form))\n } else {\n // For very large numbers beyond our defined units, just spell out the number\n words.push(this.spellUnder1000(Number(x), false))\n }\n }\n }\n\n return words.join(' ').replaceAll(/\\s+/g, ' ').trim()\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n let onesMap = []\n index = index - 1\n if (x === 0n) continue\n const [n1, n2, n3] = this.getDigits(x) // units, tens, hundreds (as BigInt)\n // hundreds (only for the last group, not for thousands)\n if (n3 > 0n && index === 0) {\n words.push(this.hundreds[Number(n3)])\n }\n // tens & teens (only for the last group, not for thousands)\n if (index === 0) {\n if (n2 > 1n) {\n words.push(this.twenties[Number(n2)])\n }\n if (n2 === 1n) {\n words.push(this.tens[Number(n1)])\n } else if (n1 > 0n) {\n // pick masculine/feminine units (only for the last group, not for thousands)\n const feminineUnits = this.feminine && index === 0\n onesMap = feminineUnits ? this.onesFeminine : this.ones\n // if there is a twenty/treizeci/etc AND ones > 0 → add \"și\"\n if (n2 > 1n) words.push('și')\n words.push(onesMap[Number(n1)])\n }\n }\n // big unit name (mie/mii, milion/milioane, …)\n if (index > 0) {\n const form = this.thousands[index]\n if (form) {\n words.push(this.romanianPluralize(x, form))\n } else {\n // For very large numbers beyond our defined units, just spell out the number\n words.push(this.spellUnder1000(Number(x), true))\n }\n }\n }\n return words.join(' ').replaceAll(/\\s+/g, ' ').trim()\n }\n}\n\n/**\n * Converts a number to Romanian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Romanian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Romanian(options).convertToWords(value)\n}\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = require('../internals/environment-v8-version');\nvar fails = require('../internals/fails');\nvar globalThis = require('../internals/global-this');\n\nvar $String = globalThis.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol('symbol detection');\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar isArray = require('../internals/is-array');\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Safari < 13 does not throw an error in this case\nvar SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () {\n // makes no sense without proper strict mode support\n if (this !== undefined) return true;\n try {\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n Object.defineProperty([], 'length', { writable: false }).length = 1;\n } catch (error) {\n return error instanceof TypeError;\n }\n}();\n\nmodule.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) {\n if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) {\n throw new $TypeError('Cannot set read only .length');\n } return O.length = length;\n} : function (O, length) {\n return O.length = length;\n};\n","'use strict';\nvar globalThis = require('../internals/global-this');\n\n// https://github.com/tc39/ecma262/pull/3467\nmodule.exports = function (METHOD_NAME, ExpectedError) {\n var Iterator = globalThis.Iterator;\n var IteratorPrototype = Iterator && Iterator.prototype;\n var method = IteratorPrototype && IteratorPrototype[METHOD_NAME];\n\n var CLOSED = false;\n\n if (method) try {\n method.call({\n next: function () { return { done: true }; },\n 'return': function () { CLOSED = true; }\n }, -1);\n } catch (error) {\n // https://bugs.webkit.org/show_bug.cgi?id=291195\n if (!(error instanceof ExpectedError)) CLOSED = false;\n }\n\n if (!CLOSED) return method;\n};\n","'use strict';\nvar check = function (it) {\n return it && it.Math === Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof global == 'object' && global) ||\n check(typeof this == 'object' && this) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || Function('return this')();\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * @typedef {Object} DutchOptions\n * @property {boolean} [includeOptionalAnd=false] Include optional \"en\" separator.\n * @property {boolean} [noHundredPairs=false] Disable comma before hundreds.\n * @property {boolean} [accentOne=true] Use accented \"één\" for one.\n */\n\n/**\n * Dutch language converter.\n *\n * Features:\n * - Optional \"en\" (and) separator for tens (includeOptionalAnd)\n * - Optional comma before hundreds (noHundredPairs)\n * - Compound word formation without hyphenation\n */\nexport class Dutch extends GreedyScaleLanguage {\n negativeWord = 'min'\n decimalSeparatorWord = 'komma'\n zeroWord = 'nul'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'quadriljard'],\n [1_000_000_000_000_000_000_000_000n, 'quadriljoen'],\n [1_000_000_000_000_000_000_000n, 'triljard'],\n [1_000_000_000_000_000_000n, 'triljoen'],\n [1_000_000_000_000_000n, 'biljard'],\n [1_000_000_000_000n, 'biljoen'],\n [1_000_000_000n, 'miljard'],\n [1_000_000n, 'miljoen'],\n [1000n, 'duizend'],\n [100n, 'honderd'],\n [90n, 'negentig'],\n [80n, 'tachtig'],\n [70n, 'zeventig'],\n [60n, 'zestig'],\n [50n, 'vijftig'],\n [40n, 'veertig'],\n [30n, 'dertig'],\n [20n, 'twintig'],\n [19n, 'negentien'],\n [18n, 'achttien'],\n [17n, 'zeventien'],\n [16n, 'zestien'],\n [15n, 'vijftien'],\n [14n, 'veertien'],\n [13n, 'dertien'],\n [12n, 'twaalf'],\n [11n, 'elf'],\n [10n, 'tien'],\n [9n, 'negen'],\n [8n, 'acht'],\n [7n, 'zeven'],\n [6n, 'zes'],\n [5n, 'vijf'],\n [4n, 'vier'],\n [3n, 'drie'],\n [2n, 'twee'],\n [1n, 'één'],\n [0n, 'nul']\n ]\n\n /**\n * Initializes the Dutch converter with language-specific options.\n *\n * @param {DutchOptions} [options={}] Configuration options.\n */\n constructor ({ includeOptionalAnd = false, noHundredPairs = false, accentOne = true } = {}) {\n super()\n\n this.includeOptionalAnd = includeOptionalAnd\n\n this.noHundredPairs = noHundredPairs\n\n this.accentOne = accentOne\n if (!this.accentOne) {\n this.scaleWordPairs[this.scaleWordPairs.length - 2][1] = 'een'\n }\n }\n\n /**\n * Merges two adjacent word-number pairs according to Dutch grammar rules.\n *\n * Dutch-specific rules:\n * - Implicit \"één\": `mergeScales({ 'één': 1n }, { 'duizend': 1000n })` → `{ 'duizend': 1000n }`\n * - Reversed digit order for tens + units: `mergeScales({ 'twintig': 20n }, { 'één': 1n })` → `{ 'ééntwintig': 21n }`\n * - Optional \"en\" separator based on includeOptionalAnd option\n * - Compound words without separators for most combinations\n * - Converts 'één' to 'een' in compound words (no accent in compounds)\n * - Space separators for large numbers (millions+)\n *\n * @param {Object} current The left operand as `{ word: BigInt }`.\n * @param {Object} next The right operand as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'één': 1n }, { 'duizend': 1000n }); // { 'duizend': 1000n }\n * mergeScales({ 'twintig': 20n }, { 'drie': 3n }); // { 'drieentwintig': 23n }\n */\n mergeScales (current, next) {\n let cText = Object.keys(current)[0]\n let nText = Object.keys(next)[0]\n const cNumber = Object.values(current)[0] // BigInt\n const nNumber = Object.values(next)[0] // BigInt\n\n // Implicit \"een\": omit before large multipliers (\"miljoen\" not \"een miljoen\")\n if (cNumber === 1n) {\n if (nNumber < 1_000_000n) {\n return next\n }\n cText = this.accentOne ? 'één' : 'een'\n }\n\n // Handle multiplication and spacing\n if (nNumber > cNumber) {\n let hadSpace = false\n // Large scale words (millions+): add space before multiplier\n if (nNumber >= 1_000_000n) {\n cText += ' '\n hadSpace = true\n } else if (nNumber > 100n) {\n // Hundreds and above: add space after multiplier\n nText += ' '\n hadSpace = true\n }\n // Convert 'één' to 'een' in compounds (when no space or accentOne disabled)\n if (!hadSpace || !this.accentOne) {\n cText = cText.replace(/één/g, 'een')\n nText = nText.replace(/één/g, 'een')\n }\n return { [`${cText}${nText}`]: cNumber * nNumber }\n }\n\n // Track if we're adding a space (which keeps words separate)\n let hasSpace = false\n\n if (nNumber < 10n && cNumber > 10n && cNumber < 100n) {\n const temporary = nText\n nText = cText\n const andTxt = temporary.endsWith('e') ? 'ën' : 'en'\n cText = `${temporary}${andTxt}`\n } else if (nNumber < 13n && cNumber < 1000n && this.includeOptionalAnd) {\n cText = `${cText}en`\n } else if (nNumber < 13n && cNumber >= 1000n && this.includeOptionalAnd) {\n nText = ` en ${nText}`\n hasSpace = true\n } else if (cNumber >= 1_000_000n) {\n cText += ' '\n hasSpace = true\n } else if (cNumber === 1000n) {\n cText += ' '\n hasSpace = true\n }\n\n // Convert 'één' to 'een' in direct compounds (no space)\n // Keep 'één' only if there's a space AND accentOne=true\n if (!hasSpace) {\n cText = cText.replace(/één/g, 'een')\n nText = nText.replace(/één/g, 'een')\n } else if (!this.accentOne) {\n cText = cText.replace(/één/g, 'een')\n nText = nText.replace(/één/g, 'een')\n }\n\n return { [`${cText}${nText}`]: cNumber + nNumber }\n }\n\n convertWholePart (value) {\n if (value >= 1100n && value < 10_000n && !this.noHundredPairs) {\n const high = value / 100n\n const low = value % 100n\n if (high % 10n !== 0n) {\n let result = super.convertWholePart(high) + 'honderd'\n if (low) {\n result +=\n (this.includeOptionalAnd ? ' en ' : ' ') + super.convertWholePart(low)\n }\n return result\n }\n }\n return super.convertWholePart(value)\n }\n}\n\n/**\n * Converts a number to Dutch cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Dutch class options).\n * @param {boolean} [options.includeOptionalAnd=false] Include optional 'en' (and) separator.\n * @param {boolean} [options.noHundredPairs=false] Don't combine hundreds with tens/units.\n * @param {boolean} [options.accentOne=true] Use accented 'één' for standalone 1.\n * @returns {string} The number expressed in Dutch words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(1); // 'één' (default accent)\n * convertToWords(1, { accentOne: false }); // 'een'\n * convertToWords(21); // 'eenentwintig' (no accent in compounds)\n * convertToWords(42); // 'tweeenveertig'\n * convertToWords('1.5'); // 'één komma vijf'\n */\nexport default function convertToWords (value, options = {}) {\n return new Dutch(options).convertToWords(value)\n}\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = function (object, key, value) {\n if (DESCRIPTORS) definePropertyModule.f(object, key, createPropertyDescriptor(0, value));\n else object[key] = value;\n};\n","'use strict';\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\nvar documentAll = typeof document == 'object' && document.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nmodule.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\nvar V8_PROTOTYPE_DEFINE_BUG = require('../internals/v8-prototype-define-bug');\nvar anObject = require('../internals/an-object');\nvar toPropertyKey = require('../internals/to-property-key');\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\n\nvar createSetLike = function (size) {\n return {\n size: size,\n has: function () {\n return false;\n },\n keys: function () {\n return {\n next: function () {\n return { done: true };\n }\n };\n }\n };\n};\n\nvar createSetLikeWithInfinitySize = function (size) {\n return {\n size: size,\n has: function () {\n return true;\n },\n keys: function () {\n throw new Error('e');\n }\n };\n};\n\nmodule.exports = function (name, callback) {\n var Set = getBuiltIn('Set');\n try {\n new Set()[name](createSetLike(0));\n try {\n // late spec change, early WebKit ~ Safari 17 implementation does not pass it\n // https://github.com/tc39/proposal-set-methods/pull/88\n // also covered engines with\n // https://bugs.webkit.org/show_bug.cgi?id=272679\n new Set()[name](createSetLike(-1));\n return false;\n } catch (error2) {\n if (!callback) return true;\n // early V8 implementation bug\n // https://issues.chromium.org/issues/351332634\n try {\n new Set()[name](createSetLikeWithInfinitySize(-Infinity));\n return false;\n } catch (error) {\n var set = new Set([1, 2]);\n return callback(set[name](createSetLikeWithInfinitySize(Infinity)));\n }\n }\n } catch (error) {\n return false;\n }\n};\n","/**\n * Filipino (Tagalog) language implementation for n2words\n *\n * Uses scale-based system with irregular patterns for numbers 1-19.\n * Filipino numbers follow patterns like: sampu (10), labinisa (11), dalawampu (20)\n *\n * @module lib/languages/tl\n * @example\n * import fil from './lib/languages/fil.js'\n * tl(42) // 'apatnapu dalawa'\n * tl(1000) // 'isang libo'\n */\n\nimport GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Filipino language implementation\n * Extends GreedyScaleLanguage with scale-based number conversion\n */\nclass FilipinoLanguage extends GreedyScaleLanguage {\n negativeWord = 'negatibo'\n decimalSeparatorWord = 'punto'\n zeroWord = 'zero'\n convertDecimalsPerDigit = true // Read decimals digit-by-digit\n\n scaleWordPairs = [\n [1000000000000n, 'trilyong'],\n [1000000000n, 'milyong'],\n [1000000n, 'milyong'],\n [1000n, 'libong'],\n [100n, 'daang'],\n\n // Tens\n [90n, 'siyamnapu'],\n [80n, 'walumpu'],\n [70n, 'pitumpu'],\n [60n, 'animnapu'],\n [50n, 'limampu'],\n [40n, 'apatnapu'],\n [30n, 'tatlumpu'],\n [20n, 'dalawampu'],\n\n // Teens (must come before 10 to be matched first)\n [19n, 'labinsiyam'],\n [18n, 'labingwalo'],\n [17n, 'labimpito'],\n [16n, 'labinanum'],\n [15n, 'labinlima'],\n [14n, 'labinapat'],\n [13n, 'labintatlo'],\n [12n, 'labindalawa'],\n [11n, 'labinisa'],\n [10n, 'sampu'],\n\n // Ones\n [9n, 'siyam'],\n [8n, 'walo'],\n [7n, 'pito'],\n [6n, 'anim'],\n [5n, 'lima'],\n [4n, 'apat'],\n [3n, 'tatlo'],\n [2n, 'dalawa'],\n [1n, 'isa'],\n [0n, 'zero']\n ]\n\n /**\n * Convert a whole number to Filipino words.\n * Overrides parent to handle zero explicitly.\n *\n * @param {bigint} wholeNumber The whole number to convert.\n * @returns {string} The Filipino representation.\n */\n convertWholePart (wholeNumber) {\n // Handle zero explicitly\n if (wholeNumber === 0n) {\n return this.zeroWord\n }\n return super.convertWholePart(wholeNumber)\n }\n\n /**\n * Merge two word-sets according to Filipino grammar rules.\n *\n * Features Filipino-specific rules:\n * - \"ng\" connector between words\n * - Consonant-ending words use \"na\" instead of \"ng\"\n * - Implicit \"one\" omission (\"isang daan\" → \"daan\")\n *\n * @param {Object} leftWordSet Left word-set as `{ word: BigInt }`.\n * @param {Object} rightWordSet Right word-set as `{ word: BigInt }`.\n * @returns {Object} Merged word-set with combined text and value.\n */\n mergeScales (leftWordSet, rightWordSet) {\n const leftWord = Object.keys(leftWordSet)[0]\n const rightWord = Object.keys(rightWordSet)[0]\n const leftValue = Object.values(leftWordSet)[0]\n const rightValue = Object.values(rightWordSet)[0]\n\n // Don't merge zero with anything - just return the non-zero value\n if (leftValue === 0n) {\n return rightWordSet\n }\n if (rightValue === 0n) {\n return leftWordSet\n }\n\n // Implicit \"one\" - omit when adding with values < 100\n if (leftValue === 1n && rightValue < 100n) {\n return rightWordSet\n }\n\n // Multiply when right is a scale word AND right > left\n // Use \"ng\" connector for Filipino, but consonant-ending words use \" na \"\n if (rightValue > leftValue && rightValue >= 100n) {\n // Words ending in consonants (not vowels) use \" na \" instead of \"ng\"\n const vowels = ['a', 'e', 'i', 'o', 'u']\n const lastChar = leftWord[leftWord.length - 1]\n if (!vowels.includes(lastChar)) {\n return {\n [`${leftWord} na ${rightWord}`]: leftValue * rightValue\n }\n }\n // Vowel-ending words add \"ng\"\n return {\n [`${leftWord}ng ${rightWord}`]: leftValue * rightValue\n }\n }\n\n // Special Filipino rule: certain tens words take \"-ng\" linker when followed by ones\n // Only limampu (50) confirmed to use this pattern\n if (leftValue >= 10n && leftValue < 100n && rightValue >= 1n && rightValue < 10n) {\n const tensWithNg = ['limampu']\n if (tensWithNg.includes(leftWord)) {\n return {\n [`${leftWord}ng ${rightWord}`]: leftValue + rightValue\n }\n }\n }\n\n // Default: space for addition\n return {\n [`${leftWord} ${rightWord}`]: leftValue + rightValue\n }\n }\n}\n\n/**\n * Convert a number to Filipino words\n *\n * @param {number|string|bigint} value - The number to convert\n * @param {Object} [options={}] - Conversion options\n * @returns {string} The Filipino word representation\n * @example\n * convertToWords(42) // 'apatnapu dalawa'\n * convertToWords(1000) // 'isang libo'\n * convertToWords(123456) // 'isang daang dalawampung tatlong libong apat na daang limampung anim'\n */\nexport default function convertToWords (value, options = {}) {\n return new FilipinoLanguage(options).convertToWords(value)\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar symmetricDifference = require('../internals/set-symmetric-difference');\nvar setMethodGetKeysBeforeCloning = require('../internals/set-method-get-keys-before-cloning-detection');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar FORCED = !setMethodAcceptSetLike('symmetricDifference') || !setMethodGetKeysBeforeCloning('symmetricDifference');\n\n// `Set.prototype.symmetricDifference` method\n// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference\n$({ target: 'Set', proto: true, real: true, forced: FORCED }, {\n symmetricDifference: symmetricDifference\n});\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar anObject = require('../internals/an-object');\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n","'use strict';\nvar uncurryThisAccessor = require('../internals/function-uncurry-this-accessor');\nvar SetHelpers = require('../internals/set-helpers');\n\nmodule.exports = uncurryThisAccessor(SetHelpers.proto, 'size', 'get') || function (set) {\n return set.size;\n};\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * Japanese language converter.\n *\n * Converts numbers to Japanese kanji numerals using the Sino-Japanese system:\n * - Uses kanji characters (一, 二, 三, etc.)\n * - Grouping by 万 (man, 10,000) and 億 (oku, 100,000,000)\n * - Unique scale units: 兆 (chō, trillion), 京 (kei, 10^16)\n * - Special rules for 1: omitted before 十 (10), 百 (100), 千 (1000), but kept for 万 and above\n *\n * Key Features:\n * - Sino-Japanese number system (standard for general counting)\n * - Grouping by powers of 10,000 (万-based system, not 1,000)\n * - Scale units: 万 (10^4), 億 (10^8), 兆 (10^12), 京 (10^16)\n * - Special handling of 一 (one) prefix\n * - Support for very large numbers up to 無量大数 (10^68)\n *\n * Algorithm:\n * 1. Split number into groups of 4 digits (万-based, not 3-digit thousand-based)\n * 2. Convert each group to kanji using special rules\n * 3. Append appropriate scale word (万, 億, 兆, etc.)\n * 4. Join all groups\n *\n * Special Rules:\n * - 10, 100, 1000: Don't use 一 prefix (十, 百, 千 not 一十, 一百, 一千)\n * - 10,000+: Keep 一 prefix (一万, 一億, 一兆)\n * - Zero: 零 or 〇 (both acceptable, 零 is more formal)\n */\nexport class Japanese extends AbstractLanguage {\n negativeWord = 'マイナス'\n decimalSeparatorWord = '点'\n zeroWord = '零'\n wordSeparator = '' // Japanese doesn't use spaces between characters\n convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion\n\n // Digits used for group conversion (1-9)\n digits = ['一', '二', '三', '四', '五', '六', '七', '八', '九']\n\n // Scale words for grouping by 10^4\n scales = [\n '', // 10^0 (ones)\n '万', // 10^4 (man)\n '億', // 10^8 (oku)\n '兆', // 10^12 (chō)\n '京', // 10^16 (kei)\n '垓', // 10^20 (gai)\n '秭', // 10^24 (jo/shi)\n '穣', // 10^28 (jō)\n '溝', // 10^32 (kō)\n '澗', // 10^36 (kan)\n '正', // 10^40 (sei)\n '載', // 10^44 (sai)\n '極', // 10^48 (goku)\n '恒河沙', // 10^52 (gōgasha)\n '阿僧祇', // 10^56 (asōgi)\n '那由他', // 10^60 (nayuta)\n '不可思議', // 10^64 (fukashigi)\n '無量大数' // 10^68 (muryōtaisū)\n ]\n\n /**\n * Converts a group of up to 4 digits to Japanese kanji.\n * Handles special rules for omitting 一 before 十, 百, 千.\n *\n * Rule: Within a group, omit 一 before 十/百/千 EXCEPT when:\n * - It's a lower group (not isTopGroup) AND\n * - It would be the only character in that position\n *\n * @param {bigint} num - Number from 0 to 9999\n * @param {boolean} isTopGroup - Whether this is the highest non-zero group\n * @returns {string} Japanese kanji representation\n */\n convertGroup (num, isTopGroup = false) {\n if (num === 0n) return ''\n\n const thousands = num / 1000n\n const hundreds = (num % 1000n) / 100n\n const tens = (num % 100n) / 10n\n const ones = num % 10n\n\n let result = ''\n\n // Thousands (千)\n if (thousands > 0n) {\n // Always omit 一 before 千 when thousands === 1\n if (thousands === 1n) {\n result += '千'\n } else {\n result += this.digits[Number(thousands) - 1] + '千'\n }\n }\n\n // Hundreds (百)\n if (hundreds > 0n) {\n // Always omit 一 before 百 when hundreds === 1\n if (hundreds === 1n) {\n result += '百'\n } else {\n result += this.digits[Number(hundreds) - 1] + '百'\n }\n }\n\n // Tens (十)\n if (tens > 0n) {\n // Always omit 一 before 十 when tens === 1\n if (tens === 1n) {\n result += '十'\n } else {\n result += this.digits[Number(tens) - 1] + '十'\n }\n }\n\n // Ones\n if (ones > 0n) {\n result += this.digits[Number(ones) - 1]\n }\n\n return result\n }\n\n /**\n * Converts a BigInt number to Japanese cardinal form.\n *\n * @param {bigint} number - The number to convert\n * @returns {string} Japanese kanji representation\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n\n let temp = number\n let scaleIndex = 0\n const groups = []\n\n // Split into groups of 4 digits (万-based system)\n while (temp > 0n) {\n const group = temp % 10000n\n if (group > 0n) {\n groups.push({ value: group, scale: scaleIndex })\n }\n temp = temp / 10000n\n scaleIndex++\n }\n\n // Reverse to process from highest to lowest\n groups.reverse()\n\n let result = ''\n\n for (let i = 0; i < groups.length; i++) {\n const { value, scale } = groups[i]\n const isTopGroup = (i === 0)\n\n const groupStr = this.convertGroup(value, isTopGroup)\n\n // For scales >= 1 (万 and above), always add the scale word\n if (scale >= 1) {\n // Special case: if group is 1 and scale >= 1, we need 一 before the scale\n if (value === 1n) {\n result += '一' + this.scales[scale]\n } else {\n result += groupStr + this.scales[scale]\n }\n } else {\n result += groupStr\n }\n }\n\n return result\n }\n}\n\n/**\n * Converts a value to cardinal (written) form in Japanese.\n *\n * @param {number|string|bigint} value - Number to convert.\n * @param {Object} [options] - Options for the converter.\n * @returns {string} Value in Japanese kanji numerals.\n * @throws {Error} If value is invalid.\n *\n * @example\n * convertToWords(42, { lang: 'ja' }); // '四十二'\n * convertToWords(1000, { lang: 'ja' }); // '千'\n * convertToWords(10000, { lang: 'ja' }); // '一万'\n */\nexport default function convertToWords (value, options = {}) {\n return new Japanese(options).convertToWords(value)\n}\n","'use strict';\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = require('../internals/indexed-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n","import TurkicLanguage from '../classes/turkic-language.js'\n\n/**\n * @typedef {Object} TurkishOptions\n * @property {boolean} [dropSpaces=false] Remove spaces between words if true.\n */\n\n/**\n * Turkish language converter.\n *\n * Inherits from TurkicLanguage shared patterns:\n * - Space-separated number combinations\n * - Omits '1' before hundreds and thousands\n * - Optional word spacing (dropSpaces option)\n * - Supports 'ş', 'ç', 'ğ', 'ı', 'ü', 'ö' characters\n */\nexport class Turkish extends TurkicLanguage {\n negativeWord = 'eksi'\n decimalSeparatorWord = 'virgül'\n zeroWord = 'sıfır'\n wordSeparator = ' '\n scaleWordPairs = [\n [1_000_000_000_000_000_000n, 'kentilyon'],\n [1_000_000_000_000_000n, 'katrilyon'],\n [1_000_000_000_000n, 'trilyon'],\n [1_000_000_000n, 'milyar'],\n [1_000_000n, 'milyon'],\n [1000n, 'bin'],\n [100n, 'yüz'],\n [90n, 'doksan'],\n [80n, 'seksen'],\n [70n, 'yetmiş'],\n [60n, 'altmış'],\n [50n, 'elli'],\n [40n, 'kırk'],\n [30n, 'otuz'],\n [20n, 'yirmi'],\n [10n, 'on'],\n [9n, 'dokuz'],\n [8n, 'sekiz'],\n [7n, 'yedi'],\n [6n, 'altı'],\n [5n, 'beş'],\n [4n, 'dört'],\n [3n, 'üç'],\n [2n, 'iki'],\n [1n, 'bir'],\n [0n, 'sıfır']\n ]\n\n /**\n * Initializes the Turkish converter with language-specific options.\n *\n * @param {TurkishOptions} [options={}] Configuration options.\n */\n constructor ({ dropSpaces = false } = {}) {\n super()\n\n this.dropSpaces = dropSpaces\n\n if (this.dropSpaces === true) {\n this.wordSeparator = ''\n }\n }\n}\n\n/**\n * Converts a number to Turkish cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see TR class).\n * @param {boolean} [options.dropSpaces=false] Remove spaces between words if true.\n * @returns {string} The number expressed in Turkish words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42, { lang: 'tr' }); // 'kırk iki'\n * convertToWords(42, { lang: 'tr', dropSpaces: true }); // 'kırkiki'\n */\nexport default function convertToWords (value, options = {}) {\n return new Turkish(options).convertToWords(value)\n}\n","'use strict';\nvar store = require('../internals/shared-store');\n\nmodule.exports = function (key, value) {\n return store[key] || (store[key] = value || {});\n};\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Polish language converter.\n *\n * Implements Polish number words using the Slavic language pattern:\n * - Polish number words (jeden, dwa, trzy, cztery, pięć...)\n * - Complex Slavic three-form pluralization (tysiąc/tysiące/tysięcy)\n * - Polish-specific declension patterns\n * - Distinctive Polish phonology and orthography\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"tysiąc\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"tysiące\")\n * * Form 3 (many): all other numbers (e.g., \"tysięcy\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n *\n * Features:\n * - Polish diacritical marks (ą, ć, ę, ł, ń, ś, ź, ż)\n * - Gender and case agreement\n * - Polish-specific number word endings\n *\n * Inherits from SlavicLanguage for complex pluralization algorithms.\n */\nexport class Polish extends SlavicLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'przecinek'\n zeroWord = 'zero'\n ones = {\n 1: 'jeden',\n 2: 'dwa',\n 3: 'trzy',\n 4: 'cztery',\n 5: 'pięć',\n 6: 'sześć',\n 7: 'siedem',\n 8: 'osiem',\n 9: 'dziewięć'\n }\n\n tens = {\n 0: 'dziesięć',\n 1: 'jedenaście',\n 2: 'dwanaście',\n 3: 'trzynaście',\n 4: 'czternaście',\n 5: 'piętnaście',\n 6: 'szesnaście',\n 7: 'siedemnaście',\n 8: 'osiemnaście',\n 9: 'dziewiętnaście'\n }\n\n twenties = {\n 2: 'dwadzieścia',\n 3: 'trzydzieści',\n 4: 'czterdzieści',\n 5: 'pięćdziesiąt',\n 6: 'sześćdziesiąt',\n 7: 'siedemdziesiąt',\n 8: 'osiemdziesiąt',\n 9: 'dziewięćdziesiąt'\n }\n\n hundreds = {\n 1: 'sto',\n 2: 'dwieście',\n 3: 'trzysta',\n 4: 'czterysta',\n 5: 'pięćset',\n 6: 'sześćset',\n 7: 'siedemset',\n 8: 'osiemset',\n 9: 'dziewięćset'\n }\n\n thousands = {\n 1: ['tysiąc', 'tysiące', 'tysięcy'], // 10^ 3\n 2: ['milion', 'miliony', 'milionów'], // 10^ 6\n 3: ['miliard', 'miliardy', 'miliardów'], // 10^ 9\n 4: ['bilion', 'biliony', 'bilionów'], // 10^ 12\n 5: ['biliard', 'biliardy', 'biliardów'], // 10^ 15\n 6: ['trylion', 'tryliony', 'trylionów'], // 10^ 18\n 7: ['tryliard', 'tryliardy', 'tryliardów'], // 10^ 21\n 8: ['kwadrylion', 'kwadryliony', 'kwadrylionów'], // 10^ 24\n 9: ['kwaryliard', 'kwadryliardy', 'kwadryliardów'], // 10^ 27\n 10: ['kwintylion', 'kwintyliony', 'kwintylionów'] // 10^ 30\n }\n\n /**\n * Implements Polish-specific three-form pluralization rules.\n *\n * Polish three-form system:\n * - Form 1 (singular): exactly n=1 (e.g., \"tysiąc\")\n * - Form 2 (few): n ends in 2-4, excluding teens (22-24, 32-34...) (e.g., \"tysiące\")\n * - Form 3 (many): all other numbers (e.g., \"tysięcy\")\n *\n * @param {bigint} n The number to classify.\n * @param {Array<string>} forms Array of [singular, few, many] word forms.\n * @returns {string} The appropriate form for the number n.\n */\n pluralize (n, forms) {\n if (n === 1n) {\n return forms[0]\n }\n\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n if (lastDigit < 5n && lastDigit > 1n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {\n return forms[1]\n }\n\n return forms[2]\n }\n\n /**\n * Converts a whole number to Polish cardinal form.\n *\n * Algorithm (chunk-based decomposition):\n * 1. Split number into chunks of 3 digits (right-to-left): ones, thousands, millions, etc.\n * 2. For each non-zero chunk:\n * a. Extract hundreds digit (n3), tens digit (n2), ones digit (n1)\n * b. Add hundreds word (e.g., \"sto\", \"dwieście\")\n * c. Add tens/ones (handles teens 10-19 separately from compound tens)\n * d. Add pluralized magnitude word (e.g., \"tysiące\", \"miliony\")\n * 3. Join all words with spaces\n *\n * Example: 1234 → chunks [1, 234] → \"jeden tysiąc dwieście trzydzieści cztery\"\n * - Chunk 1 (index=1, thousands): \"jeden\" + \"tysiąc\"\n * - Chunk 234 (index=0): \"dwieście\" + \"trzydzieści\" + \"cztery\"\n *\n * Special case: When chunk=1 at thousands+ levels, omit the ones word to avoid\n * redundancy with the pluralized magnitude (e.g., just \"tysiąc\" not \"jeden tysiąc\").\n *\n * @param {bigint} number The whole number to convert.\n * @returns {string} The number expressed in Polish words.\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n if (x === 0n) {\n continue\n }\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0n) {\n words.push(this.hundreds[n3])\n }\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n && !(index > 0 && x === 1n)) {\n words.push(this.ones[n1])\n }\n if (index > 0) {\n words.push(this.pluralize(x, this.thousands[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Polish cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {SlavicOptions} [options={}] Configuration options.\n * @returns {string} The number expressed in Polish words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Polish(options).convertToWords(value)\n}\n","import AbstractLanguage from '../classes/abstract-language.js'\n\n/**\n * Persian (Farsi) language converter.\n *\n * Converts numbers to Persian words using Persian-Arabic numerals:\n * - Right-to-left script orientation\n * - Base-10 decimal system with Persian number words\n * - Conjunction \"و\" (va/and) for compound numbers\n * - Traditional Persian number naming conventions\n *\n * Key Features:\n * - Named number lookup table (namedNumbers) for direct mapping 0-999\n * - Group-based algorithm for numbers >= 1000:\n * 1. Split into groups of 3 digits\n * 2. Convert each group to words using named table or recursion\n * 3. Append magnitude word (هزار/میلیون/میلیارد)\n * 4. Join with \"و\" (and) conjunction\n * - Special compound forms (دویست for 200, سیصد for 300)\n * - Proper Persian grammatical structure\n * - Support for large numbers (thousands, millions, billions, trillions)\n *\n * Features:\n * - Native Persian digits and words\n * - Special compound forms (e.g., دویست for 200, سیصد for 300)\n * - Support for large numbers (thousands, millions)\n * - Proper Persian grammatical structure\n */\nexport class Farsi extends AbstractLanguage {\n negativeWord = 'منفى'\n decimalSeparatorWord = 'ممیّز'\n zeroWord = 'صفر'\n namedNumbers = {\n 0: 'صفر',\n 1: 'یک',\n 2: 'دو',\n 3: 'سه',\n 4: 'چهار',\n 5: 'پنج',\n 6: 'شش',\n 7: 'هفت',\n 8: 'هشت',\n 9: 'نه',\n 10: 'ده',\n 11: 'یازده',\n 12: 'دوازده',\n 13: 'سیزده',\n 14: 'چهارده',\n 15: 'پانزده',\n 16: 'شانزده',\n 17: 'هفده',\n 18: 'هجده',\n 19: 'نوزده',\n 20: 'بیست',\n 30: 'سی',\n 40: 'چهل',\n 50: 'پنجاه',\n 60: 'شصت',\n 70: 'هفتاد',\n 80: 'هشتاد',\n 90: 'نود',\n 100: 'صد',\n 200: 'دویست',\n 300: 'سيصد',\n 400: 'چهار صد',\n 500: 'پانصد',\n 600: 'ششصد',\n 700: 'هفتصد',\n 800: 'هشتصد',\n 900: 'نهصد',\n 1000: 'هزار',\n 1_000_000: 'میلیون'\n }\n\n convertWholePart (number) {\n if (this.namedNumbers[number] && number !== 1_000_000n) {\n return this.namedNumbers[number]\n }\n\n if (number > 20n && number < 100n) {\n const xone = number % 10n\n const xten = number - xone\n return `${this.namedNumbers[xten]} و ${this.namedNumbers[xone]}`\n }\n\n if (number > 100n && number < 1000n) {\n const xhundred = 100n * (number / 100n)\n const tail = this.convertWholePart(number - xhundred)\n return `${this.namedNumbers[xhundred]} و ${tail}`\n }\n\n if (number > 1000n && number < 1_000_000n) {\n const thousandMultiplier = number / 1000n\n const namedThousandMultiplier =\n (thousandMultiplier === 1n\n ? ''\n : this.convertWholePart(thousandMultiplier)) +\n ' ' +\n this.namedNumbers[1000]\n const tailNumber = number - thousandMultiplier * 1000n\n const tail = tailNumber === 0n ? '' : ' ' + this.convertWholePart(tailNumber)\n return `${namedThousandMultiplier}${tail}`\n }\n\n if (number >= 1_000_000n) {\n const millionMultiplier = number / 1_000_000n\n const namedMillion =\n this.convertWholePart(millionMultiplier) + ' ' + this.namedNumbers[1_000_000]\n const tailNumber = number - millionMultiplier * 1_000_000n\n const tail = tailNumber === 0n ? '' : ' و ' + this.convertWholePart(tailNumber)\n return `${namedMillion}${tail}`\n }\n }\n}\n\n/**\n * Converts a number to Persian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @returns {string} The number expressed in Persian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Farsi(options).convertToWords(value)\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar isSubsetOf = require('../internals/set-is-subset-of');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar INCORRECT = !setMethodAcceptSetLike('isSubsetOf', function (result) {\n return result;\n});\n\n// `Set.prototype.isSubsetOf` method\n// https://tc39.es/ecma262/#sec-set.prototype.issubsetof\n$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, {\n isSubsetOf: isSubsetOf\n});\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar createElement = require('../internals/document-create-element');\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a !== 7;\n});\n","'use strict';\nvar aCallable = require('../internals/a-callable');\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this-clause');\nvar aCallable = require('../internals/a-callable');\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar bind = uncurryThis(uncurryThis.bind);\n\n// optional / simple context binding\nmodule.exports = function (fn, that) {\n aCallable(fn);\n return that === undefined ? fn : NATIVE_BIND ? bind(fn, that) : function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Croatian language converter.\n *\n * Implements Croatian number words using the Slavic language pattern:\n * - Croatian number words (jedan/jedna, dva/dvije, tri, četiri...)\n * - Gender-aware forms (masculine/feminine)\n * - Slavic three-form pluralization (tisuća/tisuće/tisuća)\n * - Croatian-specific declension endings\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"tisuća\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"tisuće\")\n * * Form 3 (many): all other numbers (e.g., \"tisuća\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n * - Gender-specific number forms for 1 and 2 (masculine/feminine dual forms)\n *\n * Features:\n * - Dual gender forms for 1 and 2 (jedan/jedna, dva/dvije)\n * - Latin script orthography\n * - Similar structure to Serbian\n *\n * Inherits from SlavicLanguage for complex pluralization algorithms.\n */\nexport class Croatian extends SlavicLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'zarez'\n zeroWord = 'nula'\n ones = {\n 1: ['jedan', 'jedna'],\n 2: ['dva', 'dvije'],\n 3: ['tri', 'tri'],\n 4: ['četiri', 'četiri'],\n 5: ['pet', 'pet'],\n 6: ['šest', 'šest'],\n 7: ['sedam', 'sedam'],\n 8: ['osam', 'osam'],\n 9: ['devet', 'devet']\n }\n\n tens = {\n 0: 'deset',\n 1: 'jedanaest',\n 2: 'dvanaest',\n 3: 'trinaest',\n 4: 'četrnaest',\n 5: 'petnaest',\n 6: 'šesnaest',\n 7: 'sedamnaest',\n 8: 'osamnaest',\n 9: 'devetnaest'\n }\n\n twenties = {\n 2: 'dvadeset',\n 3: 'trideset',\n 4: 'četrdeset',\n 5: 'pedeset',\n 6: 'šezdeset',\n 7: 'sedamdeset',\n 8: 'osamdeset',\n 9: 'devedeset'\n }\n\n hundreds = {\n 1: 'sto',\n 2: 'dvjesto',\n 3: 'tristo',\n 4: 'četiristo',\n 5: 'petsto',\n 6: 'šesto',\n 7: 'sedamsto',\n 8: 'osamsto',\n 9: 'devetsto'\n }\n\n SCALE = {\n 0: ['', '', '', false],\n 1: ['tisuća', 'tisuće', 'tisuća', true], // 10 ^ 3\n 2: ['milijun', 'milijuna', 'milijuna', false], // 10 ^ 6\n 3: ['milijarda', 'milijarde', 'milijarda', false], // 10 ^ 9\n 4: ['bilijun', 'bilijuna', 'bilijuna', false], // 10 ^ 12\n 5: ['bilijarda', 'bilijarde', 'bilijarda', false], // 10 ^ 15\n 6: ['trilijun', 'trilijuna', 'trilijuna', false], // 10 ^ 18\n 7: ['trilijarda', 'trilijarde', 'trilijarda', false], // 10 ^ 21\n 8: ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna', false], // 10 ^ 24\n 9: ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda', false], // 10 ^ 27\n 10: ['kvintilijun', 'kvintilijuna', 'kvintilijuna', false] // 10 ^ 30\n }\n\n pluralize (n, forms) {\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit === 1n) {\n return forms[0]\n }\n\n if ((lastTwoDigits < 10n || lastTwoDigits > 20n) && lastDigit > 1n && lastDigit < 5n) {\n return forms[1]\n }\n\n return forms[2]\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0n) {\n words.push(this.hundreds[n3])\n }\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n) {\n const isFeminine = (this.feminine || this.SCALE[index][3])\n const genderIndex = isFeminine ? 1 : 0\n words.push(this.ones[n1][genderIndex])\n }\n if ((index > 0) && (x !== 0n)) {\n words.push(this.pluralize(x, this.SCALE[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Croatian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Croatian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Croatian(options).convertToWords(value)\n}\n","'use strict';\nvar shared = require('../internals/shared');\nvar uid = require('../internals/uid');\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n","'use strict';\nvar toLength = require('../internals/to-length');\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n","'use strict';\nmodule.exports = {};\n","'use strict';\nvar defineBuiltIn = require('../internals/define-built-in');\n\nmodule.exports = function (target, src, options) {\n for (var key in src) defineBuiltIn(target, key, src[key], options);\n return target;\n};\n","/**\n * Abstract base class for language converters.\n *\n * What this class handles:\n * - Validates and normalizes caller input (`number | string | bigint`), rejecting NaN/invalid strings.\n * - Splits sign, whole, and decimal parts, caching the whole part for languages that need it.\n * - Delegates whole-number wording to `convertWholePart(wholeNumber)` implemented by subclasses.\n * - Converts decimals via `decimalDigitsToWords()`, preserving leading zeros and supporting per-digit mode when `convertDecimalsPerDigit` is true.\n *\n * What subclasses must provide:\n * - `convertWholePart(wholeNumber)` method implementation (required; abstract).\n * - `negativeWord` class property (word preceding negative numbers, e.g., \"minus\").\n * - `zeroWord` class property (word for digit 0, e.g., \"zero\").\n * - `decimalSeparatorWord` class property (word between whole and decimal, e.g., \"point\").\n * - `wordSeparator` class property (word separator in output, typically a space).\n * Optional: override `convertDecimalsPerDigit`, `digits`, or `convertDigitToWord()` for custom behavior.\n *\n * This class stays minimal; language grammar lives in subclasses.\n *\n * @abstract\n */\nclass AbstractLanguage {\n /**\n * Word that precedes negative numbers (e.g., \"minus\", \"negative\", \"moins\").\n * @type {string}\n */\n negativeWord = ''\n\n /**\n * Word that separates whole and decimal parts (e.g., \"point\", \"virgule\", \"comma\").\n * @type {string}\n */\n decimalSeparatorWord = ''\n\n /**\n * Word representation for the digit 0 (e.g., \"zero\", \"zéro\", \"null\").\n * @type {string}\n */\n zeroWord = ''\n\n /**\n * Character(s) used to separate words in the output (typically a space).\n * @type {string}\n */\n wordSeparator = ' '\n\n /**\n * Cached whole number portion from the most recent conversion.\n * Some languages need access to this value during conversion for\n * pluralization rules or special cases (e.g., Czech, Hebrew).\n * @type {bigint}\n */\n cachedWholeNumber = 0n\n\n /**\n * Whether to convert decimal digits individually rather than grouped.\n * - `true`: Each digit converted separately (e.g., \"05\" → \"zero five\")\n * - `false`: Leading zeros preserved, remaining grouped (e.g., \"14\" → \"fourteen\")\n * Used by languages like Japanese, Thai, Tamil, Telugu.\n * @type {boolean}\n */\n convertDecimalsPerDigit = false\n\n /**\n * Optional array of digit words for direct lookup in `convertDigitToWord()`.\n * - Length 10: indices 0–9 map directly to digit words\n * - Length 9: indices 0–8 map to words for digits 1–9\n * - `null`: Falls back to `convertWholePart()` for digit conversion\n * @type {string[]|null}\n */\n digits = null\n\n /**\n * Convert a single decimal digit (0-9) to its word representation.\n *\n * Default behavior:\n * - 0 returns the language's `zeroWord`\n * - If a `digits` array is present, use it for direct lookup\n * - Length 10: indices 0–9 map directly\n * - Length 9: indices 1–9 map via `idx - 1`\n * - Otherwise delegate to `convertWholePart(digit)`\n *\n * Subclasses may override this for custom logic.\n *\n * @protected\n * @param {bigint} digit A single digit value (0-9) as BigInt\n * @returns {string} The word representation of the digit\n */\n convertDigitToWord (digit) {\n const idx = Number(digit)\n if (idx === 0) return this.zeroWord\n\n if (Array.isArray(this.digits)) {\n if (this.digits.length === 10) {\n return this.digits[idx] ?? this.zeroWord\n }\n if (this.digits.length === 9) {\n return this.digits[idx - 1] ?? this.zeroWord\n }\n }\n\n return this.convertWholePart(digit)\n }\n\n /**\n * Convert the decimal fractional digits into words.\n *\n * Behavior depends on the `convertDecimalsPerDigit` class property:\n *\n * **Per-digit mode** (`convertDecimalsPerDigit: true`):\n * - Each decimal digit is converted individually using `convertDigitToWord()`\n * - Example: \"05\" -> [zero, 'five'], \"14\" -> ['one', 'four']\n * - Used by: Japanese, Thai, Tamil, Telugu\n *\n * **Grouped mode** (default, `convertDecimalsPerDigit: false`):\n * - Leading zeros are preserved as individual `zeroWord` entries\n * - Remaining digits are grouped and converted as a number\n * - Example: \"05\" -> [zero, 'five'], \"14\" -> ['fourteen']\n * - Used by: Most languages (English, Spanish, French, etc.)\n *\n * @protected\n * @param {string} decimalString The decimal digits as a string (e.g. `'05'` for 3.05).\n * @returns {Array<string>} Array of word tokens representing the fractional part.\n *\n * @example\n * // Per-digit mode\n * decimalDigitsToWords('05'); // -> [this.zeroWord, 'five']\n * decimalDigitsToWords('14'); // -> ['one', 'four']\n *\n * // Grouped mode\n * decimalDigitsToWords('05'); // -> [this.zeroWord, 'five']\n * decimalDigitsToWords('14'); // -> ['fourteen']\n */\n decimalDigitsToWords (decimalString) {\n const words = []\n const len = decimalString.length\n\n if (this.convertDecimalsPerDigit) {\n for (let i = 0; i < len; i++) {\n const decimalDigit = BigInt(decimalString[i])\n words.push(this.convertDigitToWord(decimalDigit))\n }\n return words\n }\n\n // Default grouped-decimal behavior with leading zero preservation\n let i = 0\n while (i < len && decimalString[i] === '0') {\n words.push(this.zeroWord)\n i++\n }\n\n if (i === len) return words\n\n const remainingDigits = decimalString.slice(i)\n words.push(this.convertWholePart(BigInt(remainingDigits)))\n\n return words\n }\n\n /**\n * Convert a numeric input into its language cardinal representation.\n *\n * This is the public entry point used by consumers. It normalizes the input\n * (accepting `number | string | bigint`), validates it, splits sign and\n * fractional parts, and delegates whole-number conversion to\n * `convertWholePart(BigInt)` and fractional conversion to `decimalDigitsToWords()`.\n *\n * Errors and validation:\n * - Passing `NaN` (as `number`) throws `TypeError`.\n * - Passing a non-numeric `string` throws `Error`.\n * - Passing an unsupported type throws `TypeError`.\n *\n * @public\n * @param {number|string|bigint} value Numeric input to convert. Strings may include a single `.` decimal marker.\n * @returns {string} The localized cardinal string.\n * @throws {TypeError|Error} For invalid input as described above.\n */\n convertToWords (value) {\n // Normalize and validate input\n const inputType = typeof value\n\n if (inputType === 'number') {\n if (Number.isNaN(value)) throw new TypeError('NaN is not an accepted number.')\n value = value.toString()\n } else if (inputType === 'string') {\n value = value.trim()\n if (value.length === 0 || Number.isNaN(Number(value))) { throw new Error('Invalid number format: \"' + value + '\"') }\n } else if (inputType !== 'bigint') {\n throw new TypeError(\n 'Invalid variable type, expected number|string|bigint, received: ' + inputType\n )\n }\n\n const words = []\n\n // Detect negativity and strip sign for further processing.\n // Must check before type coercion for BigInt (comparison works but slice does not).\n let isNegative = false\n if (inputType === 'bigint') {\n if (value < 0n) {\n isNegative = true\n value = -value\n }\n } else {\n // For strings, check first character before normalization\n if (value[0] === '-') {\n isNegative = true\n value = value.slice(1)\n }\n }\n\n // Extract whole and decimal parts based on type.\n // BigInt has no decimal point; strings may contain a single '.'.\n // Default whole part to '0' if empty (e.g., '.5' -> '0' + '.5')\n let wholeNumber\n let decimalPart\n if (inputType === 'bigint') {\n wholeNumber = value\n } else {\n const decimalPointIndex = value.indexOf('.')\n if (decimalPointIndex === -1) {\n wholeNumber = BigInt(value)\n } else {\n const wholePartString = value.slice(0, decimalPointIndex) || '0'\n wholeNumber = BigInt(wholePartString)\n decimalPart = value.slice(decimalPointIndex + 1)\n }\n }\n\n this.cachedWholeNumber = wholeNumber\n\n if (isNegative) words.push(this.negativeWord)\n\n words.push(this.convertWholePart(wholeNumber))\n\n // Append decimal portion if present (separator + fractional digits)\n if (decimalPart) {\n words.push(this.decimalSeparatorWord)\n words.push(...this.decimalDigitsToWords(decimalPart))\n }\n\n return words.join(this.wordSeparator)\n }\n\n /**\n * Convert a BigInt whole number to its cardinal word representation.\n *\n * This is a template method that subclasses MUST implement to provide\n * language-specific number conversion logic.\n *\n * @abstract\n * @param {bigint} wholeNumber The whole number part to convert\n * @returns {string} The cardinal representation in the target language\n */\n convertWholePart (wholeNumber) {\n throw new Error('convertWholePart() must be implemented by subclass')\n }\n}\n\nexport default AbstractLanguage\n","'use strict';\nvar anObject = require('../internals/an-object');\nvar iteratorClose = require('../internals/iterator-close');\n\n// call something on iterator step with safe closing on error\nmodule.exports = function (iterator, fn, value, ENTRIES) {\n try {\n return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);\n } catch (error) {\n iteratorClose(iterator, 'throw', error);\n }\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Swedish language converter.\n *\n * Converts numbers to Swedish words, supporting:\n * - Negative numbers (prepended with \"minus\")\n * - Decimal numbers (word \"komma\" between whole and fractional parts)\n * - Numbers up to quadrillions\n *\n * Merge rules:\n * - Hyphenated for compound tens (e.g., \"tjugo-tre\")\n * - \"och\" (and) after hundreds (e.g., \"hundra och ett\")\n * - Space-separated for larger composites (e.g., \"en miljon\")\n */\nexport class Swedish extends GreedyScaleLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'komma'\n zeroWord = 'noll'\n wordSeparator = ' '\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'kvadriljon'],\n [1_000_000_000_000_000_000_000_000n, 'triljon'],\n [1_000_000_000_000_000_000_000n, 'biljon'],\n [1_000_000_000_000_000_000n, 'miljard'],\n [1_000_000_000_000n, 'biljon'],\n [1_000_000_000n, 'miljard'],\n [1_000_000n, 'miljon'],\n [1000n, 'tusen'],\n [100n, 'hundra'],\n [90n, 'nittio'],\n [80n, 'åttio'],\n [70n, 'sjuttio'],\n [60n, 'sextio'],\n [50n, 'femtio'],\n [40n, 'fyrtio'],\n [30n, 'trettio'],\n [20n, 'tjugo'],\n [19n, 'nitton'],\n [18n, 'arton'],\n [17n, 'sjutton'],\n [16n, 'sexton'],\n [15n, 'femton'],\n [14n, 'fjorton'],\n [13n, 'tretton'],\n [12n, 'tolv'],\n [11n, 'elva'],\n [10n, 'tio'],\n [9n, 'nio'],\n [8n, 'åtta'],\n [7n, 'sju'],\n [6n, 'sex'],\n [5n, 'fem'],\n [4n, 'fyra'],\n [3n, 'tre'],\n [2n, 'två'],\n [1n, 'ett'],\n [0n, 'noll']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to Swedish grammar rules.\n *\n * Swedish-specific rules:\n * - Implicit \"ett\": `mergeScales({ 'ett': 1n }, { 'hundra': 100n })` → `{ 'hundra': 100n }`\n * - Hyphenated compounds: `mergeScales({ 'tjugo': 20n }, { 'tre': 3n })` → `{ 'tjugo-tre': 23n }`\n * - \"och\" after hundreds: `mergeScales({ 'hundra': 100n }, { 'ett': 1n })` → `{ 'hundra och ett': 101n }`\n * - \"en\" for millions: `mergeScales({ 'ett': 1n }, { 'miljon': 1000000n })` → `{ 'en miljon': 1000000n }`\n *\n * @param {Object} leftPair Left word-set as `{ word: BigInt }`.\n * @param {Object} rightPair Right word-set as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'ett': 1n }, { 'hundra': 100n }); // { 'hundra': 100n }\n * mergeScales({ 'tjugo': 20n }, { 'tre': 3n }); // { 'tjugo-tre': 23n }\n */\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const leftNumber = Object.values(leftPair)[0]\n const rightNumber = Object.values(rightPair)[0]\n\n if (leftNumber === 1n && rightNumber < 100n) {\n return rightPair\n }\n\n // Omit 'ett' before 'hundra' and 'tusen'\n if (leftNumber === 1n && (rightNumber === 100n || rightNumber === 1000n)) {\n return rightPair\n }\n\n if (leftNumber < 100n && leftNumber > rightNumber) {\n return { [`${leftWord}-${rightWord}`]: leftNumber + rightNumber }\n }\n\n if (leftNumber >= 100n && rightNumber < 100n) {\n return { [`${leftWord} och ${rightWord}`]: leftNumber + rightNumber }\n }\n\n if (rightNumber > leftNumber) {\n if (leftNumber === 1n && rightNumber >= 1_000_000n) {\n return { [`en ${rightWord}`]: leftNumber * rightNumber }\n }\n return { [`${leftWord} ${rightWord}`]: leftNumber * rightNumber }\n }\n\n return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }\n }\n}\n\n/**\n * Converts a number to Swedish cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Swedish class options).\n * @returns {string} The number expressed in Swedish words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'fyrtio-två'\n * convertToWords('1.5'); // 'ett komma fem'\n */\nexport default function convertToWords (value, options = {}) {\n return new Swedish(options).convertToWords(value)\n}\n","'use strict';\nmodule.exports = false;\n","import { French } from './fr.js'\n\n/**\n * @typedef {Object} BelgianFrenchOptions\n * @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds.\n */\n\n/**\n * Belgian French language converter.\n *\n * Extends the French converter with Belgian French regional variant:\n * - Uses \"septante\" (70) instead of \"soixante-dix\"\n * - Uses \"nonante\" (90) instead of \"quatre-vingt-dix\"\n * - Maintains standard French \"quatre-vingts\" for 80\n * - More regular and logical number system than standard French\n *\n * Features:\n * - Regional number word variations (septante, nonante)\n * - Simplified tens naming (no complex arithmetic)\n * - Inherits all other French grammar rules from FR class\n * - Same pluralization and hyphenation patterns as standard French\n */\nexport class BelgianFrench extends French {\n /**\n * Initializes the Belgian French converter.\n *\n * @param {BelgianFrenchOptions} [options={}] Configuration options.\n */\n constructor (options = {}) {\n super(options)\n // Fill the empty placeholder slots with Belgian variants\n // First empty slot (index 10) is for 90n (between 100n and 80n)\n // Second empty slot (index 12) is for 70n (between 80n and 60n)\n this.scaleWordPairs = this.scaleWordPairs.map((pair, index) => {\n if (Array.isArray(pair) && pair.length === 0) {\n // Check next pair to determine which slot this is\n const nextPair = this.scaleWordPairs[index + 1]\n if (nextPair && nextPair[0] === 80n) {\n return [90n, 'nonante']\n } else if (nextPair && nextPair[0] === 60n) {\n return [70n, 'septante']\n }\n }\n return pair\n })\n }\n}\n\n/**\n * Converts a number to Belgian French cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds.\n * @returns {string} The number expressed in Belgian French words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new BelgianFrench(options).convertToWords(value)\n}\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar create = require('../internals/object-create');\nvar defineProperty = require('../internals/object-define-property').f;\n\nvar UNSCOPABLES = wellKnownSymbol('unscopables');\nvar ArrayPrototype = Array.prototype;\n\n// Array.prototype[@@unscopables]\n// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables\nif (ArrayPrototype[UNSCOPABLES] === undefined) {\n defineProperty(ArrayPrototype, UNSCOPABLES, {\n configurable: true,\n value: create(null)\n });\n}\n\n// add a key to Array.prototype[@@unscopables]\nmodule.exports = function (key) {\n ArrayPrototype[UNSCOPABLES][key] = true;\n};\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\nvar copyConstructorProperties = require('../internals/copy-constructor-properties');\nvar isForced = require('../internals/is-forced');\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = globalThis;\n } else if (STATIC) {\n target = globalThis[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = globalThis[TARGET] && globalThis[TARGET].prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Czech language converter.\n *\n * Implements Czech number words using the Slavic language pattern:\n * - Czech number words (jedna, dva, tři, čtyři, pět...)\n * - Slavic three-form pluralization (tisíc/tisíce/tisíc)\n * - Gender agreement for numbers 1-2\n * - Czech-specific number word endings\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic languages\n * * Form 1 (singular): 1 (e.g., \"tisíc\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"tisíce\")\n * * Form 3 (many): all other numbers (e.g., \"tisíc\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n *\n * Inherits from SlavicLanguage:\n * - Complex pluralization rules (one/few/many forms)\n * - Group-based large number handling (chunk decomposition via splitByX())\n * - Proper declension patterns via pluralize() method\n */\nexport class Czech extends SlavicLanguage {\n negativeWord = 'mínus'\n zeroWord = 'nula'\n ones = {\n 1: 'jedna',\n 2: 'dva',\n 3: 'tři',\n 4: 'čtyři',\n 5: 'pět',\n 6: 'šest',\n 7: 'sedm',\n 8: 'osm',\n 9: 'devět'\n }\n\n tens = {\n 0: 'deset',\n 1: 'jedenáct',\n 2: 'dvanáct',\n 3: 'třináct',\n 4: 'čtrnáct',\n 5: 'patnáct',\n 6: 'šestnáct',\n 7: 'sedmnáct',\n 8: 'osmnáct',\n 9: 'devatenáct'\n }\n\n twenties = {\n 2: 'dvacet',\n 3: 'třicet',\n 4: 'čtyřicet',\n 5: 'padesát',\n 6: 'šedesát',\n 7: 'sedmdesát',\n 8: 'osmdesát',\n 9: 'devadesát'\n }\n\n hundreds = {\n 1: 'sto',\n 2: 'dvě stě',\n 3: 'tři sta',\n 4: 'čtyři sta',\n 5: 'pět set',\n 6: 'šest set',\n 7: 'sedm set',\n 8: 'osm set',\n 9: 'devět set'\n }\n\n thousands = {\n 1: ['tisíc', 'tisíce', 'tisíc'], // 10^ 3\n 2: ['milion', 'miliony', 'milionů'], // 10^ 6\n 3: ['miliarda', 'miliardy', 'miliard'], // 10^ 9\n 4: ['bilion', 'biliony', 'bilionů'], // 10^ 12\n 5: ['biliarda', 'biliardy', 'biliard'], // 10^ 15\n 6: ['trilion', 'triliony', 'trilionů'], // 10^ 18\n 7: ['triliarda', 'triliardy', 'triliard'], // 10^ 21\n 8: ['kvadrilion', 'kvadriliony', 'kvadrilionů'], // 10^ 24\n 9: ['kvadriliarda', 'kvadriliardy', 'kvadriliard'], // 10^ 27\n 10: ['quintillion', 'quintilliony', 'quintillionů'] // 10^ 30\n }\n\n /**\n * Returns the Czech word for the decimal separator based on the whole number.\n *\n * @returns {string} The Czech word for the decimal separator.\n */\n get decimalSeparatorWord () {\n if (this.cachedWholeNumber === 0n || this.cachedWholeNumber === 1n) {\n return 'celá'\n } else if (this.cachedWholeNumber >= 2n && this.cachedWholeNumber <= 4n) {\n return 'celé'\n } else {\n return 'celých'\n }\n }\n\n /**\n * Initializes the Czech converter with language-specific options.\n *\n * @param {SlavicOptions} [options={}] Configuration options (inherited from SlavicLanguage).\n */\n constructor (options = {}) {\n super(options)\n\n // Remove the inherited decimalSeparatorWord property so our getter works\n delete this.decimalSeparatorWord\n }\n\n /**\n * Implements Czech-specific three-form pluralization rules.\n *\n * Czech three-form system:\n * - Form 1 (singular): exactly n=1 (e.g., \"tisíc\")\n * - Form 2 (few): n ends in 2-4, excluding teens (22-24, 32-34...) (e.g., \"tisíce\")\n * - Form 3 (many): all other numbers (e.g., \"tisíc\" for 0, 5+)\n *\n * @param {bigint} n The number to classify.\n * @param {Array<string>} forms Array of [singular, few, many] word forms.\n * @returns {string} The appropriate form for the number n.\n */\n pluralize (n, forms) {\n if (n === 1n) {\n return forms[0]\n }\n\n // Check if n is in the \"few\" form range (2-4, 22-24, 32-34, etc., excluding teens)\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n if (lastDigit > 1n && lastDigit < 5n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {\n return forms[1]\n }\n\n return forms[2]\n }\n\n /**\n * Converts a whole number to Czech cardinal form.\n *\n * Algorithm (chunk-based decomposition):\n * 1. Split number into chunks of 3 digits (right-to-left): ones, thousands, millions, etc.\n * 2. For each non-zero chunk:\n * a. Extract hundreds digit (n3), tens digit (n2), ones digit (n1)\n * b. Add hundreds word (e.g., \"sto\", \"dvě stě\")\n * c. Add tens/ones (handles teens 10-19 separately from compound tens)\n * d. Add pluralized magnitude word (e.g., \"tisíce\", \"miliony\")\n * 3. Join all words with spaces\n *\n * Example: 1234 → chunks [1, 234] → \"jeden tisíc dvěstěčtyřicet\"\n * - Chunk 1 (index=1, thousands): \"jeden\" + \"tisíc\"\n * - Chunk 234 (index=0): \"dvě stě\" + \"třicet\" + \"čtyři\"\n *\n * Special case: When chunk=1 at thousands+ levels, omit the ones word to avoid\n * redundancy with the pluralized magnitude (e.g., just \"tisíc\" not \"jeden tisíc\").\n *\n * @param {bigint} number The whole number to convert.\n * @returns {string} The number expressed in Czech words.\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index--\n if (x === 0n) continue\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0n) {\n words.push(this.hundreds[n3])\n }\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n && !(index > 0 && x === 1n)) {\n words.push(this.ones[n1])\n }\n if (index > 0) {\n words.push(this.pluralize(x, this.thousands[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Czech cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {SlavicOptions} [options={}] Configuration options.\n * @returns {string} The number expressed in Czech words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Czech(options).convertToWords(value)\n}\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar aCallable = require('../internals/a-callable');\n\nmodule.exports = function (object, key, method) {\n try {\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n return uncurryThis(aCallable(Object.getOwnPropertyDescriptor(object, key)[method]));\n } catch (error) { /* empty */ }\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar V8_PROTOTYPE_DEFINE_BUG = require('../internals/v8-prototype-define-bug');\nvar definePropertyModule = require('../internals/object-define-property');\nvar anObject = require('../internals/an-object');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar objectKeys = require('../internals/object-keys');\n\n// `Object.defineProperties` method\n// https://tc39.es/ecma262/#sec-object.defineproperties\n// eslint-disable-next-line es/no-object-defineproperties -- safe\nexports.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var props = toIndexedObject(Properties);\n var keys = objectKeys(Properties);\n var length = keys.length;\n var index = 0;\n var key;\n while (length > index) definePropertyModule.f(O, key = keys[index++], props[key]);\n return O;\n};\n","'use strict';\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n","'use strict';\nvar $TypeError = TypeError;\nvar MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991\n\nmodule.exports = function (it) {\n if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded');\n return it;\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar definePropertyModule = require('../internals/object-define-property');\nvar makeBuiltIn = require('../internals/make-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Norwegian language converter.\n *\n * GreedyScaleLanguage with inline Norwegian merge rules:\n * - Hyphenation for compound numbers (e.g., \"tjueen\")\n * - \"og\" (and) for hundreds combinations\n * - Comma separation for non-magnitude additions\n * - Implicit '1' before tens and magnitudes\n * - Space separators for large numbers\n */\nexport class Norwegian extends GreedyScaleLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'komma'\n zeroWord = 'null'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000_000_000n, 'quintillard'],\n [1_000_000_000_000_000_000_000_000_000_000n, 'quintillion'],\n [1_000_000_000_000_000_000_000_000_000n, 'quadrillard'],\n [1_000_000_000_000_000_000_000_000n, 'quadrillion'],\n [1_000_000_000_000_000_000_000n, 'trillard'],\n [1_000_000_000_000_000_000n, 'trillion'],\n [1_000_000_000_000_000n, 'billard'],\n [1_000_000_000_000n, 'billion'],\n [1_000_000_000n, 'millard'],\n [1_000_000n, 'million'],\n [1000n, 'tusen'],\n [100n, 'hundre'],\n [90n, 'nitti'],\n [80n, 'åtti'],\n [70n, 'sytti'],\n [60n, 'seksti'],\n [50n, 'femti'],\n [40n, 'førti'],\n [30n, 'tretti'],\n [20n, 'tjue'],\n [19n, 'nitten'],\n [18n, 'atten'],\n [17n, 'sytten'],\n [16n, 'seksten'],\n [15n, 'femten'],\n [14n, 'fjorten'],\n [13n, 'tretten'],\n [12n, 'tolv'],\n [11n, 'elleve'],\n [10n, 'ti'],\n [9n, 'ni'],\n [8n, 'åtte'],\n [7n, 'syv'],\n [6n, 'seks'],\n [5n, 'fem'],\n [4n, 'fire'],\n [3n, 'tre'],\n [2n, 'to'],\n [1n, 'en'],\n [0n, 'null']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to Norwegian grammar rules.\n *\n * Norwegian-specific rules:\n * - Implicit \\\"en\\\": `mergeScales({ 'en': 1n }, { 'hundre': 100n })` → `{ 'hundre': 100n }`\n * - Hyphenation for compound tens: `mergeScales({ 'tjue': 20n }, { 'en': 1n })` → `{ 'tjue-en': 21n }`\n * - \\\"og\\\" (and) after hundreds: `mergeScales({ 'hundre': 100n }, { 'en': 1n })` → `{ 'hundre og en': 101n }`\n * - Space-separated for large numbers (thousands+)\n * - Comma separator for non-magnitude additions (e.g., \\\"tusen, en\\\")\n *\n * @param {Object} leftPair The left operand as `{ word: BigInt }`.\n * @param {Object} rightPair The right operand as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'en': 1n }, { 'hundre': 100n }); // { 'hundre': 100n }\n * mergeScales({ 'tjue': 20n }, { 'tre': 3n }); // { 'tjue-tre': 23n }\n */\n // Norwegian merge rules mirror the former Scandinavian base logic\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const leftNumber = Object.values(leftPair)[0]\n const rightNumber = Object.values(rightPair)[0]\n\n if (leftNumber === 1n && rightNumber < 100n) {\n return rightPair\n }\n\n if (leftNumber < 100n && leftNumber > rightNumber) {\n return { [`${leftWord}-${rightWord}`]: leftNumber + rightNumber }\n }\n\n if (leftNumber >= 100n && rightNumber < 100n) {\n return { [`${leftWord} og ${rightWord}`]: leftNumber + rightNumber }\n }\n\n if (rightNumber > leftNumber) {\n return { [`${leftWord} ${rightWord}`]: leftNumber * rightNumber }\n }\n\n return { [`${leftWord}, ${rightWord}`]: leftNumber + rightNumber }\n }\n}\n\n/**\n * Converts a number to Norwegian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Norwegian class options).\n * @returns {string} The number expressed in Norwegian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'førti-to'\n * convertToWords('1.5'); // 'en komma fem'\n */\nexport default function convertToWords (value, options = {}) {\n return new Norwegian(options).convertToWords(value)\n}\n","'use strict';\nvar TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar isCallable = require('../internals/is-callable');\nvar classofRaw = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n","'use strict';\nvar toPrimitive = require('../internals/to-primitive');\nvar isSymbol = require('../internals/is-symbol');\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n","'use strict';\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\n\nmodule.exports = NATIVE_SYMBOL &&\n !Symbol.sham &&\n typeof Symbol.iterator == 'symbol';\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar classof = require('../internals/classof-raw');\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) === 'String' ? split(it, '') : $Object(it);\n} : $Object;\n","'use strict';\nvar has = require('../internals/set-helpers').has;\n\n// Perform ? RequireInternalSlot(M, [[SetData]])\nmodule.exports = function (it) {\n has(it);\n return it;\n};\n","import AbstractLanguage from './abstract-language.js'\n\n/**\n * @typedef {string[]} SlavicPluralForms\n * Array of three plural forms for Slavic languages:\n * - [0]: Singular form (for numbers ending in 1, except 11)\n * - [1]: Few form (for numbers ending in 2-4, except 12-14)\n * - [2]: Many form (for all other numbers: 0, 5-20, and numbers ending in 0, 5-9, 11-19)\n */\n\n/**\n * @typedef {Object.<string, SlavicPluralForms>} SlavicThousandsMap\n * Mapping from power indices to their plural forms.\n * Example: { '0': ['тысяча', 'тысячи', 'тысяч'], '1': ['миллион', 'миллиона', 'миллионов'] }\n */\n\n/**\n * Base class for Slavic and related languages with complex pluralization.\n *\n * This class provides a reusable implementation for languages that share:\n * - Three-form pluralization (singular/few/many)\n * - Gender-aware number forms (masculine/feminine for 1, 2)\n * - Hundreds, tens, ones decomposition\n * - Chunk-based large number handling (thousands, millions, etc.)\n * - Inherits decimal handling from AbstractLanguage (supports both grouped and\n * per-digit modes via the `convertDecimalsPerDigit` class property).\n *\n * Used by: Russian, Czech, Polish, Ukrainian, Serbian, Croatian,\n * as well as Baltic (Lithuanian, Latvian) and Hebrew languages.\n *\n * Subclasses MUST define these properties with language-specific vocabulary:\n * - `ones` - Object mapping 1-9 to masculine forms\n * - `onesFeminine` - Object mapping 1-9 to feminine forms\n * - `tens` - Object mapping 0-9 to teen numbers (10-19)\n * - `twenties` - Object mapping 2-9 to tens (20-90)\n * - `hundreds` - Object mapping 1-9 to hundreds (100-900)\n * - `thousands` - Object mapping power indices to [singular, few, many] forms\n * - `feminine` - Boolean indicating if feminine forms should be used (optional)\n *\n * @abstract\n * @extends AbstractLanguage\n */\nclass SlavicLanguage extends AbstractLanguage {\n /**\n * Masculine forms for digits 1-9.\n *\n * @type {object}\n */\n ones = {}\n\n /**\n * Feminine forms for digits 1-9.\n *\n * @type {object}\n */\n onesFeminine = {}\n\n /**\n * Words for tens (10, 20, 30, etc.).\n *\n * @type {object}\n */\n tens = {}\n\n /**\n * Special forms for 21-29 in some languages.\n *\n * @type {object}\n */\n twenties = {}\n\n /**\n * Words for hundreds (100, 200, 300, etc.).\n *\n * @type {object}\n */\n hundreds = {}\n\n /**\n * Scale words for thousands, millions, etc.\n *\n * @type {object}\n */\n thousands = {}\n\n /**\n * Use feminine forms for numbers (affects 1-9).\n *\n * @type {boolean}\n */\n feminine\n\n /**\n * Initializes the Slavic language converter with language-specific options.\n *\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers (affects gender agreement).\n */\n constructor ({ feminine = false } = {}) {\n super()\n\n this.feminine = feminine\n }\n\n /**\n * Converts a whole number to its word representation.\n *\n * This method implements the Slavic number construction algorithm:\n * 1. Split number into 3-digit chunks (right to left)\n * 2. For each chunk: convert hundreds, tens, ones\n * 3. Apply gender rules for ones (feminine for thousands, or when feminine=true)\n * 4. Add pluralized power word (thousand/million/billion/etc.)\n * 5. Join all parts with spaces\n *\n * @param {bigint} number The whole number to convert (non-negative).\n * @returns {string} The number in words.\n */\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let chunkIndex = chunks.length\n\n for (const chunkValue of chunks) {\n chunkIndex = chunkIndex - 1\n\n if (chunkValue === 0n) {\n continue\n }\n\n const [onesDigit, tensDigit, hundredsDigit] = this.getDigits(chunkValue)\n\n if (hundredsDigit > 0n) {\n words.push(this.hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1n) {\n words.push(this.twenties[tensDigit])\n }\n\n // Handle teens (10-19) or ones (1-9)\n if (tensDigit === 1n) {\n // Teens: use tens array directly\n words.push(this.tens[onesDigit])\n } else if (onesDigit > 0n) {\n // Ones: use feminine form for thousands (chunkIndex 1) or when feminine=true (chunkIndex 0)\n const onesArray =\n chunkIndex === 1 || (this.feminine && chunkIndex === 0)\n ? this.onesFeminine\n : this.ones\n words.push(onesArray[onesDigit])\n }\n\n // Add power word (thousand, million, etc.) with proper pluralization\n if (chunkIndex > 0) {\n words.push(this.pluralize(chunkValue, this.thousands[chunkIndex]))\n }\n }\n\n return words.join(' ')\n }\n\n /**\n * Splits a number string into chunks of X digits.\n *\n * Example: splitByX('1234567', 3) => [1n, 234n, 567n]\n *\n * @param {string} numberString The number as a string.\n * @param {number} chunkSize Chunk size (typically 3 for thousands grouping).\n * @returns {bigint[]} Array of BigInt chunks.\n */\n splitByX (numberString, chunkSize) {\n const chunks = []\n const stringLength = numberString.length\n\n if (stringLength > chunkSize) {\n const remainderLength = stringLength % chunkSize\n\n if (remainderLength > 0) {\n chunks.push(BigInt(numberString.slice(0, remainderLength)))\n }\n\n for (let i = remainderLength; i < stringLength; i += chunkSize) {\n chunks.push(BigInt(numberString.slice(i, i + chunkSize)))\n }\n } else {\n chunks.push(BigInt(numberString))\n }\n\n return chunks\n }\n\n /**\n * Extracts individual digits from a number (units, tens, hundreds).\n *\n * Returns digits in reverse order: [ones, tens, hundreds]\n * Example: 456 => [6n, 5n, 4n]\n *\n * @param {bigint} value The number to extract digits from (0-999).\n * @returns {bigint[]} Array of [ones, tens, hundreds] as BigInts.\n */\n getDigits (value) {\n // Direct BigInt arithmetic is faster than string manipulation\n const onesPlace = value % 10n\n const tensPlace = (value / 10n) % 10n\n const hundredsPlace = value / 100n\n return [onesPlace, tensPlace, hundredsPlace]\n }\n\n /**\n * Selects the correct plural form based on Slavic pluralization rules.\n *\n * Slavic languages use three forms:\n * - Form 0 (singular): numbers ending in 1 (but not 11)\n * - Form 1 (few): numbers ending in 2-4 (but not 12-14)\n * - Form 2 (many): all other numbers (0, 5-20, 25-30, etc.)\n *\n * Examples (Russian):\n * - 1, 21, 31... => тысяча (form 0)\n * - 2-4, 22-24, 32-34... => тысячи (form 1)\n * - 0, 5-20, 25-30... => тысяч (form 2)\n *\n * @param {bigint} n The number to check.\n * @param {string[]} forms Array of [singular, few, many] forms.\n * @returns {string} The appropriate form for the number.\n */\n pluralize (number, pluralForms) {\n const remainder100 = number % 100n\n const remainder10 = number % 10n\n\n // Check if in 11-19 range (special case)\n if (remainder100 >= 10n && remainder100 <= 20n) {\n return pluralForms[2] // Always use \"many\" form for 11-20\n }\n\n if (remainder10 === 1n) {\n return pluralForms[0] // Singular\n }\n\n if (remainder10 >= 2n && remainder10 <= 4n) {\n return pluralForms[1] // Few (2-4)\n }\n\n return pluralForms[2] // Many\n }\n}\n\nexport default SlavicLanguage\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar call = require('../internals/function-call');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar hasOwn = require('../internals/has-own-property');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n","'use strict';\nvar classofRaw = require('../internals/classof-raw');\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = function (fn) {\n // Nashorn bug:\n // https://github.com/zloirock/core-js/issues/1128\n // https://github.com/zloirock/core-js/issues/1130\n if (classofRaw(fn) === 'Function') return uncurryThis(fn);\n};\n","'use strict';\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\n\n// https://tc39.es/ecma262/#sec-array.prototype.toreversed\n// https://tc39.es/ecma262/#sec-%typedarray%.prototype.toreversed\nmodule.exports = function (O, C) {\n var len = lengthOfArrayLike(O);\n var A = new C(len);\n var k = 0;\n for (; k < len; k++) A[k] = O[len - k - 1];\n return A;\n};\n","'use strict';\nvar IS_PURE = require('../internals/is-pure');\nvar globalThis = require('../internals/global-this');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nvar SHARED = '__core-js_shared__';\nvar store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {});\n\n(store.versions || (store.versions = [])).push({\n version: '3.47.0',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2025 Denis Pushkarev (zloirock.ru), 2025 CoreJS Company (core-js.io)',\n license: 'https://github.com/zloirock/core-js/blob/v3.47.0/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar difference = require('../internals/set-difference');\nvar fails = require('../internals/fails');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar SET_LIKE_INCORRECT_BEHAVIOR = !setMethodAcceptSetLike('difference', function (result) {\n return result.size === 0;\n});\n\nvar FORCED = SET_LIKE_INCORRECT_BEHAVIOR || fails(function () {\n // https://bugs.webkit.org/show_bug.cgi?id=288595\n var setLike = {\n size: 1,\n has: function () { return true; },\n keys: function () {\n var index = 0;\n return {\n next: function () {\n var done = index++ > 1;\n if (baseSet.has(1)) baseSet.clear();\n return { done: done, value: 2 };\n }\n };\n }\n };\n // eslint-disable-next-line es/no-set -- testing\n var baseSet = new Set([1, 2, 3, 4]);\n // eslint-disable-next-line es/no-set-prototype-difference -- testing\n return baseSet.difference(setLike).size !== 3;\n});\n\n// `Set.prototype.difference` method\n// https://tc39.es/ecma262/#sec-set.prototype.difference\n$({ target: 'Set', proto: true, real: true, forced: FORCED }, {\n difference: difference\n});\n","'use strict';\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\nvar isObject = require('../internals/is-object');\nvar create = require('../internals/object-create');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar IS_PURE = require('../internals/is-pure');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar BUGGY_SAFARI_ITERATORS = false;\n\n// `%IteratorPrototype%` object\n// https://tc39.es/ecma262/#sec-%iteratorprototype%-object\nvar IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;\n\n/* eslint-disable es/no-array-prototype-keys -- safe */\nif ([].keys) {\n arrayIterator = [].keys();\n // Safari 8 has buggy iterators w/o `next`\n if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;\n else {\n PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));\n if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;\n }\n}\n\nvar NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype) || fails(function () {\n var test = {};\n // FF44- legacy iterators case\n return IteratorPrototype[ITERATOR].call(test) !== test;\n});\n\nif (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {};\nelse if (IS_PURE) IteratorPrototype = create(IteratorPrototype);\n\n// `%IteratorPrototype%[@@iterator]()` method\n// https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator\nif (!isCallable(IteratorPrototype[ITERATOR])) {\n defineBuiltIn(IteratorPrototype, ITERATOR, function () {\n return this;\n });\n}\n\nmodule.exports = {\n IteratorPrototype: IteratorPrototype,\n BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS\n};\n","'use strict';\nvar hasOwn = require('../internals/has-own-property');\nvar ownKeys = require('../internals/own-keys');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n","'use strict';\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n};\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar isCallable = require('../internals/is-callable');\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method];\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * @typedef {Object} DanishOptions\n * @property {boolean} [ordFlag=false] Enable ordinal number conversion.\n */\n\n/**\n * Danish language converter.\n *\n * GreedyScaleLanguage with Danish-specific extensions:\n * - Unique vigesimal (base-20) number system for 50-90\n * - Special composition rules (\"og\" for \"and\" between units and tens)\n * - Reverse digit order (e.g., \"fem-og-tyve\" = five-and-twenty = 25)\n * - Support for ordinal numbers via ordFlag option\n *\n * Key Features:\n * - Vigesimal tens: halvtreds (50), treds (60), halvfjerds (70), firs (80), halvfems (90)\n * - Units-before-tens pattern (e.g., \"tre-og-tyve\" = 23)\n * - \"et\" prefix for hundreds/thousands (not \"en\")\n * - Optional ordinal number conversion via ordFlag option\n * - Inline merge logic tailored for Danish ordering\n */\nexport class Danish extends GreedyScaleLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'komma'\n zeroWord = 'nul'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'quadrillarder'],\n [1_000_000_000_000_000_000_000_000n, 'quadrillioner'],\n [1_000_000_000_000_000_000_000n, 'trillarder'],\n [1_000_000_000_000_000_000n, 'trillioner'],\n [1_000_000_000_000_000n, 'billarder'],\n [1_000_000_000_000n, 'billioner'],\n [1_000_000_000n, 'millarder'],\n [1_000_000n, 'millioner'],\n [1000n, 'tusind'],\n [100n, 'hundrede'],\n [90n, 'halvfems'],\n [80n, 'firs'],\n [70n, 'halvfjerds'],\n [60n, 'treds'],\n [50n, 'halvtreds'],\n [40n, 'fyrre'],\n [30n, 'tredive'],\n [20n, 'tyve'],\n [19n, 'nitten'],\n [18n, 'atten'],\n [17n, 'sytten'],\n [16n, 'seksten'],\n [15n, 'femten'],\n [14n, 'fjorten'],\n [13n, 'tretten'],\n [12n, 'tolv'],\n [11n, 'elleve'],\n [10n, 'ti'],\n [9n, 'ni'],\n [8n, 'otte'],\n [7n, 'syv'],\n [6n, 'seks'],\n [5n, 'fem'],\n [4n, 'fire'],\n [3n, 'tre'],\n [2n, 'to'],\n [1n, 'et'],\n [0n, 'nul']\n ]\n\n /**\n * Initializes the Danish converter with language-specific options.\n *\n * @param {DanishOptions} [options={}] Configuration options.\n */\n constructor ({ ordFlag = false } = {}) {\n super()\n\n this.ordFlag = ordFlag\n }\n\n /**\n * Merges two adjacent word-number pairs according to Danish grammar rules.\n * Danish uses complex vigesimal (base-20) patterns and reverse digit ordering.\n *\n * Key Danish patterns:\n * - Vigesimal tens: halvtreds(50), treds(60), halvfjerds(70), firs(80), halvfems(90)\n * - Units-before-tens order with \"og\" (and): \"tre-og-tyve\" (3 and 20 = 25)\n * - \"et\" prefix for hundreds/thousands (not \"en\")\n * - Space separators for large magnitudes (≥ millions)\n * - Ordinal support via this.ordFlag\n *\n * @param {Object} current The left operand as `{ word: bigint }`.\n * @param {Object} next The right operand as `{ word: bigint }`.\n * @returns {Object} Merged pair with combined word and resulting number (bigint).\n */\n mergeScales (current, next) {\n let cText = Object.keys(current)[0]\n let nText = Object.keys(next)[0]\n const cNumber = Object.values(current)[0] // BigInt (e.g., 1n, 100n, 1000n)\n const nNumber = Object.values(next)[0] // BigInt (e.g., magnitude level like 100n, 1000n)\n\n // Prepend \"et\" to hundreds and thousands (not \"en\") for proper Danish form\n if (nNumber === 100n || nNumber === 1000n) {\n next = { [`et${nText}`]: nNumber }\n }\n\n // Implicit '1' handling: omit '1' before most magnitudes (except millions/ordinals)\n if (cNumber === 1n) {\n if (nNumber < 1_000_000n || this.ordFlag) {\n return next // Just the magnitude word (e.g., \"hundrede\" not \"en hundrede\")\n }\n cText = 'en' // Explicit \"en\" (one) for millions and above\n }\n\n // Multiplication across magnitude boundaries\n if (nNumber > cNumber) {\n // Space for million+ (e.g., \"en million\", \"to millioner\")\n if (nNumber >= 1_000_000n) {\n cText += ' '\n }\n return { [`${cText}${nText}`]: cNumber * nNumber }\n }\n\n // Addition with separator rules:\n // \"og\" (and) for hundreds + smaller numbers\n if (cNumber >= 100n && cNumber < 1000n) {\n cText += ' og '\n } else if (cNumber >= 1000n && cNumber <= 100_000n) {\n // Special \"e og\" for thousands (e.g., \"tusinde og tyve\")\n cText += 'e og '\n }\n\n // Units-before-tens reversal (Danish vigesimal pattern):\n // For small units (< 10) with tens (10-99), swap order: \"tre og tyve\" (25)\n if (nNumber < 10n && cNumber > 10n && cNumber < 100n) {\n if (nNumber === 1n) {\n nText = 'en' // Convert 1 to \"en\" for vigesimal context\n }\n // Swap positions: units go after \"og\", tens go before\n const temporary = nText\n nText = cText\n cText = temporary + 'og'\n } else if (cNumber >= 1_000_000n) {\n // Space for large magnitudes (millions+)\n cText += ' '\n }\n\n return { [`${cText}${nText}`]: cNumber + nNumber }\n }\n}\n\n/**\n * Converts a number to Danish cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Danish class options).\n * @param {boolean} [options.ordFlag=false] Enable ordinal number conversion.\n * @returns {string} The number expressed in Danish words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(25); // 'femogtyve' (five-and-twenty)\n * convertToWords(50); // 'halvtreds' (half-third-times-twenty)\n */\nexport default function convertToWords (value, options = {}) {\n return new Danish(options).convertToWords(value)\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar intersection = require('../internals/set-intersection');\nvar setMethodAcceptSetLike = require('../internals/set-method-accept-set-like');\n\nvar INCORRECT = !setMethodAcceptSetLike('intersection', function (result) {\n return result.size === 2 && result.has(1) && result.has(2);\n}) || fails(function () {\n // eslint-disable-next-line es/no-array-from, es/no-set, es/no-set-prototype-intersection -- testing\n return String(Array.from(new Set([1, 2, 3]).intersection(new Set([3, 2])))) !== '3,2';\n});\n\n// `Set.prototype.intersection` method\n// https://tc39.es/ecma262/#sec-set.prototype.intersection\n$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, {\n intersection: intersection\n});\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar globalThis = require('../internals/global-this');\nvar anInstance = require('../internals/an-instance');\nvar anObject = require('../internals/an-object');\nvar isCallable = require('../internals/is-callable');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar defineBuiltInAccessor = require('../internals/define-built-in-accessor');\nvar createProperty = require('../internals/create-property');\nvar fails = require('../internals/fails');\nvar hasOwn = require('../internals/has-own-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar IteratorPrototype = require('../internals/iterators-core').IteratorPrototype;\nvar DESCRIPTORS = require('../internals/descriptors');\nvar IS_PURE = require('../internals/is-pure');\n\nvar CONSTRUCTOR = 'constructor';\nvar ITERATOR = 'Iterator';\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\n\nvar $TypeError = TypeError;\nvar NativeIterator = globalThis[ITERATOR];\n\n// FF56- have non-standard global helper `Iterator`\nvar FORCED = IS_PURE\n || !isCallable(NativeIterator)\n || NativeIterator.prototype !== IteratorPrototype\n // FF44- non-standard `Iterator` passes previous tests\n || !fails(function () { NativeIterator({}); });\n\nvar IteratorConstructor = function Iterator() {\n anInstance(this, IteratorPrototype);\n if (getPrototypeOf(this) === IteratorPrototype) throw new $TypeError('Abstract class Iterator not directly constructable');\n};\n\nvar defineIteratorPrototypeAccessor = function (key, value) {\n if (DESCRIPTORS) {\n defineBuiltInAccessor(IteratorPrototype, key, {\n configurable: true,\n get: function () {\n return value;\n },\n set: function (replacement) {\n anObject(this);\n if (this === IteratorPrototype) throw new $TypeError(\"You can't redefine this property\");\n if (hasOwn(this, key)) this[key] = replacement;\n else createProperty(this, key, replacement);\n }\n });\n } else IteratorPrototype[key] = value;\n};\n\nif (!hasOwn(IteratorPrototype, TO_STRING_TAG)) defineIteratorPrototypeAccessor(TO_STRING_TAG, ITERATOR);\n\nif (FORCED || !hasOwn(IteratorPrototype, CONSTRUCTOR) || IteratorPrototype[CONSTRUCTOR] === Object) {\n defineIteratorPrototypeAccessor(CONSTRUCTOR, IteratorConstructor);\n}\n\nIteratorConstructor.prototype = IteratorPrototype;\n\n// `Iterator` constructor\n// https://tc39.es/ecma262/#sec-iterator\n$({ global: true, constructor: true, forced: FORCED }, {\n Iterator: IteratorConstructor\n});\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar shared = require('../internals/shared');\nvar hasOwn = require('../internals/has-own-property');\nvar uid = require('../internals/uid');\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar Symbol = globalThis.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Korean language converter.\n *\n * Features:\n * - Space-separated for large numbers (>= 만/10,000)\n * - Concatenated for smaller numbers\n * - Omits '일' (1) before multipliers\n */\nexport class Korean extends GreedyScaleLanguage {\n negativeWord = '마이너스'\n decimalSeparatorWord = '점'\n zeroWord = '영'\n scaleWordPairs = [\n [10_000_000_000_000_000_000_000_000_000n, '양'],\n [1_000_000_000_000_000_000_000_000n, '자'],\n [100_000_000_000_000_000_000n, '해'],\n [10_000_000_000_000_000n, '경'],\n [1_000_000_000_000n, '조'],\n [100_000_000n, '억'],\n [10_000n, '만'],\n [1000n, '천'],\n [100n, '백'],\n [10n, '십'],\n [9n, '구'],\n [8n, '팔'],\n [7n, '칠'],\n [6n, '육'],\n [5n, '오'],\n [4n, '사'],\n [3n, '삼'],\n [2n, '이'],\n [1n, '일'],\n [0n, '영']\n ]\n\n /**\n * Merges two adjacent word-number pairs according to Korean grammar rules.\n *\n * Korean-specific rules:\n * - Omits '일' (1) before multipliers <= 만 (10,000)\n * - Concatenates without space for small numbers (< 만)\n * - Separates with space for large numbers (>= 만)\n * - Multiplies when right > left, adds when left > right\n *\n * @param {Object} leftPair The left operand as `{ word: number }`.\n * @param {Object} rightPair The right operand as `{ word: number }`.\n * @returns {Object} Merged pair with combined word and resulting number.\n */\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const leftNumber = Object.values(leftPair)[0] // BigInt\n const rightNumber = Object.values(rightPair)[0] // BigInt\n\n // Implicit \"일\": omit 1 before multipliers up to 만 (10,000)\n if (leftNumber === 1n && rightNumber <= 10_000n) return rightPair\n // Concatenate (no space) for small numbers less than 만\n if (leftNumber < 10_000n && leftNumber > rightNumber) return { [`${leftWord}${rightWord}`]: leftNumber + rightNumber }\n // Space-separate for large numbers (>= 만) when adding\n if (leftNumber >= 10_000n && leftNumber > rightNumber) return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }\n // Multiply for all scale combinations\n return { [`${leftWord}${rightWord}`]: leftNumber * rightNumber }\n }\n}\n\n/**\n * Converts a number to Korean cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Korean class options).\n * @returns {string} The number expressed in Korean words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // '사십이'\n * convertToWords(10001); // '만 일'\n */\nexport default function convertToWords (value, options = {}) {\n return new Korean(options).convertToWords(value)\n}\n","import AbstractLanguage from '../classes/abstract-language.js'\n\nclass Swahili extends AbstractLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'nukta'\n zeroWord = 'sifuri'\n digits = {\n 0: 'sifuri',\n 1: 'moja',\n 2: 'mbili',\n 3: 'tatu',\n 4: 'nne',\n 5: 'tano',\n 6: 'sita',\n 7: 'saba',\n 8: 'nane',\n 9: 'tisa'\n }\n\n tens = {\n 10: 'kumi',\n 20: 'ishirini',\n 30: 'thelathini',\n 40: 'arobaini',\n 50: 'hamsini',\n 60: 'sitini',\n 70: 'sabini',\n 80: 'themanini',\n 90: 'tisini'\n }\n\n scales = [\n '',\n 'elfu',\n 'milioni',\n 'bilioni',\n 'trilioni'\n ]\n\n wordsUnder100 (n) {\n if (n < 10) return this.digits[n]\n if (n === 10) return this.tens[10]\n if (n < 20) {\n // 11-19: 'kumi na <digit>'\n return this.tens[10] + ' na ' + this.digits[n - 10]\n }\n const tens = Math.trunc(n / 10) * 10\n const ones = n % 10\n if (ones === 0) return this.tens[tens]\n return this.tens[tens] + ' na ' + this.digits[ones]\n }\n\n wordsUnder1000 (n) {\n if (n < 100) return this.wordsUnder100(n)\n if (n === 100) return 'mia moja'\n const hundreds = Math.trunc(n / 100)\n const rest = n % 100\n const parts = []\n\n // Hundreds: 'mia <digit>'\n parts.push('mia ' + this.digits[hundreds])\n if (rest > 0) {\n if (rest < 10) {\n parts.push('na ' + this.digits[rest])\n } else {\n parts.push(this.wordsUnder100(rest))\n }\n }\n\n return parts.join(' ')\n }\n\n splitBy3 (number) {\n const s = number.toString()\n if (s.length <= 3) return [Number(s)]\n const groups = []\n const last3 = s.slice(-3)\n groups.unshift(Number(last3))\n let remaining = s.slice(0, -3)\n while (remaining.length > 0) {\n const group = remaining.slice(-3)\n groups.unshift(Number(group))\n remaining = remaining.slice(0, -3)\n }\n return groups\n }\n\n convertWholePart (number) {\n if (number === 0n) return this.zeroWord\n\n const groups = this.splitBy3(number)\n const parts = []\n\n for (let i = 0; i < groups.length; i++) {\n const val = groups[i]\n if (val === 0) continue\n const scaleIndex = groups.length - i - 1\n // scale word\n if (scaleIndex === 0) {\n if (val < 10 && parts.length > 0) {\n parts.push('na ' + this.digits[val])\n } else if (val === 100 && parts.length > 0) {\n // In compound numbers (e.g., 1100 -> 'elfu moja mia'), use 'mia' not 'mia moja'\n parts.push('mia')\n } else {\n parts.push(this.wordsUnder1000(val))\n }\n } else {\n // e.g., 'elfu moja', 'milioni mbili'\n const unit = (val === 1) ? 'moja' : this.wordsUnder1000(val)\n parts.push(this.scales[scaleIndex] + ' ' + unit)\n }\n }\n\n return parts.join(' ').trim()\n }\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Swahili(options).convertToWords(value)\n}\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar iterateSimple = require('../internals/iterate-simple');\nvar SetHelpers = require('../internals/set-helpers');\n\nvar Set = SetHelpers.Set;\nvar SetPrototype = SetHelpers.proto;\nvar forEach = uncurryThis(SetPrototype.forEach);\nvar keys = uncurryThis(SetPrototype.keys);\nvar next = keys(new Set()).next;\n\nmodule.exports = function (set, fn, interruptible) {\n return interruptible ? iterateSimple({ iterator: keys(set), next: next }, fn) : forEach(set, fn);\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar has = require('../internals/set-helpers').has;\nvar size = require('../internals/set-size');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSimple = require('../internals/iterate-simple');\nvar iteratorClose = require('../internals/iterator-close');\n\n// `Set.prototype.isSupersetOf` method\n// https://tc39.es/ecma262/#sec-set.prototype.issupersetof\nmodule.exports = function isSupersetOf(other) {\n var O = aSet(this);\n var otherRec = getSetRecord(other);\n if (size(O) < otherRec.size) return false;\n var iterator = otherRec.getIterator();\n return iterateSimple(iterator, function (e) {\n if (!has(O, e)) return iteratorClose(iterator, 'normal', false);\n }) !== false;\n};\n","'use strict';\nvar isObject = require('../internals/is-object');\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + ' is not an object');\n};\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar isCallable = require('../internals/is-callable');\n\nvar WeakMap = globalThis.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * @typedef {Object} SpanishOptions\n * @property {string} [genderStem='o'] Masculine 'o' or feminine 'a' ending.\n */\n\n/**\n * Spanish language converter.\n *\n * Handles Spanish grammatical features:\n * - Gender agreement for numbers (masculine by default, feminine via `genderStem`)\n * - \"y\" (and) between tens and units (e.g., \"veinte y uno\")\n * - Special forms for hundreds (e.g., \"cien\", \"ciento\", \"doscientos\")\n * - Million pluralization\n */\nexport class Spanish extends GreedyScaleLanguage {\n negativeWord = 'menos'\n decimalSeparatorWord = 'punto'\n zeroWord = 'cero'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000n, 'cuatrillón'],\n [1_000_000_000_000_000_000n, 'trillón'],\n [1_000_000_000_000n, 'billón'],\n [1_000_000n, 'millón'],\n [1000n, 'mil'],\n [100n, 'cien'],\n [90n, 'noventa'],\n [80n, 'ochenta'],\n [70n, 'setenta'],\n [60n, 'sesenta'],\n [50n, 'cincuenta'],\n [40n, 'cuarenta'],\n [30n, 'treinta'],\n [29n, 'veintinueve'],\n [28n, 'veintiocho'],\n [27n, 'veintisiete'],\n [26n, 'veintiséis'],\n [25n, 'veinticinco'],\n [24n, 'veinticuatro'],\n [23n, 'veintitrés'],\n [22n, 'veintidós'],\n [21n, 'veintiuno'],\n [20n, 'veinte'],\n [19n, 'diecinueve'],\n [18n, 'dieciocho'],\n [17n, 'diecisiete'],\n [16n, 'dieciseis'],\n [15n, 'quince'],\n [14n, 'catorce'],\n [13n, 'trece'],\n [12n, 'doce'],\n [11n, 'once'],\n [10n, 'diez'],\n [9n, 'nueve'],\n [8n, 'ocho'],\n [7n, 'siete'],\n [6n, 'seis'],\n [5n, 'cinco'],\n [4n, 'cuatro'],\n [3n, 'tres'],\n [2n, 'dos'],\n [1n, 'uno'],\n [0n, 'cero']\n ]\n\n /**\n * Initializes the Spanish converter.\n *\n * @param {SpanishOptions} [options={}] Configuration options.\n */\n constructor ({ genderStem = 'o' } = {}) {\n super()\n\n this.genderStem = genderStem\n }\n\n /**\n * Merges two adjacent word-number pairs according to Spanish grammar rules.\n *\n * Spanish-specific rules:\n * - Implicit \"uno\": `mergeScales({ 'uno': 1n }, { 'mil': 1000n })` → `{ 'mil': 1000n }`\n * - \"y\" (and) between tens and units: `mergeScales({ 'veinte': 20n }, { 'uno': 1n })` → `{ 'veinte y uno': 21n }`\n * - Gender agreement for hundreds: \"cien\" + suffix based on genderStem\n * - Special forms for hundreds (cien/ciento/quinientos/setecientos/novecientos)\n * - Million pluralization when coefficient > 1: \"millones\" instead of \"millón\"\n *\n * @param {Object} currentPair The left operand as `{ word: BigInt }`.\n * @param {Object} nextPair The right operand as `{ word: BigInt }`.\n * @returns {Object} Merged pair with combined word and resulting numeric value.\n *\n * @example\n * mergeScales({ 'uno': 1n }, { 'mil': 1000n }); // { 'mil': 1000n }\n * mergeScales({ 'veinte': 20n }, { 'tres': 3n }); // { 'veinte y tres': 23n }\n */\n mergeScales (currentPair, nextPair) {\n let currentWord = Object.keys(currentPair)[0]\n let nextWord = Object.keys(nextPair)[0]\n const currentNumber = Object.values(currentPair)[0]\n const nextNumber = Object.values(nextPair)[0]\n\n if (currentNumber === 1n) {\n if (nextNumber < 1_000_000n) return nextPair\n currentWord = 'un'\n } else if (currentNumber === 100n && nextNumber % 1000n !== 0n) {\n currentWord += 't' + this.genderStem\n }\n\n if (nextNumber < currentNumber) {\n if (currentNumber < 100n) {\n return { [`${currentWord} y ${nextWord}`]: currentNumber + nextNumber }\n }\n return { [`${currentWord} ${nextWord}`]: currentNumber + nextNumber }\n }\n\n if (nextNumber % 1_000_000n === 0n && currentNumber > 1n) {\n nextWord = nextWord.slice(0, -3) + 'lones'\n }\n\n if (nextNumber === 100n) {\n if (currentNumber === 5n) {\n currentWord = 'quinien'\n nextWord = ''\n } else if (currentNumber === 7n) {\n currentWord = 'sete'\n } else if (currentNumber === 9n) {\n currentWord = 'nove'\n }\n nextWord += 't' + this.genderStem + 's'\n } else {\n nextWord = ' ' + nextWord\n }\n\n return { [`${currentWord}${nextWord}`]: currentNumber * nextNumber }\n }\n}\n\n/**\n * Converts a number to Spanish cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see ES class).\n * @returns {string} The number expressed in Spanish words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42, { lang: 'es' }); // 'cuarenta y dos'\n * convertToWords(100, { lang: 'es' }); // 'cien'\n */\nexport default function convertToWords (value, options = {}) {\n return new Spanish(options).convertToWords(value)\n}\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype !== 42;\n});\n","'use strict';\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","'use strict';\nvar aSet = require('../internals/a-set');\nvar SetHelpers = require('../internals/set-helpers');\nvar size = require('../internals/set-size');\nvar getSetRecord = require('../internals/get-set-record');\nvar iterateSet = require('../internals/set-iterate');\nvar iterateSimple = require('../internals/iterate-simple');\n\nvar Set = SetHelpers.Set;\nvar add = SetHelpers.add;\nvar has = SetHelpers.has;\n\n// `Set.prototype.intersection` method\n// https://tc39.es/ecma262/#sec-set.prototype.intersection\nmodule.exports = function intersection(other) {\n var O = aSet(this);\n var otherRec = getSetRecord(other);\n var result = new Set();\n\n if (size(O) > otherRec.size) {\n iterateSimple(otherRec.getIterator(), function (e) {\n if (has(O, e)) add(result, e);\n });\n } else {\n iterateSet(O, function (e) {\n if (otherRec.includes(e)) add(result, e);\n });\n }\n\n return result;\n};\n","'use strict';\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n","'use strict';\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n","'use strict';\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n","'use strict';\nvar SetHelpers = require('../internals/set-helpers');\nvar iterate = require('../internals/set-iterate');\n\nvar Set = SetHelpers.Set;\nvar add = SetHelpers.add;\n\nmodule.exports = function (set) {\n var result = new Set();\n iterate(set, function (it) {\n add(result, it);\n });\n return result;\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toObject = require('../internals/to-object');\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + ' is not a function');\n};\n","/**\n * Converts numbers to their word representation in Kannada (ಕನ್ನಡ).\n * @module languages/kn\n */\n\nimport SouthAsianLanguage from '../classes/south-asian-language.js'\n\n/**\n * Kannada language implementation using Indian-style number grouping.\n * @extends SouthAsianLanguage\n */\nclass KannadaLanguage extends SouthAsianLanguage {\n negativeWord = 'ಋಣಾತ್ಮಕ'\n decimalSeparatorWord = 'ದಶಮಾಂಶ'\n zeroWord = 'ಸೊನ್ನೆ'\n hundredWord = 'ನೂರು'\n convertDecimalsPerDigit = true\n\n /**\n * Array of number words from 0 to 99.\n * Index matches the number value.\n * @type {string[]}\n */\n belowHundred = [\n 'ಸೊನ್ನೆ', 'ಒಂದು', 'ಎರಡು', 'ಮೂರು', 'ನಾಲ್ಕು', 'ಐದು', 'ಆರು', 'ಏಳು', 'ಎಂಟು', 'ಒಂಬತ್ತು',\n 'ಹತ್ತು', 'ಹನ್ನೊಂದು', 'ಹನ್ನೆರಡು', 'ಹದಿಮೂರು', 'ಹದಿನಾಲ್ಕು', 'ಹದಿನೈದು', 'ಹದಿನಾರು', 'ಹದಿನೇಳು', 'ಹದಿನೆಂಟು', 'ಹತ್ತೊಂಬತ್ತು',\n 'ಇಪ್ಪತ್ತು', 'ಇಪ್ಪತ್ತೊಂದು', 'ಇಪ್ಪತ್ತೆರಡು', 'ಇಪ್ಪತ್ತಮೂರು', 'ಇಪ್ಪತ್ತನಾಲ್ಕು', 'ಇಪ್ಪತ್ತೈದು', 'ಇಪ್ಪತ್ತಾರು', 'ಇಪ್ಪತ್ತೇಳು', 'ಇಪ್ಪತ್ತೆಂಟು', 'ಇಪ್ಪತ್ತೊಂಬತ್ತು',\n 'ಮೂವತ್ತು', 'ಮೂವತ್ತೊಂದು', 'ಮೂವತ್ತೆರಡು', 'ಮೂವತ್ತಮೂರು', 'ಮೂವತ್ತನಾಲ್ಕು', 'ಮೂವತ್ತೈದು', 'ಮೂವತ್ತಾರು', 'ಮೂವತ್ತೇಳು', 'ಮೂವತ್ತೆಂಟು', 'ಮೂವತ್ತೊಂಬತ್ತು',\n 'ನಲವತ್ತು', 'ನಲವತ್ತೊಂದು', 'ನಲವತ್ತೆರಡು', 'ನಲವತ್ತಮೂರು', 'ನಲವತ್ತನಾಲ್ಕು', 'ನಲವತ್ತೈದು', 'ನಲವತ್ತಾರು', 'ನಲವತ್ತೇಳು', 'ನಲವತ್ತೆಂಟು', 'ನಲವತ್ತೊಂಬತ್ತು',\n 'ಐವತ್ತು', 'ಐವತ್ತೊಂದು', 'ಐವತ್ತೆರಡು', 'ಐವತ್ತಮೂರು', 'ಐವತ್ತನಾಲ್ಕು', 'ಐವತ್ತೈದು', 'ಐವತ್ತಾರು', 'ಐವತ್ತೇಳು', 'ಐವತ್ತೆಂಟು', 'ಐವತ್ತೊಂಬತ್ತು',\n 'ಅರವತ್ತು', 'ಅರವತ್ತೊಂದು', 'ಅರವತ್ತೆರಡು', 'ಅರವತ್ತಮೂರು', 'ಅರವತ್ತನಾಲ್ಕು', 'ಅರವತ್ತೈದು', 'ಅರವತ್ತಾರು', 'ಅರವತ್ತೇಳು', 'ಅರವತ್ತೆಂಟು', 'ಅರವತ್ತೊಂಬತ್ತು',\n 'ಎಪ್ಪತ್ತು', 'ಎಪ್ಪತ್ತೊಂದು', 'ಎಪ್ಪತ್ತೆರಡು', 'ಎಪ್ಪತ್ತಮೂರು', 'ಎಪ್ಪತ್ತನಾಲ್ಕು', 'ಎಪ್ಪತ್ತೈದು', 'ಎಪ್ಪತ್ತಾರು', 'ಎಪ್ಪತ್ತೇಳು', 'ಎಪ್ಪತ್ತೆಂಟು', 'ಎಪ್ಪತ್ತೊಂಬತ್ತು',\n 'ಎಂಬತ್ತು', 'ಎಂಬತ್ತೊಂದು', 'ಎಂಬತ್ತೆರಡು', 'ಎಂಬತ್ತಮೂರು', 'ಎಂಬತ್ತನಾಲ್ಕು', 'ಎಂಬತ್ತೈದು', 'ಎಂಬತ್ತಾರು', 'ಎಂಬತ್ತೇಳು', 'ಎಂಬತ್ತೆಂಟು', 'ಎಂಬತ್ತೊಂಬತ್ತು',\n 'ತೊಂಬತ್ತು', 'ತೊಂಬತ್ತೊಂದು', 'ತೊಂಬತ್ತೆರಡು', 'ತೊಂಬತ್ತಮೂರು', 'ತೊಂಬತ್ತನಾಲ್ಕು', 'ತೊಂಬತ್ತೈದು', 'ತೊಂಬತ್ತಾರು', 'ತೊಂಬತ್ತೇಳು', 'ತೊಂಬತ್ತೆಂಟು', 'ತೊಂಬತ್ತೊಂಬತ್ತು'\n ]\n\n /**\n * Scale words for powers of ten in Indian numbering system.\n * Index 0 = units, 1 = thousand, 2 = lakh, 3 = crore, etc.\n * @type {string[]}\n */\n scaleWords = [\n '', // units\n 'ಸಾವಿರ', // thousand (1,000)\n 'ಲಕ್ಷ', // lakh (100,000)\n 'ಕೋಟಿ', // crore (10,000,000)\n 'ಅಬ್ಜ', // arab (1,000,000,000)\n 'ಖರ್ವ', // kharab (100,000,000,000)\n 'ನೀಲ', // neel (10,000,000,000,000)\n 'ಪದ್ಮ', // padma (1,000,000,000,000,000)\n 'ಶಂಖ' // shankh (100,000,000,000,000,000)\n ]\n\n /**\n * Converts numbers using the belowHundred array directly.\n */\n}\n\n/**\n * Converts a number to its word representation in Kannada.\n * @param {number|string|bigint} value - The number to convert\n * @param {Object} [options={}] - Conversion options\n * @returns {string} The word representation of the number\n * @example\n * convertToWords(42) // 'ನಲವತ್ತೆರಡು'\n * convertToWords(1000) // 'ಒಂದು ಸಾವಿರ'\n * convertToWords(100000) // 'ಒಂದು ಲಕ್ಷ'\n */\nexport default function convertToWords (value, options = {}) {\n return new KannadaLanguage(options).convertToWords(value)\n}\n","import SlavicLanguage from '../classes/slavic-language.js'\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] Use feminine forms for numbers.\n */\n\n/**\n * Lithuanian language converter.\n *\n * Implements Lithuanian number words using the Slavic language pattern:\n * - Lithuanian number words (vienas/viena, du/dvi, trys, keturi...)\n * - Gender-aware forms (masculine/feminine)\n * - Baltic three-form pluralization (tūkstantis/tūkstančiai/tūkstančių)\n * - Lithuanian-specific declension patterns\n *\n * Key Features:\n * - Three-form pluralization system shared across Slavic/Baltic languages\n * * Form 1 (singular): 1 (e.g., \"tūkstantis\")\n * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., \"tūkstančiai\")\n * * Form 3 (many): all other numbers (e.g., \"tūkstančių\")\n * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)\n * - Large number handling via thousands[] array with indexed [singular, few, many] forms\n * - Gender-specific number forms for 1 and 2 (masculine/feminine dual forms)\n *\n * Features:\n * - Dual gender forms (vienas/viena, du/dvi, keturi/keturios)\n * - Complex declension patterns for large numbers\n * - Baltic language characteristics\n *\n * Inherits from SlavicLanguage as Lithuanian uses similar pluralization.\n */\nexport class Lithuanian extends SlavicLanguage {\n negativeWord = 'minus'\n decimalSeparatorWord = 'kablelis'\n zeroWord = 'nulis'\n ones = {\n 1: 'vienas',\n 2: 'du',\n 3: 'trys',\n 4: 'keturi',\n 5: 'penki',\n 6: 'šeši',\n 7: 'septyni',\n 8: 'aštuoni',\n 9: 'devyni'\n }\n\n onesFeminine = {\n 1: 'viena',\n 2: 'dvi',\n 3: 'trys',\n 4: 'keturios',\n 5: 'penkios',\n 6: 'šešios',\n 7: 'septynios',\n 8: 'aštuonios',\n 9: 'devynios'\n }\n\n tens = {\n 0: 'dešimt',\n 1: 'vienuolika',\n 2: 'dvylika',\n 3: 'trylika',\n 4: 'keturiolika',\n 5: 'penkiolika',\n 6: 'šešiolika',\n 7: 'septyniolika',\n 8: 'aštuoniolika',\n 9: 'devyniolika'\n }\n\n twenties = {\n 2: 'dvidešimt',\n 3: 'trisdešimt',\n 4: 'keturiasdešimt',\n 5: 'penkiasdešimt',\n 6: 'šešiasdešimt',\n 7: 'septyniasdešimt',\n 8: 'aštuoniasdešimt',\n 9: 'devyniasdešimt'\n }\n\n hundreds = ['šimtas', 'šimtai']\n\n thousands = {\n 1: ['tūkstantis', 'tūkstančiai', 'tūkstančių'],\n 2: ['milijonas', 'milijonai', 'milijonų'],\n 3: ['milijardas', 'milijardai', 'milijardų'],\n 4: ['trilijonas', 'trilijonai', 'trilijonų'],\n 5: ['kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'],\n 6: ['kvintilijonas', 'kvintilijonai', 'kvintilijonų'],\n 7: ['sikstilijonas', 'sikstilijonai', 'sikstilijonų'],\n 8: ['septilijonas', 'septilijonai', 'septilijonų'],\n 9: ['oktilijonas', 'oktilijonai', 'oktilijonų'],\n 10: ['naintilijonas', 'naintilijonai', 'naintilijonų']\n }\n\n pluralize (n, forms) {\n if (n === 0n) {\n return forms[2]\n }\n\n const [n1, n2] = this.getDigits(n)\n\n if (n2 === 1n || n1 === 0n) {\n return forms[2]\n }\n\n if (n1 === 1n) {\n return forms[0]\n }\n\n return forms[1]\n }\n\n convertWholePart (number) {\n if (number === 0n) {\n return this.zeroWord\n }\n const words = []\n const chunks = this.splitByX(number.toString(), 3)\n let index = chunks.length\n for (const x of chunks) {\n index = index - 1\n if (x === 0n) {\n continue\n }\n const [n1, n2, n3] = this.getDigits(x)\n if (n3 > 0n) {\n words.push(this.ones[n3])\n if (n3 > 1n) {\n words.push(this.hundreds[1])\n } else {\n words.push(this.hundreds[0])\n }\n }\n if (n2 > 1n) {\n words.push(this.twenties[n2])\n }\n if (n2 === 1n) {\n words.push(this.tens[n1])\n } else if (n1 > 0n) {\n if ((index === 1 || (this.feminine && index === 0)) && number < 1000n) {\n words.push(this.onesFeminine[n1])\n } else {\n words.push(this.ones[n1])\n }\n }\n if (index > 0) {\n words.push(this.pluralize(x, this.thousands[index]))\n }\n }\n return words.join(' ')\n }\n}\n\n/**\n * Converts a number to Lithuanian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options={}] Configuration options.\n * @param {boolean} [options.feminine=false] Use feminine forms for numbers.\n * @returns {string} The number expressed in Lithuanian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n */\nexport default function convertToWords (value, options = {}) {\n return new Lithuanian(options).convertToWords(value)\n}\n","'use strict';\nvar globalThis = require('../internals/global-this');\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(globalThis, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n globalThis[key] = value;\n } return value;\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar create = require('../internals/object-create');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar defineBuiltIns = require('../internals/define-built-ins');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar InternalStateModule = require('../internals/internal-state');\nvar getMethod = require('../internals/get-method');\nvar IteratorPrototype = require('../internals/iterators-core').IteratorPrototype;\nvar createIterResultObject = require('../internals/create-iter-result-object');\nvar iteratorClose = require('../internals/iterator-close');\nvar iteratorCloseAll = require('../internals/iterator-close-all');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar ITERATOR_HELPER = 'IteratorHelper';\nvar WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator';\nvar NORMAL = 'normal';\nvar THROW = 'throw';\nvar setInternalState = InternalStateModule.set;\n\nvar createIteratorProxyPrototype = function (IS_ITERATOR) {\n var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER);\n\n return defineBuiltIns(create(IteratorPrototype), {\n next: function next() {\n var state = getInternalState(this);\n // for simplification:\n // for `%WrapForValidIteratorPrototype%.next` or with `state.returnHandlerResult` our `nextHandler` returns `IterResultObject`\n // for `%IteratorHelperPrototype%.next` - just a value\n if (IS_ITERATOR) return state.nextHandler();\n if (state.done) return createIterResultObject(undefined, true);\n try {\n var result = state.nextHandler();\n return state.returnHandlerResult ? result : createIterResultObject(result, state.done);\n } catch (error) {\n state.done = true;\n throw error;\n }\n },\n 'return': function () {\n var state = getInternalState(this);\n var iterator = state.iterator;\n state.done = true;\n if (IS_ITERATOR) {\n var returnMethod = getMethod(iterator, 'return');\n return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true);\n }\n if (state.inner) try {\n iteratorClose(state.inner.iterator, NORMAL);\n } catch (error) {\n return iteratorClose(iterator, THROW, error);\n }\n if (state.openIters) try {\n iteratorCloseAll(state.openIters, NORMAL);\n } catch (error) {\n return iteratorClose(iterator, THROW, error);\n }\n if (iterator) iteratorClose(iterator, NORMAL);\n return createIterResultObject(undefined, true);\n }\n });\n};\n\nvar WrapForValidIteratorPrototype = createIteratorProxyPrototype(true);\nvar IteratorHelperPrototype = createIteratorProxyPrototype(false);\n\ncreateNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper');\n\nmodule.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) {\n var IteratorProxy = function Iterator(record, state) {\n if (state) {\n state.iterator = record.iterator;\n state.next = record.next;\n } else state = record;\n state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER;\n state.returnHandlerResult = !!RETURN_HANDLER_RESULT;\n state.nextHandler = nextHandler;\n state.counter = 0;\n state.done = false;\n setInternalState(this, state);\n };\n\n IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype;\n\n return IteratorProxy;\n};\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\n// eslint-disable-next-line es/no-function-prototype-bind -- safe\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n","'use strict';\nvar globalThis = require('../internals/global-this');\nvar userAgent = require('../internals/environment-user-agent');\n\nvar process = globalThis.process;\nvar Deno = globalThis.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n","'use strict';\nvar call = require('../internals/function-call');\nvar anObject = require('../internals/an-object');\nvar getMethod = require('../internals/get-method');\n\nmodule.exports = function (iterator, kind, value) {\n var innerResult, innerError;\n anObject(iterator);\n try {\n innerResult = getMethod(iterator, 'return');\n if (!innerResult) {\n if (kind === 'throw') throw value;\n return value;\n }\n innerResult = call(innerResult, iterator);\n } catch (error) {\n innerError = true;\n innerResult = error;\n }\n if (kind === 'throw') throw value;\n if (innerError) throw innerResult;\n anObject(innerResult);\n return value;\n};\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar call = Function.prototype.call;\n// eslint-disable-next-line es/no-function-prototype-bind -- safe\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n if (length === 0) return !IS_INCLUDES && -1;\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar arrayToReversed = require('../internals/array-to-reversed');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar addToUnscopables = require('../internals/add-to-unscopables');\n\nvar $Array = Array;\n\n// `Array.prototype.toReversed` method\n// https://tc39.es/ecma262/#sec-array.prototype.toreversed\n$({ target: 'Array', proto: true }, {\n toReversed: function toReversed() {\n return arrayToReversed(toIndexedObject(this), $Array);\n }\n});\n\naddToUnscopables('toReversed');\n","import AbstractLanguage from '../classes/abstract-language.js'\n\nclass Tamil extends AbstractLanguage {\n negativeWord = 'மைனஸ்'\n decimalSeparatorWord = 'புள்ளி'\n zeroWord = 'பூஜ்ஜியம்'\n convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion\n belowHundred = [\n 'பூஜ்ஜியம்',\n 'ஒன்று',\n 'இரண்டு',\n 'மூன்று',\n 'நான்கு',\n 'ஐந்து',\n 'ஆறு',\n 'ஏழு',\n 'எட்டு',\n 'ஒன்பது',\n 'பத்து',\n 'பதினொன்று',\n 'பன்னிரண்டு',\n 'பதிமூன்று',\n 'பதினான்கு',\n 'பதினைந்து',\n 'பதினாறு',\n 'பதினேழு',\n 'பதினெட்டு',\n 'பத்தொன்பது',\n 'இருபது',\n 'இருபத்தொன்று',\n 'இருபத்திரண்டு',\n 'இருபத்திமூன்று',\n 'இருபத்திநான்கு',\n 'இருபத்தைந்து',\n 'இருபத்தாறு',\n 'இருபத்தேழு',\n 'இருபத்தெட்டு',\n 'இருபத்தொன்பது',\n 'முப்பது',\n 'முப்பத்தொன்று',\n 'முப்பத்திரண்டு',\n 'முப்பத்திமூன்று',\n 'முப்பத்திநான்கு',\n 'முப்பத்தைந்து',\n 'முப்பத்தாறு',\n 'முப்பத்தேழு',\n 'முப்பத்தெட்டு',\n 'முப்பத்தொன்பது',\n 'நாற்பது',\n 'நாற்பத்தொன்று',\n 'நாற்பத்திரண்டு',\n 'நாற்பத்திமூன்று',\n 'நாற்பத்திநான்கு',\n 'நாற்பத்தைந்து',\n 'நாற்பத்தாறு',\n 'நாற்பத்தேழு',\n 'நாற்பத்தெட்டு',\n 'நாற்பத்தொன்பது',\n 'ஐம்பது',\n 'ஐம்பத்தொன்று',\n 'ஐம்பத்திரண்டு',\n 'ஐம்பத்திமூன்று',\n 'ஐம்பத்திநான்கு',\n 'ஐம்பத்தைந்து',\n 'ஐம்பத்தாறு',\n 'ஐம்பத்தேழு',\n 'ஐம்பத்தெட்டு',\n 'ஐம்பத்தொன்பது',\n 'அறுபது',\n 'அறுபத்தொன்று',\n 'அறுபத்திரண்டு',\n 'அறுபத்திமூன்று',\n 'அறுபத்திநான்கு',\n 'அறுபத்தைந்து',\n 'அறுபத்தாறு',\n 'அறுபத்தேழு',\n 'அறுபத்தெட்டு',\n 'அறுபத்தொன்பது',\n 'எழுபது',\n 'எழுபத்தொன்று',\n 'எழுபத்திரண்டு',\n 'எழுபத்திமூன்று',\n 'எழுபத்திநான்கு',\n 'எழுபத்தைந்து',\n 'எழுபத்தாறு',\n 'எழுபத்தேழு',\n 'எழுபத்தெட்டு',\n 'எழுபத்தொன்பது',\n 'எண்பது',\n 'எண்பத்தொன்று',\n 'எண்பத்திரண்டு',\n 'எண்பத்திமூன்று',\n 'எண்பத்திநான்கு',\n 'எண்பத்தைந்து',\n 'எண்பத்தாறு',\n 'எண்பத்தேழு',\n 'எண்பத்தெட்டு',\n 'எண்பத்தொன்பது',\n 'தொண்ணூறு',\n 'தொண்ணூற்று ஒன்று',\n 'தொண்ணூற்று இரண்டு',\n 'தொண்ணூற்று மூன்று',\n 'தொண்ணூற்று நான்கு',\n 'தொண்ணூற்று ஐந்து',\n 'தொண்ணூற்று ஆறு',\n 'தொண்ணூற்று ஏழு',\n 'தொண்ணூற்று எட்டு',\n 'தொண்ணூற்று ஒன்பது'\n ]\n\n hundreds = [\n '',\n 'நூறு',\n 'இருநூறு',\n 'முன்னூறு',\n 'நானூறு',\n 'ஐநூறு',\n 'அறுநூறு',\n 'எழுநூறு',\n 'எண்நூறு',\n 'தொள்ளாயிரம்'\n ]\n\n // Digits map 1–9 for decimal reading\n digits = [\n 'ஒன்று',\n 'இரண்டு',\n 'மூன்று',\n 'நான்கு',\n 'ஐந்து',\n 'ஆறு',\n 'ஏழு',\n 'எட்டு',\n 'ஒன்பது'\n ]\n\n scales = [\n '',\n 'ஆயிரம்',\n 'லட்சம்',\n 'கோடி',\n 'அரபு',\n 'கராபு',\n 'நீல்',\n 'பத்ம',\n 'சங்கு'\n ]\n\n /**\n * Convert numbers below 100 to Tamil words.\n *\n * @param {number} number The number to convert (0-99).\n * @returns {string} The Tamil representation.\n */\n convertBelowHundred (number) {\n return this.belowHundred[number]\n }\n\n convertBelowThousand (number) {\n if (number === 0) return ''\n if (number < 100) return this.convertBelowHundred(number)\n\n const hundreds = Math.trunc(number / 100)\n const remainder = number % 100\n let hundredPart = this.hundreds[hundreds]\n\n if (remainder > 0) {\n if (hundredPart.endsWith('ம்')) {\n hundredPart = hundredPart.replace(/ம்$/, 'த்து')\n } else if (hundredPart.endsWith('று')) {\n hundredPart = hundredPart.slice(0, -2) + 'ற்று'\n }\n }\n\n const parts = [hundredPart]\n if (remainder > 0) {\n parts.push(this.convertBelowHundred(remainder))\n }\n\n return parts.join(' ').trim()\n }\n\n splitIndian (number) {\n const numStr = number.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const groups = []\n const last3 = numStr.slice(-3)\n groups.unshift(Number(last3))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n const group = remaining.slice(-2)\n groups.unshift(Number(group))\n remaining = remaining.slice(0, -2)\n }\n\n return groups\n }\n\n convertWholePart (number) {\n if (number === 0n) return this.zeroWord\n\n const groups = this.splitIndian(number)\n const groupCount = groups.length\n const words = []\n\n for (let i = 0; i < groupCount; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n const scaleIndex = groupCount - i - 1\n const groupWords = (groupValue === 1 && scaleIndex > 0) ? 'ஒரு' : this.convertBelowThousand(groupValue)\n words.push(groupWords)\n if (scaleIndex > 0 && this.scales[scaleIndex]) {\n words.push(this.scales[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n }\n}\n\nexport default function convertToWords (value, options = {}) {\n return new Tamil(options).convertToWords(value)\n}\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * @typedef {Object} ChineseOptions\n * @property {boolean} [formal=true] Use formal/financial numerals (壹贰叁) vs. common numerals (一二三).\n */\n\n/**\n * Chinese language converter.\n *\n * Features:\n * - Concatenated number-word format (no spaces)\n * - Implicit zero insertion for positional values\n * - Decimal digits pronounced individually\n * - Supports both formal (financial) and common (everyday) styles\n */\nexport class Chinese extends GreedyScaleLanguage {\n negativeWord = '负'\n decimalSeparatorWord = '点'\n zeroWord = '零'\n wordSeparator = ''\n\n /**\n * Initializes the Chinese converter.\n *\n * @param {ChineseOptions} [options={}] Configuration options.\n */\n constructor ({ formal = true } = {}) {\n super()\n\n this.formal = formal\n\n if (this.formal) {\n this.scaleWordPairs = [\n [1_000_000_000_000n, '万'],\n [100_000_000n, '亿'],\n [10_000n, '万'],\n [1000n, '仟'],\n [100n, '佰'],\n [10n, '拾'],\n [9n, '玖'],\n [8n, '捌'],\n [7n, '柒'],\n [6n, '陆'],\n [5n, '伍'],\n [4n, '肆'],\n [3n, '叁'],\n [2n, '贰'],\n [1n, '壹'],\n [0n, '零']\n ]\n } else {\n this.scaleWordPairs = [\n [1_000_000_000_000n, '万'],\n [100_000_000n, '亿'],\n [10_000n, '万'],\n [1000n, '千'],\n [100n, '百'],\n [10n, '十'],\n [9n, '九'],\n [8n, '八'],\n [7n, '七'],\n [6n, '六'],\n [5n, '五'],\n [4n, '四'],\n [3n, '三'],\n [2n, '二'],\n [1n, '一'],\n [0n, '零']\n ]\n }\n }\n\n /**\n * Merges two adjacent word-number pairs according to Chinese grammar rules.\n *\n * Chinese-specific rules:\n * - Omits '一' (or '壹' in formal style) before single digits (< 10)\n * - Concatenates without space\n * - Inserts '零' (zero) when positional values skip magnitude levels\n * - Multiplies when right > left, adds otherwise\n *\n * @param {Object} leftPair The left operand as `{ word: number }`.\n * @param {Object} rightPair The right operand as `{ word: number }`.\n * @returns {Object} Merged pair with combined word and resulting number.\n */\n mergeScales (leftPair, rightPair) {\n const leftWord = Object.keys(leftPair)[0]\n const leftNumber = Object.values(leftPair)[0]\n const rightWord = Object.keys(rightPair)[0]\n const rightNumber = Object.values(rightPair)[0]\n\n // Implicit one: omit 1 before single digits (< 10)\n if (leftNumber === 1n && rightNumber < 10n) {\n return rightPair\n }\n\n // Multiply when right > left (scale words like 千, 万, 亿)\n if (rightNumber > leftNumber) {\n return { [`${leftWord}${rightWord}`]: leftNumber * rightNumber }\n }\n\n // Insert \"零\" (zero) when position skip levels (e.g., 1003 = 千零三)\n // zeroDigit() checks if gap exists between left and right magnitude\n if (this.zeroDigit(leftNumber) > this.digit(rightNumber)) {\n return { [`${leftWord}${this.zeroWord}${rightWord}`]: leftNumber + rightNumber }\n }\n\n // Default: concatenate without zero insertion\n return { [`${leftWord}${rightWord}`]: leftNumber + rightNumber }\n }\n\n /**\n * Get the number of digits in a number.\n *\n * @param {bigint|number} number_ The number to count digits for.\n * @returns {number} The count of digits.\n */\n digit (number_) {\n return number_.toString().length\n }\n\n /**\n * Count the number of zeros in a number.\n *\n * @param {bigint|number} number_ The number to count zeros in.\n * @returns {number} The count of zero digits.\n */\n zeroDigit (number_) {\n return [...number_.toString()].filter(c => c === '0').length\n }\n\n /**\n * Convert decimal digits to words by reading each digit individually.\n * Overrides the default grouped behavior from AbstractLanguage.\n *\n * @param {string} decimalString The decimal digits as a string.\n * @returns {Array<string>} Array of individual digit words.\n */\n decimalDigitsToWords (decimalString) {\n const words = []\n for (let i = 0; i < decimalString.length; i++) {\n const digitValue = BigInt(decimalString[i])\n words.push(this.convertWholePart(digitValue))\n }\n return words\n }\n}\n\n/**\n * Converts a number to Chinese cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {ChineseOptions} [options] Conversion options.\n * @returns {string} The number expressed in Chinese words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // '肆拾贰' (formal style)\n * convertToWords(42, { formal: false }); // '四十二' (common style)\n */\nexport default function convertToWords (value, options = {}) {\n return new Chinese(options).convertToWords(value)\n}\n","import GreedyScaleLanguage from '../classes/greedy-scale-language.js'\n\n/**\n * Hungarian language converter.\n *\n * Converts numbers to Hungarian words following Hungarian conventions:\n * - Agglutinative structure for compound numbers\n * - No spaces between tens and units (e.g., \"huszonegy\" = twenty-one)\n * - Special handling for \"egy\" (one) - often omitted as multiplier\n * - Vowel harmony in compound words\n *\n * Features:\n * - Compact number representations (húsz, harminc, negyven)\n * - Pre-composed twenties (huszonegy through huszonkilenc)\n * - \"egész\" as decimal separator (meaning \"whole\")\n * - Support for very large numbers (up to quadrilliards)\n */\nexport class Hungarian extends GreedyScaleLanguage {\n negativeWord = 'mínusz'\n decimalSeparatorWord = 'egész'\n zeroWord = 'nulla'\n scaleWordPairs = [\n [1_000_000_000_000_000_000_000_000_000n, 'quadrilliárd'],\n [1_000_000_000_000_000_000_000_000n, 'quadrillió'],\n [1_000_000_000_000_000_000_000n, 'trilliárd'],\n [1_000_000_000_000_000_000n, 'trillió'],\n [1_000_000_000_000_000n, 'billiárd'],\n [1_000_000_000_000n, 'billió'],\n [1_000_000_000n, 'milliárd'],\n [1_000_000n, 'millió'],\n [1000n, 'ezer'],\n [100n, 'száz'],\n [90n, 'kilencven'],\n [80n, 'nyolcvan'],\n [70n, 'hetven'],\n [60n, 'hatvan'],\n [50n, 'ötven'],\n [40n, 'negyven'],\n [30n, 'harminc'],\n [29n, 'huszonkilenc'],\n [28n, 'huszonnyolc'],\n [27n, 'huszonhét'],\n [26n, 'huszonhat'],\n [25n, 'huszonöt'],\n [24n, 'huszonnégy'],\n [23n, 'huszonhárom'],\n [22n, 'huszonkettő'],\n [21n, 'huszonegy'],\n [20n, 'húsz'],\n [19n, 'tizenkilenc'],\n [18n, 'tizennyolc'],\n [17n, 'tizenhét'],\n [16n, 'tizenhat'],\n [15n, 'tizenöt'],\n [14n, 'tizennégy'],\n [13n, 'tizenhárom'],\n [12n, 'tizenkettő'],\n [11n, 'tizenegy'],\n [10n, 'tíz'],\n [9n, 'kilenc'],\n [8n, 'nyolc'],\n [7n, 'hét'],\n [6n, 'hat'],\n [5n, 'öt'],\n [4n, 'négy'],\n [3n, 'három'],\n [2n, 'kettő'],\n [1n, 'egy'],\n [0n, 'nulla']\n ]\n\n tensToCardinal (number) {\n // Expecting `number` as bigint when called from convertWholePart\n if (this.getScaleWord(number)) {\n return this.getScaleWord(number)\n } else {\n const tens = number / 10n\n const units = number % 10n\n return this.getScaleWord(tens * 10n) + this.convertWholePart(units)\n }\n }\n\n hundredsToCardinal (number) {\n const hundreds = number / 100n\n let prefix = 'száz'\n if (hundreds !== 1n) {\n prefix = this.convertWholePart(hundreds, '') + prefix\n }\n const postfix = this.convertWholePart(number % 100n, '')\n return prefix + postfix\n }\n\n thousandsToCardinal (number) {\n const thousands = number / 1000n\n let prefix = 'ezer'\n if (thousands !== 1n) {\n prefix = this.convertWholePart(thousands, '') + prefix\n }\n const postfix = this.convertWholePart(number % 1000n, '')\n const middle = (number <= 2000n || postfix === '') ? '' : '-'\n return prefix + middle + postfix\n }\n\n bigNumberToCardinal (number) {\n const numberLength = number.toString().length\n const digits = (numberLength % 3 === 0) ? numberLength - 2 : numberLength\n const exp = 10 ** (Math.floor(digits / 3) * 3)\n const prefix = this.convertWholePart(number / BigInt(exp), '')\n const rest = this.convertWholePart(number % BigInt(exp), '')\n const postfix = (rest === '') ? '' : ('-' + rest)\n return prefix + this.getScaleWord(BigInt(exp)) + postfix\n }\n\n convertWholePart (number, zeroWord = this.zeroWord) {\n let words = ''\n\n // Normalize to BigInt for consistent comparisons\n if (typeof number !== 'bigint') number = BigInt(number)\n\n if (number === 0n) {\n words = zeroWord\n } else if (zeroWord === '' && number === 2n) {\n words = 'két'\n } else if (number < 30n) {\n words = this.getScaleWord(number)\n } else if (number < 100n) {\n words = this.tensToCardinal(number)\n } else if (number < 1000n) {\n words = this.hundredsToCardinal(number)\n } else if (number < 1_000_000n) {\n words = this.thousandsToCardinal(number)\n } else {\n words = this.bigNumberToCardinal(number)\n }\n\n return words\n }\n}\n\n/**\n * Converts a number to Hungarian cardinal (written) form.\n *\n * @param {number|string|bigint} value The number to convert.\n * @param {Object} [options] Conversion options (see Hungarian class options).\n * @returns {string} The number expressed in Hungarian words.\n * @throws {TypeError} If value is NaN or invalid type.\n * @throws {Error} If value is an invalid number string.\n *\n * @example\n * convertToWords(42); // 'negyvenkettő'\n * convertToWords(21); // 'huszonegy'\n */\nexport default function convertToWords (value, options = {}) {\n return new Hungarian(options).convertToWords(value)\n}\n","'use strict';\n// Should get iterator record of a set-like object before cloning this\n// https://bugs.webkit.org/show_bug.cgi?id=289430\nmodule.exports = function (METHOD_NAME) {\n try {\n // eslint-disable-next-line es/no-set -- needed for test\n var baseSet = new Set();\n var setLike = {\n size: 0,\n has: function () { return true; },\n keys: function () {\n // eslint-disable-next-line es/no-object-defineproperty -- needed for test\n return Object.defineProperty({}, 'next', {\n get: function () {\n baseSet.clear();\n baseSet.add(4);\n return function () {\n return { done: true };\n };\n }\n });\n }\n };\n var result = baseSet[METHOD_NAME](setLike);\n\n return result.size === 1 && result.values().next().value === 4;\n } catch (error) {\n return false;\n }\n};\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","/**\n * @module n2words\n */\n\n/** @typedef {'ar'|'az'|'bn'|'cs'|'de'|'da'|'el'|'en'|'es'|'fa'|'fr'|'fr-BE'|'gu'|'he'|'hi'|'hr'|'hu'|'id'|'it'|'ja'|'kn'|'ko'|'lt'|'lv'|'mr'|'ms'|'nl'|'nb'|'pa-Guru'|'pl'|'pt'|'ro'|'ru'|'sr-Latn'|'sv'|'sw'|'ta'|'te'|'th'|'fil'|'tr'|'uk'|'ur'|'vi'|'zh-Hans'} LanguageCode */\n\n/**\n * @typedef {Object} ArabicOptions\n * @property {string} [negativeWord='ناقص'] - Word for negative numbers (minus).\n * @property {boolean} [feminine=false] - Use feminine forms for numbers.\n */\n\n/**\n * @typedef {Object} ChineseOptions\n * @property {boolean} [formal=true] - Use formal/financial numerals (壹贰叁) vs. common numerals (一二三).\n */\n\n/**\n * @typedef {Object} HebrewOptions\n * @property {string} [and='ו'] - Conjunction character (typically 'ו' for and).\n * @property {boolean} [biblical=false] - Use biblical scale words instead of modern ones.\n * @property {boolean} [feminine=false] - Use feminine forms for numbers.\n */\n\n/**\n * @typedef {Object} SpanishOptions\n * @property {('o'|'a'|string)} [genderStem='o'] - Masculine 'o' or feminine 'a' ending.\n */\n\n/**\n * @typedef {Object} DutchOptions\n * @property {boolean} [includeOptionalAnd=false] - Include optional \"en\" separator.\n * @property {boolean} [noHundredPairs=false] - Disable comma before hundreds.\n * @property {boolean} [accentOne=true] - Use accented \"één\" for one.\n */\n\n/**\n * @typedef {Object} FrenchOptions\n * @property {boolean} [withHyphenSeparator=false] - Use hyphens (true) instead of spaces (false) in compounds.\n */\n\n/**\n * @typedef {Object} TurkishOptions\n * @property {boolean} [dropSpaces=false] - Remove spaces between words if true.\n */\n\n/**\n * @typedef {Object} RomanianOptions\n * @property {boolean} [feminine=false] - Use feminine forms for numbers.\n */\n\n/**\n * @typedef {Object} DanishOptions\n * @property {boolean} [ordFlag=false] - Enable ordinal number conversion.\n */\n\n/**\n * @typedef {Object} SlavicOptions\n * @property {boolean} [feminine=false] - Use feminine forms for numbers.\n */\n\n/**\n * Configuration object for number-to-words conversion with comprehensive language support.\n *\n * @typedef {Object} N2WordsOptions\n * @property {LanguageCode} [lang='en'] - Target language code with full autocomplete support.\n * Supports many languages with regional variants (e.g., 'fr-BE').\n * Falls back progressively from most-specific to least-specific (e.g., 'fr-BE' -> 'fr').\n * Throws an error if no match is found after fallback attempts.\n * @property {string} [negativeWord] - (Arabic only) Word for negative numbers.\n * @property {boolean} [feminine] - (Arabic, Hebrew, Romanian, Slavic languages) Use feminine forms.\n * @property {boolean} [formal] - (Chinese only) Use formal/financial numerals.\n * @property {string} [and] - (Hebrew only) Conjunction character.\n * @property {boolean} [biblical] - (Hebrew only) Use biblical scale words.\n * @property {('o'|'a'|string)} [genderStem] - (Spanish only) Gender ending.\n * @property {boolean} [includeOptionalAnd] - (Dutch only) Include optional \"en\".\n * @property {boolean} [noHundredPairs] - (Dutch only) Disable comma before hundreds.\n * @property {boolean} [accentOne] - (Dutch only) Use accented \"één\".\n * @property {boolean} [withHyphenSeparator] - (French, Belgian French) Use hyphens.\n * @property {boolean} [dropSpaces] - (Turkish, Azerbaijani) Remove spaces.\n * @property {boolean} [ordFlag] - (Danish only) Enable ordinal conversion.\n *\n * Language-specific options are automatically validated and forwarded to converters.\n * See individual language implementations for detailed option descriptions.\n */\n\nimport ar from './languages/ar.js'\nimport az from './languages/az.js'\nimport cs from './languages/cs.js'\nimport de from './languages/de.js'\nimport da from './languages/da.js'\nimport en from './languages/en.js'\nimport es from './languages/es.js'\nimport fa from './languages/fa.js'\nimport sw from './languages/sw.js'\nimport fr from './languages/fr.js'\nimport frBE from './languages/fr-BE.js'\nimport he from './languages/he.js'\nimport hr from './languages/hr.js'\nimport hu from './languages/hu.js'\nimport id from './languages/id.js'\nimport ms from './languages/ms.js'\nimport it from './languages/it.js'\nimport ja from './languages/ja.js'\nimport hi from './languages/hi.js'\nimport bn from './languages/bn.js'\nimport ko from './languages/ko.js'\nimport th from './languages/th.js'\nimport ta from './languages/ta.js'\nimport te from './languages/te.js'\nimport sv from './languages/sv.js'\nimport lt from './languages/lt.js'\nimport lv from './languages/lv.js'\nimport nl from './languages/nl.js'\nimport nb from './languages/nb.js'\nimport pl from './languages/pl.js'\nimport pt from './languages/pt.js'\nimport ro from './languages/ro.js'\nimport ru from './languages/ru.js'\nimport srLatn from './languages/sr-Latn.js'\nimport tr from './languages/tr.js'\nimport uk from './languages/uk.js'\nimport vi from './languages/vi.js'\nimport zhHans from './languages/zh-Hans.js'\nimport ur from './languages/ur.js'\nimport paGuru from './languages/pa-Guru.js'\nimport fil from './languages/fil.js'\nimport mr from './languages/mr.js'\nimport gu from './languages/gu.js'\nimport kn from './languages/kn.js'\nimport el from './languages/el.js'\n\n/**\n * Language converter registry.\n * Contains converters for all supported languages, statically imported to work\n * in both Node.js and browser environments (enables bundler dead-code elimination).\n * Keys are language codes (e.g., 'en', 'fr', 'fr-BE'); values are converter functions.\n * @type {Object<string, Function>}\n */\nconst dict = {\n ar,\n az,\n cs,\n de,\n da,\n en,\n es,\n fa,\n sw,\n fr,\n 'fr-BE': frBE,\n he,\n hr,\n hu,\n id,\n ms,\n it,\n ja,\n hi,\n bn,\n ko,\n th,\n ta,\n te,\n sv,\n lt,\n lv,\n nl,\n nb,\n pl,\n pt,\n ro,\n ru,\n 'sr-Latn': srLatn,\n tr,\n uk,\n vi,\n 'zh-Hans': zhHans,\n ur,\n 'pa-Guru': paGuru,\n fil,\n mr,\n gu,\n kn,\n el\n}\n\n/**\n * Convert a numeric value to its cardinal (written) form in the requested language.\n *\n * This is the main entry point. The library dispatches synchronously to the appropriate\n * per-language converter based on the `lang` option. For browser builds, language converters\n * are statically imported so bundlers (webpack/rollup) can include them in output; Node.js\n * maintains identical behavior via the same static imports.\n *\n * @param {number|string|bigint} value The number to convert. Accepts:\n * - `number` (integer or floating-point),\n * - `string` (numeric string, possibly with decimal point),\n * - `bigint` for very large integers.\n * Decimal numbers as strings preserve precision that `number` type cannot.\n * @param {N2WordsOptions} [options={}] Optional configuration object.\n *\n * @returns {string} A human-readable cardinal representation of `value` in the\n * requested language.\n *\n * @throws {TypeError} If `options` is provided but is not an object.\n * @throws {Error} If the requested language is unsupported (no match after fallback).\n *\n * @example\n * // Basic usage\n * convertToWords(1, { lang: 'en' }) // => 'one'\n * convertToWords('45.67', { lang: 'en' }) // => 'forty-five point six seven'\n * convertToWords(123n, { lang: 'fr' }) // => 'cent vingt-trois'\n *\n * @example\n * // Language-specific options (see individual language implementations)\n * convertToWords(1, { lang: 'zh-Hans', formal: true }) // Chinese formal style\n * convertToWords(1, { lang: 'cs', feminine: true }) // Czech feminine form\n */\nexport default function (value, options = {}) {\n if (options !== null && options !== undefined && typeof options !== 'object') {\n throw new TypeError('Options must be an object, received: ' + typeof options)\n }\n\n if (options === null) {\n options = {}\n }\n\n let languageCode = options.lang\n\n if (languageCode === undefined) {\n return dict.en(value, options)\n }\n\n if (typeof languageCode !== 'string') {\n languageCode = String(languageCode)\n }\n\n let languageConverter = dict[languageCode]\n if (languageConverter !== undefined) {\n return languageConverter(value, options)\n }\n\n // Progressive fallback for regional variants: strip suffix on each iteration.\n // Example: 'fr-BE-XX' -> try 'fr-BE' -> try 'fr' -> throw error\n // Uses lastIndexOf for efficiency (O(n) vs O(n²) with repeated substring)\n let lastDashIndex = languageCode.lastIndexOf('-')\n while (lastDashIndex > 0) {\n const candidateLanguageCode = languageCode.slice(0, lastDashIndex)\n languageConverter = dict[candidateLanguageCode]\n if (languageConverter !== undefined) {\n return languageConverter(value, options)\n }\n lastDashIndex = candidateLanguageCode.lastIndexOf('-')\n }\n\n throw new Error('Unsupported language: \"' + languageCode + '\". Check supported language codes in the documentation.')\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","isCallable","it","call","aCallable","anObject","tryToString","getIteratorMethod","$TypeError","TypeError","argument","usingIterator","iteratorMethod","arguments","length","$","iterate","getIteratorDirect","iteratorClose","findWithoutClosingOnEarlyError","iteratorHelperWithoutClosingOnEarlyError","target","proto","real","forced","find","predicate","this","error","record","counter","value","stop","IS_RECORD","INTERRUPTED","result","uncurryThis","fails","hasOwn","DESCRIPTORS","CONFIGURABLE_FUNCTION_NAME","inspectSource","InternalStateModule","enforceInternalState","enforce","getInternalState","get","$String","String","defineProperty","Object","stringSlice","slice","replace","join","CONFIGURABLE_LENGTH","TEMPLATE","split","makeBuiltIn","name","options","getter","setter","configurable","arity","constructor","writable","prototype","undefined","state","source","Function","toString","FunctionPrototype","getDescriptor","getOwnPropertyDescriptor","EXISTS","PROPER","CONFIGURABLE","getBuiltIn","fn","ITERATOR_INSTEAD_OF_RECORD","step","iterator","next","done","test","bind","hasOwnProperty","English","GreedyScaleLanguage","negativeWord","decimalSeparatorWord","zeroWord","scaleWordPairs","mergeScales","leftPair","rightPair","leftWord","keys","leftNumber","values","rightWord","rightNumber","convertToWords","Hindi","SouthAsianLanguage","hundredWord","belowHundred","scaleWords","isPrototypeOf","Prototype","methodName","method","Iterator","Portuguese","hundreds","static","finalizeWords","words","replaceAll","POSTCLEAN_REGEX","current","cText","nText","cNumber","nNumber","ceil","Math","floor","trunc","x","n","USE_SYMBOL_AS_UID","$Object","$Symbol","classof","getMethod","isNullOrUndefined","Iterators","ITERATOR","wellKnownSymbol","internalObjectKeys","enumBugKeys","O","Vietnamese","AbstractLanguage","base","tens","thousands","convertLess100","number","unitsPart","tensPart","tensPartText","suffix","convertLess1000","tensUnitsPart","hundredsPart","push","convertWholePart","convertMore1000","division","power","r","BigInt","pow","Number","set","has","NATIVE_WEAK_MAP","isObject","createNonEnumerableProperty","shared","sharedKey","hiddenKeys","OBJECT_ALREADY_INITIALIZED","WeakMap","store","metadata","facade","STATE","getterFor","TYPE","type","Arabic","arabicTens","arabicHundreds","arabicAppendedTwos","arabicTwos","arabicGroup","arabicAppendedGroup","arabicPluralGroups","ones","masculine","feminine","super","selectedOnes","digitFeminineStatus","digit","processArabicGroup","groupNumber","groupLevel","fullNumber","hundredsRaw","returnValue","hundredsWord","numValue","log10","tensIndex","temp","group","numberToProcess","groupDescription","trim","MarathiLanguage","convertDecimalsPerDigit","iters","kind","i","Latvian","SlavicLanguage","twenties","pluralize","forms","chunks","splitByX","index","n1","n2","n3","getDigits","Punjabi","splitToGroups","numStr","groups","last3","unshift","remaining","convertBelowThousand","remainder","parts","groupCount","groupValue","scaleIndex","Hebrew","scale","scalePlural","biblicalOnes","biblicalTens","biblicalTwenties","biblicalHundreds","biblicalThousands","biblicalScale","biblicalScalePlural","and","biblical","chunkWords","hasHundreds","tensWord","onesWord","at","union","setMethodGetKeysBeforeCloning","setMethodAcceptSetLike","createIteratorProxy","callWithSafeIterationClosing","iteratorHelperThrowsOnInvalidIterator","IS_PURE","MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR","mapWithoutClosingOnEarlyError","FORCED","IteratorProxy","mapper","map","Ukrainian","onesFeminine","obj","toIndexedObject","indexOf","object","names","key","Urdu","descriptor","f","French","withHyphenSeparator","wordSeparator","currentPair","nextPair","currentWord","nextWord","currentNumber","nextNumber","F","getPrototypeOf","activeXDocument","definePropertiesModule","html","documentCreateElement","PROTOTYPE","SCRIPT","IE_PROTO","EmptyConstructor","scriptTag","content","LT","NullProtoObjectViaActiveX","write","close","parentWindow","NullProtoObject","ActiveXObject","iframeDocument","iframe","JS","document","domain","style","display","appendChild","src","contentWindow","open","create","Properties","Malay","splitBy3","blocks","stringNumber","firstBlock","firstBlockLength","nextBlock","spell","spelling","wordBlocks","getTens","getHundreds","block","wordList","isLast","scaleWord","w","isSupersetOf","Azerbaijani","TurkicLanguage","Serbian","SCALE","lastDigit","lastTwoDigits","genderIndex","isArrayIteratorMethod","lengthOfArrayLike","getIterator","Result","stopped","ResultPrototype","iterable","unboundFunction","iterFn","that","AS_ENTRIES","IS_ITERATOR","condition","callFn","isSymbol","ordinaryToPrimitive","TO_PRIMITIVE","input","pref","exoticToPrim","toObject","CORRECT_PROTOTYPE_GETTER","ObjectPrototype","replacement","isForced","feature","detection","data","normalize","POLYFILL","NATIVE","string","toLowerCase","navigator","userAgent","Russian","Bengali","GujaratiLanguage","Telugu","digits","scales","convertBelowHundred","splitIndian","groupWords","id","postfix","random","aSet","SetHelpers","clone","size","getSetRecord","iterateSet","iterateSimple","remove","other","otherRec","e","includes","GreekLanguage","add","keysIter","functionToString","getOwnPropertySymbols","toIntegerOrInfinity","INVALID_SIZE","$RangeError","RangeError","max","SetRecord","intSize","numSize","isDisjointFrom","German","entries","mergedNumber","Indonesian","start","createElement","getScaleWord","scaleValue","matchingPair","pair","decomposeToScales","wholeNumber","decomposeWordSets","remainingValue","matchingScaleWordPair","scaleWordPair","multiplier","mergeWordSets","mergeWordSetsList","firstWordSet","secondWordSet","remainingWordSets","Array","isArray","merged","normalizedWordSets","wordSetElement","leftWordSet","rightWordSet","Error","output","trimEnd","mergedWordSet","resultString","Thai","convertBelowMillion","hundredThousands","tenThousands","splitMillionGroups","million","chunk","repeat","setArrayLength","doesNotExceedSafeInteger","properErrorOnNonWritableLength","item","len","argCount","ArrayPrototype","val","valueOf","SetPrototype","Set","Italian","cardinalWords","strTens","exponentPrefixes","accentuate","word","omitIfZero","numberToString","phoneticContraction","tensToCardinal","units","prefix","hundredsToCardinal","thousandsToCardinal","exponentLengthToString","exponentLength","bigNumberToCardinal","preDigits","exponent","infix","isSetsEqual","a","b","every","Romanian","tensMasculine","singular","plural","needsDe","results","l","padStart","toReversed","romanianPluralize","form","spellUnder1000","spellUnder100","feminineUnits","t","u","h","hundredWords","decimalDigitsToWords","decimal","chars","decimalNumber","masculineWords","toCardinalWithMasculine","onesMap","V8_VERSION","symbol","Symbol","sham","SILENT_ON_NON_WRITABLE_LENGTH_SET","METHOD_NAME","ExpectedError","IteratorPrototype","CLOSED","check","window","self","global","Dutch","includeOptionalAnd","noHundredPairs","accentOne","hadSpace","hasSpace","temporary","andTxt","endsWith","high","low","definePropertyModule","createPropertyDescriptor","documentAll","all","IE8_DOM_DEFINE","V8_PROTOTYPE_DEFINE_BUG","toPropertyKey","$defineProperty","$getOwnPropertyDescriptor","ENUMERABLE","WRITABLE","P","Attributes","enumerable","createSetLike","createSetLikeWithInfinitySize","callback","error2","Infinity","FilipinoLanguage","leftValue","rightValue","vowels","lastChar","symmetricDifference","getOwnPropertyNamesModule","getOwnPropertySymbolsModule","concat","uncurryThisAccessor","Japanese","convertGroup","num","isTopGroup","reverse","groupStr","IndexedObject","requireObjectCoercible","min","integer","Turkish","dropSpaces","Polish","Farsi","namedNumbers","xone","xten","xhundred","tail","thousandMultiplier","tailNumber","millionMultiplier","isSubsetOf","V","func","NATIVE_BIND","apply","Croatian","uid","toLength","defineBuiltIn","cachedWholeNumber","convertDigitToWord","idx","decimalString","decimalDigit","remainingDigits","inputType","isNaN","decimalPart","isNegative","decimalPointIndex","wholePartString","ENTRIES","Swedish","BelgianFrench","UNSCOPABLES","defineGlobalProperty","copyConstructorProperties","targetProperty","sourceProperty","TARGET","GLOBAL","STATIC","stat","dontCallGetSet","Czech","objectKeys","defineProperties","props","simple","unsafe","nonConfigurable","nonWritable","Norwegian","TO_STRING_TAG_SUPPORT","classofRaw","TO_STRING_TAG","CORRECT_ARGUMENTS","tag","tryGet","callee","toPrimitive","bitmap","NATIVE_SYMBOL","propertyIsEnumerable","chunkIndex","chunkValue","onesDigit","tensDigit","hundredsDigit","onesArray","numberString","chunkSize","stringLength","remainderLength","pluralForms","remainder100","remainder10","propertyIsEnumerableModule","C","A","k","SHARED","versions","version","mode","copyright","license","difference","setLike","baseSet","clear","PrototypeOfArrayIteratorPrototype","arrayIterator","BUGGY_SAFARI_ITERATORS","ownKeys","getOwnPropertyDescriptorModule","exceptions","namespace","Danish","ordFlag","intersection","from","anInstance","defineBuiltInAccessor","createProperty","CONSTRUCTOR","NativeIterator","IteratorConstructor","defineIteratorPrototypeAccessor","WellKnownSymbolsStore","createWellKnownSymbol","withoutSetter","Korean","Swahili","wordsUnder100","wordsUnder1000","rest","s","unit","forEach","interruptible","getOwnPropertyNames","Spanish","genderStem","$propertyIsEnumerable","NASHORN_BUG","exec","KannadaLanguage","Lithuanian","defineBuiltIns","createIterResultObject","iteratorCloseAll","ITERATOR_HELPER","WRAP_FOR_VALID_ITERATOR","NORMAL","THROW","setInternalState","createIteratorProxyPrototype","nextHandler","returnHandlerResult","returnMethod","inner","openIters","WrapForValidIteratorPrototype","IteratorHelperPrototype","RETURN_HANDLER_RESULT","uncurryThisWithBind","match","process","Deno","v8","innerResult","innerError","toAbsoluteIndex","createMethod","IS_INCLUDES","$this","el","fromIndex","arrayToReversed","addToUnscopables","$Array","Tamil","hundredPart","Chinese","formal","zeroDigit","number_","filter","c","digitValue","Hungarian","numberLength","exp","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","d","definition","o","prop","dict","ar","az","cs","de","da","en","es","fa","sw","fr","frBE","he","hr","hu","ms","ja","hi","bn","ko","th","ta","te","sv","lt","lv","nl","nb","pl","pt","ro","ru","srLatn","tr","uk","vi","zhHans","ur","paGuru","fil","mr","gu","kn","languageCode","lang","languageConverter","lastDashIndex","lastIndexOf","candidateLanguageCode"],"ignoreList":[],"sourceRoot":""}
1
+ {"version":3,"file":"n2words.js","sources":["../lib/utils/parse-numeric.js","../lib/languages/am.js","../lib/languages/am-Latn.js","../lib/utils/validate-options.js","../lib/utils/is-plain-object.js","../lib/languages/ar.js","../lib/languages/az.js","../lib/languages/bn.js","../lib/languages/cs.js","../lib/languages/da.js","../lib/languages/de.js","../lib/languages/el.js","../lib/languages/en.js","../lib/languages/es.js","../lib/languages/fa.js","../lib/languages/fi.js","../lib/languages/fil.js","../lib/languages/fr.js","../lib/languages/fr-BE.js","../lib/languages/gu.js","../lib/languages/ha.js","../lib/languages/hbo.js","../lib/languages/he.js","../lib/languages/hi.js","../lib/languages/hr.js","../lib/languages/hu.js","../lib/languages/id.js","../lib/languages/it.js","../lib/languages/ja.js","../lib/languages/kn.js","../lib/languages/ko.js","../lib/languages/lt.js","../lib/languages/lv.js","../lib/languages/mr.js","../lib/languages/ms.js","../lib/languages/nb.js","../lib/languages/nl.js","../lib/languages/pa.js","../lib/languages/pl.js","../lib/languages/pt.js","../lib/languages/ro.js","../lib/languages/ru.js","../lib/languages/sr-Cyrl.js","../lib/languages/sr-Latn.js","../lib/languages/sv.js","../lib/languages/sw.js","../lib/languages/ta.js","../lib/languages/te.js","../lib/languages/th.js","../lib/languages/tr.js","../lib/languages/uk.js","../lib/languages/ur.js","../lib/languages/vi.js","../lib/languages/zh-Hans.js","../lib/languages/zh-Hant.js"],"sourcesContent":["/**\n * Numeric value parsing utility.\n * Transforms user input (number, string, or bigint) into normalized components.\n * @module parse-numeric\n */\n\n/**\n * Parses a numeric value into its components.\n * @param {number|string|bigint} value\n * @returns {{isNegative: boolean, integerPart: bigint, decimalPart?: string}}\n * @throws {TypeError} If value is not number, string, or bigint\n * @throws {Error} If value is not a valid number format\n */\nexport function parseNumericValue (value) {\n const type = typeof value\n\n // BigInt: simplest case\n if (type === 'bigint') {\n return value < 0n\n ? { isNegative: true, integerPart: -value }\n : { isNegative: false, integerPart: value }\n }\n\n // Number: fast path for safe integers\n if (type === 'number') {\n if (!Number.isFinite(value)) {\n throw new Error('Number must be finite (NaN and Infinity are not supported)')\n }\n if (Number.isSafeInteger(value)) {\n return value < 0\n ? { isNegative: true, integerPart: BigInt(-value) }\n : { isNegative: false, integerPart: BigInt(value) }\n }\n return parseNumericString(numberToString(value))\n }\n\n // String input\n if (type === 'string') {\n return parseNumericString(normalizeString(value))\n }\n\n throw new TypeError(\n `Invalid value type: expected number, string, or bigint, received ${type}`\n )\n}\n\n/**\n * Converts a number to decimal string, expanding scientific notation if needed.\n */\nfunction numberToString (value) {\n const str = value.toString()\n return (str.includes('e') || str.includes('E'))\n ? expandScientificNotation(str)\n : str\n}\n\n/**\n * Validates and normalizes a string numeric input.\n */\nfunction normalizeString (value) {\n const trimmed = value.trim()\n if (trimmed.length === 0 || Number.isNaN(Number(trimmed))) {\n throw new Error(`Invalid number format: \"${value}\"`)\n }\n return (trimmed.includes('e') || trimmed.includes('E'))\n ? expandScientificNotation(trimmed)\n : trimmed\n}\n\n/**\n * Parses a normalized numeric string into components.\n */\nfunction parseNumericString (str) {\n const isNegative = str[0] === '-'\n if (isNegative) str = str.slice(1)\n\n const dotIndex = str.indexOf('.')\n if (dotIndex === -1) {\n return { isNegative, integerPart: BigInt(str) }\n }\n\n const integerStr = str.slice(0, dotIndex) || '0'\n const decimalPart = str.slice(dotIndex + 1)\n return { isNegative, integerPart: BigInt(integerStr), decimalPart }\n}\n\n/**\n * Expands scientific notation to decimal form (e.g., \"1e21\" → \"1000...\").\n */\nfunction expandScientificNotation (str) {\n const [mantissa, expStr] = str.toLowerCase().split('e')\n const exp = parseInt(expStr, 10)\n\n const dotIndex = mantissa.indexOf('.')\n const digits = dotIndex === -1\n ? mantissa\n : mantissa.slice(0, dotIndex) + mantissa.slice(dotIndex + 1)\n const integerLength = dotIndex === -1 ? mantissa.length : dotIndex\n const newDotPosition = integerLength + exp\n\n if (newDotPosition >= digits.length) {\n return digits + '0'.repeat(newDotPosition - digits.length)\n }\n if (newDotPosition <= 0) {\n return '0.' + '0'.repeat(-newDotPosition) + digits\n }\n return digits.slice(0, newDotPosition) + '.' + digits.slice(newDotPosition)\n}\n","/**\n * Amharic language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n * Native Ge'ez script (ግዕዝ) output.\n *\n * Key features:\n * - Ge'ez/Ethiopic script numerals\n * - Teens formed with \"አስራ\" prefix\n * - Keeps \"one\" before hundred: \"አንድ መቶ\" (100)\n * - Short scale naming\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'አንድ', 'ሁለት', 'ሶስት', 'አራት', 'አምስት', 'ስድስት', 'ሰባት', 'ስምንት', 'ዘጠኝ']\nconst TEENS = ['አስር', 'አስራ አንድ', 'አስራ ሁለት', 'አስራ ሶስት', 'አስራ አራት', 'አስራ አምስት', 'አስራ ስድስት', 'አስራ ሰባት', 'አስራ ስምንት', 'አስራ ዘጠኝ']\nconst TENS = ['', '', 'ሃያ', 'ሰላሳ', 'አርባ', 'ሃምሳ', 'ስልሳ', 'ሰባ', 'ሰማንያ', 'ዘጠና']\n\nconst HUNDRED = 'መቶ'\nconst THOUSAND = 'ሺ'\n\nconst ZERO = 'ዜሮ'\nconst NEGATIVE = 'አሉታዊ'\nconst DECIMAL_SEP = 'ነጥብ'\n\n// Short scale\nconst SCALE_WORDS = ['', THOUSAND, 'ሚሊዮን', 'ቢሊዮን']\n\n// ============================================================================\n// Precomputed Lookup Table\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Amharic keeps \"one\" before hundred: \"አንድ መቶ\" (100)\n if (hundredsDigit > 0) {\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)\n }\n\n if (tensDigit === 1) {\n parts.push(TEENS[ones])\n } else {\n if (tensDigit > 1) {\n parts.push(TENS[tensDigit])\n }\n if (ones > 0) {\n parts.push(ONES[ones])\n }\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n return buildLargeNumberWords(n)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = SCALE_WORDS[scaleIndex] || ''\n\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else {\n parts.push(SEGMENTS[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Amharic words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Amharic words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Amharic Latin language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n * Latin/ASCII romanization of Amharic numerals.\n *\n * Key features:\n * - Romanized numerals (and, hulet, sost)\n * - Teens formed with \"asra\" prefix\n * - Keeps \"one\" before hundred: \"and meto\" (100)\n * - Short scale naming\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'and', 'hulet', 'sost', 'arat', 'amist', 'siddist', 'sebat', 'siment', 'zeteny']\nconst TEENS = ['asir', 'asra and', 'asra hulet', 'asra sost', 'asra arat', 'asra amist', 'asra siddist', 'asra sebat', 'asra siment', 'asra zeteny']\nconst TENS = ['', '', 'haya', 'selasa', 'arba', 'hamsa', 'silsa', 'seba', 'semanya', 'zetena']\n\nconst HUNDRED = 'meto'\nconst THOUSAND = 'shi'\n\nconst ZERO = 'zero'\nconst NEGATIVE = 'asitegna'\nconst DECIMAL_SEP = 'netib'\n\n// Short scale\nconst SCALE_WORDS = ['', THOUSAND, 'miliyon', 'billiyon']\n\n// ============================================================================\n// Precomputed Lookup Table\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Amharic keeps \"one\" before hundred: \"and meto\" (100)\n if (hundredsDigit > 0) {\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)\n }\n\n if (tensDigit === 1) {\n parts.push(TEENS[ones])\n } else {\n if (tensDigit > 1) {\n parts.push(TENS[tensDigit])\n }\n if (ones > 0) {\n parts.push(ONES[ones])\n }\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n return buildLargeNumberWords(n)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = SCALE_WORDS[scaleIndex] || ''\n\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else {\n parts.push(SEGMENTS[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Amharic (Latin script) words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Amharic Latin words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","import { isPlainObject } from './is-plain-object.js'\n\n/**\n * Validates and normalizes the options parameter.\n *\n * @param {*} options The options value to validate\n * @returns {Object} A valid options object (empty object if undefined)\n * @throws {TypeError} If options is not undefined or a plain object\n */\nexport function validateOptions (options) {\n if (options === undefined) return {}\n if (isPlainObject(options)) return options\n throw new TypeError(\n `Invalid options: expected plain object or undefined, got ${typeof options}`\n )\n}\n","/**\n * Checks if a value is a plain object (not null, array, or other object types).\n *\n * A plain object is one created by:\n * - Object literal: `{}`\n * - Object.create(null): null-prototype object\n *\n * This excludes arrays, class instances, Map, Set, and other object types.\n *\n * @param {*} value Value to check\n * @returns {boolean} True if value is a plain object\n */\nexport function isPlainObject (value) {\n if (value === null || typeof value !== 'object') return false\n const proto = Object.getPrototypeOf(value)\n return proto === null || proto === Object.prototype\n}\n","/**\n * Arabic language converter - Functional Implementation\n *\n * Self-contained converter with gender agreement and complex pluralization.\n *\n * Key features:\n * - Gender agreement (masculine/feminine forms)\n * - Complex pluralization (singular/dual/plural)\n * - Traditional Arabic number naming conventions\n * - \"و\" (and) conjunction between segments\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst TENS = ['عشرون', 'ثلاثون', 'أربعون', 'خمسون', 'ستون', 'سبعون', 'ثمانون', 'تسعون']\nconst HUNDREDS = ['', 'مائة', 'مئتان', 'ثلاثمائة', 'أربعمائة', 'خمسمائة', 'ستمائة', 'سبعمائة', 'ثمانمائة', 'تسعمائة']\n\n// Magnitude words with three forms: singular, appended (tanween), plural\nconst SCALE_WORDS = ['مائة', 'ألف', 'مليون', 'مليار', 'تريليون', 'كوادريليون', 'كوينتليون', 'سكستيليون']\nconst SCALE_APPENDED = ['', 'ألفاً', 'مليوناً', 'ملياراً', 'تريليوناً', 'كوادريليوناً', 'كوينتليوناً', 'سكستيليوناً']\nconst SCALE_PLURAL = ['', 'آلاف', 'ملايين', 'مليارات', 'تريليونات', 'كوادريليونات', 'كوينتليونات', 'سكستيليونات']\n\n// Dual forms\nconst DUAL = ['مئتان', 'ألفان', 'مليونان', 'ملياران', 'تريليونان', 'كوادريليونان', 'كوينتليونان', 'سكستيليونان']\nconst DUAL_APPENDED = ['مئتا', 'ألفا', 'مليونا', 'مليارا', 'تريليونا', 'كوادريليونا', 'كوينتليونا', 'سكستيليونا']\n\n// Gender-specific forms (1-19)\nconst ONES_MASC = ['واحد', 'اثنان', 'ثلاثة', 'أربعة', 'خمسة', 'ستة', 'سبعة', 'ثمانية', 'تسعة', 'عشرة', 'أحد عشر', 'اثنا عشر', 'ثلاثة عشر', 'أربعة عشر', 'خمسة عشر', 'ستة عشر', 'سبعة عشر', 'ثمانية عشر', 'تسعة عشر']\nconst ONES_FEM = ['واحدة', 'اثنتان', 'ثلاث', 'أربع', 'خمس', 'ست', 'سبع', 'ثمان', 'تسع', 'عشر', 'إحدى عشرة', 'اثنتا عشرة', 'ثلاث عشرة', 'أربع عشرة', 'خمس عشرة', 'ست عشرة', 'سبع عشرة', 'ثماني عشرة', 'تسع عشرة']\n\nconst ZERO = 'صفر'\nconst NEGATIVE = 'ناقص'\nconst DECIMAL_SEP = 'فاصلة'\nconst AND = 'و'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Convert a 3-digit group to words.\n * Returns a clean string with no leading/trailing spaces.\n * Arabic \"و\" (and) is attached to following word: \"مائة وخمسة\" not \"مائة و خمسة\"\n */\nfunction segmentToWords (groupNumber, groupLevel, fullNumber, ones) {\n const tensValue = groupNumber % 100\n const hundredsDigit = Math.trunc(groupNumber / 100)\n let result = ''\n\n // Process hundreds\n if (hundredsDigit > 0) {\n if (tensValue === 0 && hundredsDigit === 2) {\n result = DUAL[0]\n } else {\n const hundredsWord = HUNDREDS[hundredsDigit]\n if (hundredsWord) {\n result = hundredsWord\n if (tensValue !== 0) {\n result += ' ' + AND // \"مائة و\" - و attaches to next word\n }\n }\n }\n }\n\n // Process tens and ones\n if (tensValue > 0) {\n if (tensValue < 20) {\n if (tensValue === 2 && hundredsDigit === 0 && groupLevel > 0) {\n const numValue = Number(fullNumber)\n const pow = Math.trunc(Math.log10(numValue))\n if (pow % 3 === 0 && fullNumber === BigInt(2 * Math.pow(10, pow))) {\n result += (groupNumber === 2 ? DUAL[groupLevel] : DUAL_APPENDED[groupLevel])\n } else {\n result += DUAL[groupLevel]\n }\n } else if (tensValue === 1 && groupLevel > 0) {\n result += SCALE_WORDS[groupLevel]\n } else {\n result += ones[tensValue - 1]\n }\n } else {\n const onesDigit = tensValue % 10\n const tensIndex = Math.trunc(tensValue / 10) - 2\n\n if (onesDigit > 0) {\n result += ones[onesDigit - 1] + ' ' + AND // \"ستة و\" attaches to tens\n }\n result += TENS[tensIndex]\n }\n }\n\n return result\n}\n\nfunction integerToWords (n, options) {\n if (n === 0n) return ZERO\n\n const gender = options.gender || 'masculine'\n const ones = gender === 'feminine' ? ONES_FEM : ONES_MASC\n\n let temp = n\n let group = 0\n const groups = []\n\n while (temp > 0n) {\n const numberToProcess = Number(temp % 1000n)\n temp = temp / 1000n\n\n if (numberToProcess > 0) {\n const groupDescription = segmentToWords(numberToProcess, group, n, ones)\n\n if (groupDescription) {\n let groupText = groupDescription\n\n // Add scale word for groups > 0\n if (group > 0 && numberToProcess > 2) {\n const remainder = numberToProcess % 100\n if (remainder === 1) {\n groupText += ' ' + SCALE_WORDS[group]\n } else if (numberToProcess >= 3 && numberToProcess <= 10) {\n groupText += ' ' + SCALE_PLURAL[group]\n } else {\n groupText += ' ' + (groups.length > 0 ? SCALE_APPENDED[group] : SCALE_WORDS[group])\n }\n }\n\n groups.unshift(groupText)\n }\n }\n\n group++\n }\n\n // Join groups with و (and) - space before و, attaches to next word\n // Use simple join since segmentToWords returns clean strings\n if (groups.length === 1) return groups[0]\n\n // Build result: \"group1 وgroup2 وgroup3\"\n let result = groups[0]\n for (let i = 1; i < groups.length; i++) {\n result += ' ' + AND + groups[i]\n }\n return result\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n const parts = []\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n parts.push(ZERO)\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n parts.push(integerToWords(BigInt(remainder), options))\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts a numeric value to Arabic words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @param {string} [options.negativeWord] - Custom word for negative numbers\n * @returns {string} The number in Arabic words\n *\n * @example\n * toWords(1) // 'واحد'\n * toWords(1, {gender: 'feminine'}) // 'واحدة'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n const parts = []\n\n if (isNegative) {\n parts.push(options.negativeWord || NEGATIVE)\n }\n\n parts.push(integerToWords(integerPart, options))\n\n if (decimalPart) {\n parts.push(DECIMAL_SEP)\n parts.push(decimalPartToWords(decimalPart, options))\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Azerbaijani language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - Turkic language patterns\n * - Implicit \"bir\" (one) omission before hundreds and thousands\n * - Short scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'bir', 'iki', 'üç', 'dörd', 'beş', 'altı', 'yeddi', 'səkkiz', 'doqquz']\nconst TEENS = ['on', 'on bir', 'on iki', 'on üç', 'on dörd', 'on beş', 'on altı', 'on yeddi', 'on səkkiz', 'on doqquz']\nconst TENS = ['', '', 'iyirmi', 'otuz', 'qırx', 'əlli', 'altmış', 'yetmiş', 'səksən', 'doxsan']\n\nconst HUNDRED = 'yüz'\nconst THOUSAND = 'min'\n\nconst ZERO = 'sıfır'\nconst NEGATIVE = 'mənfi'\nconst DECIMAL_SEP = 'nöqtə'\n\n// Short scale\nconst SCALE_WORDS = ['', THOUSAND, 'milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon']\n\n// ============================================================================\n// Precomputed Lookup Table\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n if (hundredsDigit === 1) {\n parts.push(HUNDRED)\n } else {\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)\n }\n }\n\n if (tensDigit === 1) {\n parts.push(TEENS[ones])\n } else {\n if (tensDigit > 1) {\n parts.push(TENS[tensDigit])\n }\n if (ones > 0) {\n parts.push(ONES[ones])\n }\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n return buildLargeNumberWords(n)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = SCALE_WORDS[scaleIndex] || ''\n\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else if (scaleIndex === 1 && segment === 1) {\n // Omit \"bir\" before thousand\n parts.push(scaleWord)\n } else {\n parts.push(SEGMENTS[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Azerbaijani words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Azerbaijani words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Bangla language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (হাজার, লাখ, কোটি)\n * - Bangla script (Bengali)\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'শূন্য'\nconst NEGATIVE = 'মাইনাস'\nconst DECIMAL_SEP = 'দশমিক'\nconst HUNDRED = 'শত'\n\nconst BELOW_HUNDRED = [\n 'শূন্য', 'এক', 'দুই', 'তিন', 'চার', 'পাঁচ', 'ছয়', 'সাত', 'আট', 'নয়',\n 'দশ', 'এগারো', 'বারো', 'তেরো', 'চৌদ্দ', 'পনেরো', 'ষোল', 'সতেরো', 'আঠারো', 'উনিশ',\n 'বিশ', 'একুশ', 'বাইশ', 'তেইশ', 'চব্বিশ', 'পঁচিশ', 'ছাব্বিশ', 'সাতাশ', 'আঠাশ', 'উনত্রিশ',\n 'ত্রিশ', 'একত্রিশ', 'বত্রিশ', 'তেত্রিশ', 'চৌত্রিশ', 'পঁয়ত্রিশ', 'ছত্রিশ', 'সাঁইত্রিশ', 'আটত্রিশ', 'উনচল্লিশ',\n 'চল্লিশ', 'একচল্লিশ', 'বেয়াল্লিশ', 'তেতাল্লিশ', 'চুয়াল্লিশ', 'পঁয়তাল্লিশ', 'ছেচল্লিশ', 'সাতচল্লিশ', 'আটচল্লিশ', 'উনপঞ্চাশ',\n 'পঞ্চাশ', 'একান্ন', 'বাহান্ন', 'তিপ্পান্ন', 'চুয়ান্ন', 'পঞ্চান্ন', 'ছাপ্পান্ন', 'সাতান্ন', 'আটান্ন', 'উনষাট',\n 'ষাট', 'একষট্টি', 'বাষট্টি', 'তেষট্টি', 'চৌষট্টি', 'পঁয়ষট্টি', 'ছেষট্টি', 'সাতষট্টি', 'আটষট্টি', 'ঊনসত্তর',\n 'সত্তর', 'একাত্তর', 'বাহাত্তর', 'তেহাত্তর', 'চুয়াত্তর', 'পঁচাত্তর', 'ছিয়াত্তর', 'সাতাত্তর', 'আটাত্তর', 'উনআশি',\n 'আশি', 'একাশি', 'বিরাশি', 'তিরাশি', 'চুরাশি', 'পঁচাশি', 'ছিয়াশি', 'সাতাশি', 'আটাশি', 'উননব্বই',\n 'নব্বই', 'একানব্বই', 'বিরানব্বই', 'তিরানব্বই', 'চুরানব্বই', 'পঁচানব্বই', 'ছিয়ানব্বই', 'সাতানব্বই', 'আটানব্বই', 'নিরানব্বই'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'হাজার', 'লাখ', 'কোটি', 'আরব', 'খরব', 'নীল', 'পদ্ম', 'শঙ্খ']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const segments = []\n segments.unshift(Number(numStr.slice(-3)))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n segments.unshift(Number(remaining.slice(-2)))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const segments = groupByThreeThenTwos(n)\n const segmentCount = segments.length\n const words = []\n\n for (let i = 0; i < segmentCount; i++) {\n const segmentValue = segments[i]\n if (segmentValue === 0) continue\n\n const scaleIndex = segmentCount - i - 1\n words.push(segmentToWords(segmentValue))\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Bengali words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Bengali words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Czech language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Czech-specific rules (handled in precomputation):\n * - Three-form pluralization: 1 = singular, 2-4 = few, 5+ = many\n * - Irregular hundreds: sto, dvě stě, tři sta, čtyři sta, pět set...\n * - Gender: dva (masc) vs dvě (fem) for 2\n * - Omit \"one\" before scale words: \"tisíc\" not \"jedna tisíc\"\n * - Dynamic decimal separator: celá/celé/celých based on integer\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\n// Ones words (masculine form)\nconst ONES = ['', 'jedna', 'dva', 'tři', 'čtyři', 'pět', 'šest', 'sedm', 'osm', 'devět']\n\n// Teens (10-19)\nconst TEENS = ['deset', 'jedenáct', 'dvanáct', 'třináct', 'čtrnáct', 'patnáct', 'šestnáct', 'sedmnáct', 'osmnáct', 'devatenáct']\n\n// Tens (20-90)\nconst TENS = ['', '', 'dvacet', 'třicet', 'čtyřicet', 'padesát', 'šedesát', 'sedmdesát', 'osmdesát', 'devadesát']\n\n// Irregular hundreds\nconst HUNDREDS = ['', 'sto', 'dvě stě', 'tři sta', 'čtyři sta', 'pět set', 'šest set', 'sedm set', 'osm set', 'devět set']\n\n// Scale plural forms [singular, few (2-4), many (5+)]\nconst PLURAL_FORMS = {\n 1: ['tisíc', 'tisíce', 'tisíc'], // 10^3\n 2: ['milion', 'miliony', 'milionů'], // 10^6\n 3: ['miliarda', 'miliardy', 'miliard'], // 10^9\n 4: ['bilion', 'biliony', 'bilionů'], // 10^12\n 5: ['biliarda', 'biliardy', 'biliard'], // 10^15\n 6: ['trilion', 'triliony', 'trilionů'], // 10^18\n 7: ['triliarda', 'triliardy', 'triliard'], // 10^21\n 8: ['kvadrilion', 'kvadriliony', 'kvadrilionů'], // 10^24\n 9: ['kvadriliarda', 'kvadriliardy', 'kvadriliard'] // 10^27\n}\n\nconst ZERO = 'nula'\nconst NEGATIVE = 'mínus'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 (masculine, default form).\n * Only used during table construction.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds (irregular)\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens\n parts.push(TEENS[ones])\n } else if (tens >= 2) {\n parts.push(TENS[tens])\n if (ones > 0) {\n parts.push(ONES[ones])\n }\n } else if (ones > 0) {\n parts.push(ONES[ones])\n }\n\n return parts.join(' ')\n}\n\n/**\n * Builds segment word for 0-999 with feminine hundreds.\n * Hundreds use irregular forms (dvě stě, tři sta) but ones remain masculine.\n */\nfunction buildSegmentWithHundreds (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds use the irregular HUNDREDS array (already has \"dvě stě\" etc.)\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones use masculine form\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else if (tens >= 2) {\n parts.push(TENS[tens])\n if (ones > 0) {\n parts.push(ONES[ones]) // masculine\n }\n } else if (ones > 0) {\n parts.push(ONES[ones]) // masculine\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999) - masculine form\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// Precompute all 1000 segment words with hundreds (irregular hundreds forms)\nconst SEGMENTS_WITH_HUNDREDS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_WITH_HUNDREDS[i] = buildSegmentWithHundreds(i)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Czech pluralization: 1 = singular, 2-4 = few, else = many.\n * Teens (11-19) always use \"many\" form.\n *\n * @param {bigint} n - The number\n * @param {string[]} forms - [singular, few, many]\n * @returns {string} The appropriate form\n */\nfunction pluralize (n, forms) {\n if (n === 1n) return forms[0]\n\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n // 2-4, but not 12-14 (teens use \"many\")\n if (lastDigit >= 2n && lastDigit <= 4n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {\n return forms[1]\n }\n\n return forms[2]\n}\n\n/**\n * Gets the decimal separator word based on integer part.\n * celá (0-1), celé (2-4), celých (5+)\n */\nfunction getDecimalSeparator (integerPart) {\n if (integerPart === 0n || integerPart === 1n) {\n return 'celá'\n } else if (integerPart >= 2n && integerPart <= 4n) {\n return 'celé'\n } else {\n return 'celých'\n }\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Czech words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Czech words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = n / 1000n\n const remainder = Number(n % 1000n)\n\n const scaleWord = pluralize(thousands, PLURAL_FORMS[1])\n\n let result\n if (thousands === 1n) {\n // Omit \"one\" before tisíc\n result = scaleWord\n } else {\n result = SEGMENTS[Number(thousands)] + ' ' + scaleWord\n }\n\n if (remainder > 0) {\n // Use form with irregular hundreds (for \"dvě stě\" etc.)\n result += ' ' + SEGMENTS_WITH_HUNDREDS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Czech words\n */\nfunction buildLargeNumberWords (n) {\n // Extract segments using BigInt division (faster than string slicing)\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(temp % 1000n)\n temp = temp / 1000n\n }\n\n // Build result string directly\n let result = ''\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0n) continue\n\n if (result) result += ' '\n\n if (i === 0) {\n // Units segment (no scale word) - use form with irregular hundreds\n result += SEGMENTS_WITH_HUNDREDS[Number(segment)]\n } else {\n // Scale word needed\n const forms = PLURAL_FORMS[i]\n if (forms) {\n const scaleWord = pluralize(segment, forms)\n\n if (segment === 1n) {\n // Omit \"one\" before scale words\n result += scaleWord\n } else {\n // Use masculine form for multiplier before scale words\n result += SEGMENTS[Number(segment)] + ' ' + scaleWord\n }\n } else {\n // Fallback for very large scales without defined forms\n result += SEGMENTS[Number(segment)]\n }\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Czech words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Czech words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Czech words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Czech words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'dvacet jedna'\n * toWords(1000) // 'tisíc'\n * toWords(2000) // 'dva tisíce'\n * toWords(5000) // 'pět tisíc'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n const separator = getDecimalSeparator(integerPart)\n result += ' ' + separator + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Danish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Vigesimal (base-20) tens naming: halvtreds (50), treds (60), etc.\n * - Units-before-tens: \"enogtyve\" (21) = one-and-twenty\n * - Compound thousands: \"ettusind\", \"firetusinde\"\n * - \"og\" conjunction after hundreds and thousands\n * - Long scale for millions+\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'et', 'to', 'tre', 'fire', 'fem', 'seks', 'syv', 'otte', 'ni']\n// \"en\" form used in vigesimal pattern (X og Y) and before millions\nconst ONES_VIGESIMAL = ['', 'en', 'to', 'tre', 'fire', 'fem', 'seks', 'syv', 'otte', 'ni']\n\nconst TEENS = ['ti', 'elleve', 'tolv', 'tretten', 'fjorten', 'femten', 'seksten', 'sytten', 'atten', 'nitten']\n\n// Danish vigesimal tens (base-20 derived names)\nconst TENS = ['', '', 'tyve', 'tredive', 'fyrre', 'halvtreds', 'treds', 'halvfjerds', 'firs', 'halvfems']\n\nconst HUNDRED = 'hundrede'\nconst THOUSAND = 'tusind'\n\nconst ZERO = 'nul'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'komma'\n\n// Long scale: millioner, millarder, billioner, etc.\nconst SCALES = ['millioner', 'millarder', 'billioner', 'billarder', 'trillioner', 'trillarder', 'quadrillioner', 'quadrillarder']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds: \"ethundrede\", \"tohundrede\" (compound, no space)\n if (hundreds > 0) {\n parts.push(ONES[hundreds] + HUNDRED)\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n // Teens\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n // Even tens\n parts.push(TENS[tens])\n } else {\n // Units-before-tens: \"enogtyve\", \"treogfyrre\"\n parts.push(ONES_VIGESIMAL[ones] + 'og' + TENS[tens])\n }\n\n // Combine with \" og \" between hundreds and remainder\n if (parts.length === 2) {\n return parts[0] + ' og ' + parts[1]\n }\n return parts[0] || ''\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Danish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Danish words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Compound thousands: \"ettusind\", \"firetusind\"\n let result = SEGMENTS[thousands] + THOUSAND\n\n if (remainder > 0) {\n // Add 'e' suffix and \" og \" for remainder: \"firetusinde og ...\"\n result += 'e og ' + SEGMENTS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Danish words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words with scale tracking\n // scaleIndex: 0 = units, 1 = thousands, 2 = millions, etc.\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS[segment]\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push({ word: segmentWord, type: 'units' })\n } else if (scaleIndex === 1) {\n // Thousands - compound form\n parts.push({ word: segmentWord + THOUSAND, type: 'thousand' })\n } else {\n // Millions+ - space-separated, use \"en\" for 1\n const scaleWord = SCALES[scaleIndex - 2]\n let numWord = segmentWord\n // \"et\" → \"en\" before millions+\n if (segment === 1) {\n numWord = 'en'\n }\n parts.push({ word: numWord + ' ' + scaleWord, type: 'million' })\n }\n }\n\n scaleIndex--\n }\n\n // Join parts with Danish rules\n return joinDanishParts(parts)\n}\n\n/**\n * Joins parts with Danish spacing rules.\n * - After thousands with remainder: \"tusinde og\"\n * - Millions are space-separated\n *\n * @param {Array} parts - Parts with type metadata\n * @returns {string} Joined string\n */\nfunction joinDanishParts (parts) {\n if (parts.length === 0) return ZERO\n if (parts.length === 1) return parts[0].word\n\n const result = []\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const nextPart = parts[i + 1]\n\n if (part.type === 'thousand' && nextPart && nextPart.type === 'units') {\n // Thousands followed by units: add \"e og\"\n result.push(part.word + 'e og ' + nextPart.word)\n i++ // Skip the units part\n } else if (part.type === 'million') {\n if (result.length > 0) {\n result.push(' ')\n }\n result.push(part.word)\n if (nextPart) {\n result.push(' ')\n }\n } else {\n if (result.length > 0 && !result[result.length - 1].endsWith(' ')) {\n result.push(' ')\n }\n result.push(part.word)\n }\n }\n\n return result.join('')\n}\n\n/**\n * Converts decimal digits to Danish words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Danish words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Danish words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Danish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'enogtyve'\n * toWords(1000) // 'ettusind'\n * toWords(1000000) // 'en millioner'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * German language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * German-specific rules (handled in precomputation):\n * - Inverted tens-ones order: \"einundzwanzig\" (one-and-twenty) for 21-99\n * - Compound words without spaces below million level\n * - Three forms of 1: \"eins\" (standalone), \"ein\" (before hundert/tausend), \"eine\" (before Million+)\n * - Scale pluralization: Million → Millionen, Milliarde → Milliarden\n * - Spaces only around million+ scale words\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\n// Ones words (1-9), index 0 unused\nconst ONES = ['', 'eins', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun']\n\n// \"ein\" form for use before hundert/und\nconst EIN = 'ein'\n\n// Teens (10-19)\nconst TEENS = ['zehn', 'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn']\n\n// Tens (20-90)\nconst TENS = ['', '', 'zwanzig', 'dreißig', 'vierzig', 'fünfzig', 'sechzig', 'siebzig', 'achtzig', 'neunzig']\n\n// Scale words (index 0 = thousand, 1 = million, etc.)\nconst SCALES = ['tausend', 'Million', 'Milliarde', 'Billion', 'Billiarde', 'Trillion', 'Trilliarde', 'Quadrillion', 'Quadrilliarde']\n\n// Pluralized scale words (million+)\nconst SCALES_PLURAL = ['tausend', 'Millionen', 'Milliarden', 'Billionen', 'Billiarden', 'Trillionen', 'Trilliarden', 'Quadrillionen', 'Quadrilliarden']\n\nconst HUNDRED = 'hundert'\nconst ZERO = 'null'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'komma'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 (standalone form, uses \"eins\").\n * German inverts ones and tens: \"einundzwanzig\" = one-and-twenty\n * Only used during table construction.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds: \"ein\" before hundert, not \"eins\"\n if (hundreds > 0) {\n result += (hundreds === 1 ? EIN : ONES[hundreds]) + HUNDRED\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens\n result += TEENS[ones]\n } else if (tens >= 2 && ones > 0) {\n // Inverted: \"einundzwanzig\" (one-and-twenty)\n // Use \"ein\" before \"und\", not \"eins\"\n result += (ones === 1 ? EIN : ONES[ones]) + 'und' + TENS[tens]\n } else if (tens >= 2) {\n // Just tens\n result += TENS[tens]\n } else if (ones > 0) {\n // Just ones (no tens, possibly after hundreds)\n // Use \"eins\" for standalone/after hundreds\n result += ONES[ones]\n }\n\n return result\n}\n\n/**\n * Builds segment word for use before \"tausend\".\n * Uses \"ein\" instead of \"eins\" for 1.\n */\nfunction buildSegmentForThousand (n) {\n if (n === 0) return ''\n if (n === 1) return EIN // \"eintausend\"\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n if (hundreds > 0) {\n result += (hundreds === 1 ? EIN : ONES[hundreds]) + HUNDRED\n }\n\n if (tens === 1) {\n result += TEENS[ones]\n } else if (tens >= 2 && ones > 0) {\n result += (ones === 1 ? EIN : ONES[ones]) + 'und' + TENS[tens]\n } else if (tens >= 2) {\n result += TENS[tens]\n } else if (ones > 0 && hundreds > 0) {\n // After hundreds, ones 1 stays \"eins\" when not followed by scale\n // But we're going to tausend, so this path won't hit for n=1\n result += ONES[ones]\n } else if (ones > 0) {\n result += ONES[ones]\n }\n\n return result\n}\n\n// Precompute all 1000 segment words (0-999) - standalone form\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// Precompute all 1000 segment words for thousand context\nconst SEGMENTS_THOUSAND = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_THOUSAND[i] = buildSegmentForThousand(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to German words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} German words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Compound: \"eintausendzweihundert\" (no spaces)\n let result = SEGMENTS_THOUSAND[thousands] + SCALES[0]\n\n if (remainder > 0) {\n result += SEGMENTS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} German words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n // Units segment (no scale word)\n parts.push({ words: SEGMENTS[segment], isScale: false, scaleLevel: 0 })\n } else if (scaleIndex === 1) {\n // Thousands: compound without space\n const segWords = SEGMENTS_THOUSAND[segment]\n parts.push({ words: segWords + SCALES[0], isScale: false, scaleLevel: 1 })\n } else {\n // Million+ : space around scale word\n let segWords\n if (segment === 1) {\n segWords = 'eine' // \"eine Million\"\n } else {\n segWords = SEGMENTS[segment]\n }\n const scaleWord = segment === 1 ? SCALES[scaleIndex - 1] : SCALES_PLURAL[scaleIndex - 1]\n parts.push({ words: segWords, isScale: false, scaleLevel: scaleIndex })\n parts.push({ words: scaleWord, isScale: true, scaleLevel: scaleIndex })\n }\n }\n\n scaleIndex--\n }\n\n // Join with German spacing rules: space around million+ scale words\n return joinGermanParts(parts)\n}\n\n/**\n * Joins parts with German spacing rules.\n * Spaces only around million+ scale words.\n *\n * @param {Array} parts - Parts with metadata\n * @returns {string} Joined string\n */\nfunction joinGermanParts (parts) {\n if (parts.length === 0) return ZERO\n\n let result = ''\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const prevPart = i > 0 ? parts[i - 1] : null\n\n // Add space before if:\n // - Current is a million+ scale word\n // - Previous was a million+ scale word\n if (i > 0) {\n const needsSpace = part.isScale || (prevPart && prevPart.isScale)\n if (needsSpace) {\n result += ' '\n }\n }\n\n result += part.words\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to German words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} German words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to German words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in German words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'einundzwanzig'\n * toWords(1000) // 'eintausend'\n * toWords(1000000) // 'eine Million'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Greek language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Space-separated number composition\n * - Implicit \"one\" (ένα) omission before scale words\n * - Irregular hundreds (διακόσια, τριακόσια, etc.)\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'ένα', 'δύο', 'τρία', 'τέσσερα', 'πέντε', 'έξι', 'επτά', 'οκτώ', 'εννέα']\n\nconst TEENS = ['δέκα', 'έντεκα', 'δώδεκα', 'δεκατρία', 'δεκατέσσερα', 'δεκαπέντε', 'δεκαέξι', 'δεκαεπτά', 'δεκαοκτώ', 'δεκαεννέα']\n\nconst TENS = ['', '', 'είκοσι', 'τριάντα', 'σαράντα', 'πενήντα', 'εξήντα', 'εβδομήντα', 'ογδόντα', 'ενενήντα']\n\n// Greek has irregular hundreds\nconst HUNDREDS = ['', 'εκατό', 'διακόσια', 'τριακόσια', 'τετρακόσια', 'πεντακόσια', 'εξακόσια', 'επτακόσια', 'οκτακόσια', 'εννιακόσια']\n\nconst THOUSAND = 'χίλια'\n\nconst ZERO = 'μηδέν'\nconst NEGATIVE = 'μείον'\nconst DECIMAL_SEP = 'κόμμα'\n\n// Short scale\nconst SCALES = ['εκατομμύριο', 'δισεκατομμύριο', 'τρισεκατομμύριο']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds (irregular forms)\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n parts.push(TENS[tens])\n } else {\n parts.push(TENS[tens] + ' ' + ONES[ones])\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Greek words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Greek words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Omit \"ένα\" before χίλια\n let result\n if (thousands === 1) {\n result = THOUSAND\n } else {\n result = SEGMENTS[thousands] + ' ' + THOUSAND\n }\n\n if (remainder > 0) {\n result += ' ' + SEGMENTS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Greek words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS[segment]\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push(segmentWord)\n } else if (scaleIndex === 1) {\n // Thousands - omit \"ένα\" before χίλια\n if (segment === 1) {\n parts.push(THOUSAND)\n } else {\n parts.push(segmentWord + ' ' + THOUSAND)\n }\n } else {\n // Millions+ - omit \"ένα\" before scale words\n const scaleWord = SCALES[scaleIndex - 2]\n if (segment === 1) {\n parts.push(scaleWord)\n } else {\n parts.push(segmentWord + ' ' + scaleWord)\n }\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts decimal digits to Greek words (per-digit).\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Greek words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n const parts = []\n\n for (const digit of decimalPart) {\n const d = parseInt(digit, 10)\n if (d === 0) {\n parts.push(ZERO)\n } else {\n parts.push(ONES[d])\n }\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts a numeric value to Greek words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Greek words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'είκοσι ένα'\n * toWords(1000) // 'χίλια'\n * toWords('3.14') // 'τρία κόμμα ένα τέσσερα'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * English language converter - Functional Implementation v2\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * English-specific rules (handled in precomputation):\n * - \"and\" after hundreds: \"one hundred and twenty-three\"\n * - Hyphenated tens-ones: \"twenty-one\", \"forty-two\"\n * - \"and\" before final segment when following scale word\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']\nconst TEENS = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']\nconst TENS = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']\n\nconst SCALES = ['thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion']\n\nconst HUNDRED = 'hundred'\nconst ZERO = 'zero'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'point'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Returns object with word and whether it contains \"hundred\" (for \"and\" logic).\n */\nfunction buildSegment (n) {\n if (n === 0) return { word: '', hasHundred: false }\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n let hasHundred = false\n\n // Hundreds\n if (hundreds > 0) {\n result = ONES[hundreds] + ' ' + HUNDRED\n hasHundred = true\n }\n\n // Tens and ones\n let tensOnes = ''\n if (tens === 1) {\n tensOnes = TEENS[ones]\n } else if (tens >= 2) {\n if (ones > 0) {\n tensOnes = TENS[tens] + '-' + ONES[ones]\n } else {\n tensOnes = TENS[tens]\n }\n } else if (ones > 0) {\n tensOnes = ONES[ones]\n }\n\n // Combine with \"and\" after hundreds\n if (result && tensOnes) {\n return { word: result + ' and ' + tensOnes, hasHundred: true }\n }\n\n return { word: result || tensOnes, hasHundred }\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_HAS_HUNDRED = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n SEGMENTS_HAS_HUNDRED[i] = result.hasHundred\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to English words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} English words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result = SEGMENTS[thousands] + ' ' + SCALES[0]\n\n if (remainder > 0) {\n const remainderWord = SEGMENTS[remainder]\n // Insert \"and\" if remainder doesn't have hundred\n if (!SEGMENTS_HAS_HUNDRED[remainder]) {\n result += ' and ' + remainderWord\n } else {\n result += ' ' + remainderWord\n }\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} English words\n */\nfunction buildLargeNumberWords (n) {\n // Extract segments using BigInt division (faster than string slicing)\n // Segments are stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Find the first (smallest index) non-zero segment - this is processed last\n let firstNonZeroIdx = -1\n for (let i = 0; i < segments.length; i++) {\n if (segments[i] !== 0) {\n firstNonZeroIdx = i\n break\n }\n }\n\n // Build result string directly (avoids intermediate object allocations)\n // Process from most-significant (end) to least-significant (start)\n let result = ''\n let prevWasScale = false\n\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i]\n if (segment === 0) continue\n\n const segmentWord = SEGMENTS[segment]\n const hasHundred = SEGMENTS_HAS_HUNDRED[segment]\n const isLastSegment = (i === firstNonZeroIdx)\n\n // Add \"and\" only before FINAL segment if it follows scale and doesn't have hundred\n if (result && isLastSegment && prevWasScale && !hasHundred) {\n result += ' and'\n }\n\n // Add segment word\n if (result) result += ' '\n result += segmentWord\n\n // Add scale word (i=0 is units, i=1 is thousands, etc.)\n if (i > 0) {\n result += ' ' + SCALES[i - 1]\n prevWasScale = true\n } else {\n prevWasScale = false\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to English words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} English words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to English words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in English words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // 'forty-two'\n * toWords(-3.14) // 'minus three point one four'\n * toWords('1000000') // 'one million'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Spanish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Spanish-specific rules (handled in precomputation):\n * - Gender agreement: uno/una, veintiuno/veintiuna, hundreds\n * - Special twenties: veinte, veintiuno, veintidós, ... veintinueve\n * - \"y\" conjunction: treinta y uno (only 30-99 with ones)\n * - \"cien\" for exact 100, \"ciento/cienta\" otherwise\n * - Irregular hundreds: quinientos, setecientos, novecientos\n * - Compound long scale: millón, mil millones, billón, mil billones\n * - \"un\" before millón (not \"uno\"), omit before mil\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES_MASC = ['', 'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve']\nconst ONES_FEM = ['', 'una', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve']\n\nconst TEENS = ['diez', 'once', 'doce', 'trece', 'catorce', 'quince', 'dieciseis', 'diecisiete', 'dieciocho', 'diecinueve']\n\n// 20-29 have special compound forms\nconst TWENTIES_MASC = ['veinte', 'veintiuno', 'veintidós', 'veintitrés', 'veinticuatro', 'veinticinco', 'veintiséis', 'veintisiete', 'veintiocho', 'veintinueve']\nconst TWENTIES_FEM = ['veinte', 'veintiuna', 'veintidós', 'veintitrés', 'veinticuatro', 'veinticinco', 'veintiséis', 'veintisiete', 'veintiocho', 'veintinueve']\n\nconst TENS = ['', '', '', 'treinta', 'cuarenta', 'cincuenta', 'sesenta', 'setenta', 'ochenta', 'noventa']\n\n// Irregular hundreds\nconst HUNDREDS_MASC = ['', 'ciento', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos', 'seiscientos', 'setecientos', 'ochocientos', 'novecientos']\nconst HUNDREDS_FEM = ['', 'cienta', 'doscientas', 'trescientas', 'cuatrocientas', 'quinientas', 'seiscientas', 'setecientas', 'ochocientas', 'novecientas']\n\n// Scale words (compound long scale)\nconst SCALES = ['millón', 'billón', 'trillón', 'cuatrillón']\nconst SCALES_PLURAL = ['millones', 'billones', 'trillones', 'cuatrillones']\n\nconst THOUSAND = 'mil'\nconst ZERO = 'cero'\nconst NEGATIVE = 'menos'\nconst DECIMAL_SEP = 'punto'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * @param {number} n - Segment value\n * @param {boolean} feminine - Use feminine forms\n * @returns {string} Spanish word\n */\nfunction buildSegment (n, feminine) {\n if (n === 0) return ''\n\n // Special case: exact 100 is \"cien\" (no gender)\n if (n === 100) return 'cien'\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n const tensOnes = n % 100\n\n const parts = []\n\n // Hundreds\n if (hundreds > 0) {\n const hundredsArr = feminine ? HUNDREDS_FEM : HUNDREDS_MASC\n parts.push(hundredsArr[hundreds])\n }\n\n // Tens and ones\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit\n const onesArr = feminine ? ONES_FEM : ONES_MASC\n parts.push(onesArr[tensOnes])\n } else if (tensOnes < 20) {\n // 10-19: teens\n parts.push(TEENS[ones])\n } else if (tensOnes < 30) {\n // 20-29: special twenties\n const twentiesArr = feminine ? TWENTIES_FEM : TWENTIES_MASC\n parts.push(twentiesArr[ones])\n } else {\n // 30-99: tens y ones\n if (ones === 0) {\n parts.push(TENS[tens])\n } else {\n const onesArr = feminine ? ONES_FEM : ONES_MASC\n parts.push(TENS[tens] + ' y ' + onesArr[ones])\n }\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999) for masculine\nconst SEGMENTS_MASC = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_MASC[i] = buildSegment(i, false)\n}\n\n// Precompute all 1000 segment words (0-999) for feminine\nconst SEGMENTS_FEM = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_FEM[i] = buildSegment(i, true)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Gets scale word for Spanish compound long scale.\n *\n * @param {number} scaleIndex - Scale level (1 = thousand, 2 = million, etc.)\n * @param {bigint} segment - Segment value for pluralization\n * @returns {string} Scale word\n */\nfunction getScaleWord (scaleIndex, segment) {\n if (scaleIndex === 1) return THOUSAND\n\n // Even indices (2, 4, 6, 8): millón, billón, trillón, cuatrillón\n // Odd indices > 1 (3, 5, 7): mil millones, mil billones, mil trillones\n if (scaleIndex % 2 === 0) {\n const arrayIndex = (scaleIndex / 2) - 1\n const baseWord = SCALES[arrayIndex]\n if (!baseWord) return ''\n return segment > 1n ? SCALES_PLURAL[arrayIndex] : baseWord\n } else {\n // Compound: \"mil millones\" pattern\n const arrayIndex = ((scaleIndex - 1) / 2) - 1\n const pluralWord = SCALES_PLURAL[arrayIndex]\n if (!pluralWord) return THOUSAND\n return THOUSAND + ' ' + pluralWord\n }\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Spanish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {boolean} feminine - Use feminine forms\n * @returns {string} Spanish words\n */\nfunction integerToWords (n, feminine) {\n if (n === 0n) return ZERO\n\n const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return segments[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n // \"mil\" not \"uno mil\"\n result = THOUSAND\n } else {\n // Use masculine for thousands segment, but check for \"uno\" → omit before mil\n const thousandsWord = SEGMENTS_MASC[thousands]\n // \"uno mil\" → \"mil\" (handled in joinSegments equivalent)\n if (thousandsWord === 'uno' || thousandsWord === 'una') {\n result = THOUSAND\n } else {\n result = thousandsWord + ' ' + THOUSAND\n }\n }\n\n if (remainder > 0) {\n result += ' ' + segments[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n, feminine)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @param {boolean} feminine - Use feminine forms\n * @returns {string} Spanish words\n */\nfunction buildLargeNumberWords (n, feminine) {\n // Extract segments using BigInt division (faster than string slicing)\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(temp % 1000n)\n temp = temp / 1000n\n }\n\n const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC\n\n // Build result string directly\n let result = ''\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0n) continue\n\n const scaleWord = i > 0 ? getScaleWord(i, segment) : ''\n\n if (result) result += ' '\n\n if (i === 0) {\n // Units segment\n result += segments[Number(segment)]\n } else if (i === 1) {\n // Thousands: omit \"uno\" before mil\n if (segment === 1n) {\n result += THOUSAND\n } else {\n result += SEGMENTS_MASC[Number(segment)] + ' ' + scaleWord\n }\n } else if (i % 2 === 1) {\n // Odd scale indices (3, 5, 7): \"mil millones\", \"mil billones\", etc.\n // Omit \"uno\" before these compound scales\n if (segment === 1n) {\n result += scaleWord\n } else {\n result += SEGMENTS_MASC[Number(segment)] + ' ' + scaleWord\n }\n } else {\n // Even scale indices (2, 4, 6): millón, billón, trillón\n if (segment === 1n) {\n // \"un millón\" not \"uno millón\"\n result += 'un ' + scaleWord\n } else {\n // Use masculine for scale segment\n result += SEGMENTS_MASC[Number(segment)] + ' ' + scaleWord\n }\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Spanish words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {boolean} feminine - Use feminine forms\n * @returns {string} Spanish words for decimal part\n */\nfunction decimalPartToWords (decimalPart, feminine) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), feminine)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Spanish words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Spanish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'veintiuno'\n * toWords(21, {gender: 'feminine'}) // 'veintiuna'\n * toWords(1000000) // 'un millón'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n const feminine = options.gender === 'feminine'\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, feminine)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, feminine)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Persian language converter - Functional Implementation\n *\n * Self-contained converter using recursive decomposition.\n *\n * Key features:\n * - \"و\" (and) conjunction for compound numbers\n * - Omit \"یک\" (one) before thousand\n * - Pre-composed hundreds (دویست, سيصد, etc.)\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = { 1: 'یک', 2: 'دو', 3: 'سه', 4: 'چهار', 5: 'پنج', 6: 'شش', 7: 'هفت', 8: 'هشت', 9: 'نه' }\nconst TEENS = { 10: 'ده', 11: 'یازده', 12: 'دوازده', 13: 'سیزده', 14: 'چهارده', 15: 'پانزده', 16: 'شانزده', 17: 'هفده', 18: 'هجده', 19: 'نوزده' }\nconst TENS = { 20: 'بیست', 30: 'سی', 40: 'چهل', 50: 'پنجاه', 60: 'شصت', 70: 'هفتاد', 80: 'هشتاد', 90: 'نود' }\nconst HUNDREDS = { 100: 'صد', 200: 'دویست', 300: 'سيصد', 400: 'چهار صد', 500: 'پانصد', 600: 'ششصد', 700: 'هفتصد', 800: 'هشتصد', 900: 'نهصد' }\n\nconst THOUSAND = 'هزار'\nconst MILLION = 'میلیون'\n\nconst ZERO = 'صفر'\nconst NEGATIVE = 'منفى'\nconst DECIMAL_SEP = 'ممیّز'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // 1-9\n if (n <= 9n) {\n return ONES[Number(n)]\n }\n\n // 10-19\n if (n <= 19n) {\n return TEENS[Number(n)]\n }\n\n // 20-99\n if (n < 100n) {\n const ones = n % 10n\n const tens = n - ones\n if (ones === 0n) {\n return TENS[Number(tens)]\n }\n return `${TENS[Number(tens)]} و ${ONES[Number(ones)]}`\n }\n\n // 100-999\n if (n < 1000n) {\n const hundreds = 100n * (n / 100n)\n const remainder = n - hundreds\n if (remainder === 0n) {\n return HUNDREDS[Number(hundreds)]\n }\n return `${HUNDREDS[Number(hundreds)]} و ${integerToWords(remainder)}`\n }\n\n // 1000-999999\n if (n < 1_000_000n) {\n const thousandMultiplier = n / 1000n\n // Persian omits \"one\" before thousand: 1000 is just \"هزار\", not \"یک هزار\"\n const thousandPrefix = thousandMultiplier === 1n\n ? ''\n : integerToWords(thousandMultiplier) + ' '\n const remainder = n % 1000n\n const suffix = remainder === 0n ? '' : ' ' + integerToWords(remainder)\n return `${thousandPrefix}${THOUSAND}${suffix}`\n }\n\n // 1000000+\n const millionMultiplier = n / 1_000_000n\n const millionPrefix = integerToWords(millionMultiplier) + ' ' + MILLION\n const remainder = n % 1_000_000n\n const suffix = remainder === 0n ? '' : ' و ' + integerToWords(remainder)\n return `${millionPrefix}${suffix}`\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Persian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Persian words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Finnish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Compound tens+ones without spaces: \"kaksikymmentäyksi\" (21)\n * - Teens with \"-toista\" suffix\n * - Omit \"yksi\" before sata/tuhat but keep before miljoona+\n * - Long scale: miljoona, miljardi, biljoona\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'yksi', 'kaksi', 'kolme', 'neljä', 'viisi', 'kuusi', 'seitsemän', 'kahdeksan', 'yhdeksän']\n\nconst TEENS = ['kymmenen', 'yksitoista', 'kaksitoista', 'kolmetoista', 'neljätoista', 'viisitoista', 'kuusitoista', 'seitsemäntoista', 'kahdeksantoista', 'yhdeksäntoista']\n\n// Tens use \"kymmentä\" suffix\nconst TENS = ['', '', 'kaksikymmentä', 'kolmekymmentä', 'neljäkymmentä', 'viisikymmentä', 'kuusikymmentä', 'seitsemänkymmentä', 'kahdeksankymmentä', 'yhdeksänkymmentä']\n\nconst HUNDRED = 'sata'\nconst THOUSAND = 'tuhat'\n\nconst ZERO = 'nolla'\nconst NEGATIVE = 'miinus'\nconst DECIMAL_SEP = 'pilkku'\n\n// Long scale\nconst SCALES = ['miljoona', 'miljardi', 'biljoona', 'triljoona']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Omits \"yksi\" before \"sata\" (hundred).\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - omit \"yksi\" before sata\n if (hundreds > 0) {\n if (hundreds === 1) {\n parts.push(HUNDRED)\n } else {\n parts.push(ONES[hundreds] + ' ' + HUNDRED)\n }\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n parts.push(TENS[tens])\n } else {\n // Compound: \"kaksikymmentäyksi\" (no space)\n parts.push(TENS[tens] + ONES[ones])\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Finnish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Finnish words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Omit \"yksi\" before tuhat\n let result\n if (thousands === 1) {\n result = THOUSAND\n } else {\n result = SEGMENTS[thousands] + ' ' + THOUSAND\n }\n\n if (remainder > 0) {\n result += ' ' + SEGMENTS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Finnish words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS[segment]\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push(segmentWord)\n } else if (scaleIndex === 1) {\n // Thousands - omit \"yksi\" before tuhat\n if (segment === 1) {\n parts.push(THOUSAND)\n } else {\n parts.push(segmentWord + ' ' + THOUSAND)\n }\n } else {\n // Millions+ - keep \"yksi\" before scale words\n const scaleWord = SCALES[scaleIndex - 2]\n parts.push(segmentWord + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts decimal digits to Finnish words (per-digit).\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Finnish words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n const parts = []\n\n for (const digit of decimalPart) {\n const d = parseInt(digit, 10)\n if (d === 0) {\n parts.push(ZERO)\n } else {\n parts.push(ONES[d])\n }\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts a numeric value to Finnish words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Finnish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'kaksikymmentäyksi'\n * toWords(1000) // 'tuhat'\n * toWords('3.14') // 'kolme pilkku yksi neljä'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Filipino language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - Linker \"ng\" after vowels: \"isang daang\" (100)\n * - Linker \" na \" after consonants: \"siyam na daang\" (900)\n * - Special tens with linker: \"limampung anim\" (56)\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'isa', 'dalawa', 'tatlo', 'apat', 'lima', 'anim', 'pito', 'walo', 'siyam']\nconst TEENS = ['sampu', 'labinisa', 'labindalawa', 'labintatlo', 'labinapat', 'labinlima', 'labinanum', 'labimpito', 'labingwalo', 'labinsiyam']\nconst TENS = ['', '', 'dalawampu', 'tatlumpu', 'apatnapu', 'limampu', 'animnapu', 'pitumpu', 'walumpu', 'siyamnapu']\n\n// Scale words include linker (end with \"ng\")\nconst HUNDRED = 'daang'\nconst THOUSAND = 'libong'\n\nconst ZERO = 'zero'\nconst NEGATIVE = 'negatibo'\nconst DECIMAL_SEP = 'punto'\n\n// Short scale with linker\nconst SCALE_WORDS = ['', THOUSAND, 'milyong', 'bilyong', 'trilyong']\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nconst VOWELS = ['a', 'e', 'i', 'o', 'u']\n\nfunction addLinker (word) {\n const lastChar = word[word.length - 1]\n if (VOWELS.includes(lastChar)) {\n return word + 'ng'\n }\n return word + ' na'\n}\n\n// ============================================================================\n// Precomputed Lookup Table\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds: \"isang daan\", \"dalawang daan\", \"siyam na daan\"\n if (hundredsDigit > 0) {\n const hundredPrefix = addLinker(ONES[hundredsDigit])\n parts.push(hundredPrefix + ' ' + HUNDRED)\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n // Teens (10-19)\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n // Even tens (20, 30, 40, etc.)\n parts.push(TENS[tensDigit])\n } else {\n // Tens + ones\n // limampu (50) gets special linker: \"limampung anim\" (56)\n if (tensDigit === 5) {\n parts.push(TENS[tensDigit] + 'ng ' + ONES[ones])\n } else {\n parts.push(TENS[tensDigit] + ' ' + ONES[ones])\n }\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n/**\n * Builds segment with linker added to last word (for use before scale words).\n */\nfunction buildSegmentWithLinker (n) {\n const segmentWord = SEGMENTS[n]\n if (!segmentWord) return ''\n\n // Find the last space to get the last word\n const lastSpaceIdx = segmentWord.lastIndexOf(' ')\n if (lastSpaceIdx === -1) {\n // Single word\n const lastChar = segmentWord[segmentWord.length - 1]\n if (lastChar === 'g' && segmentWord.endsWith('ng')) {\n return segmentWord // Already has linker\n }\n return addLinker(segmentWord)\n }\n\n // Multi-word: add linker to last word\n const prefix = segmentWord.slice(0, lastSpaceIdx + 1)\n const lastWord = segmentWord.slice(lastSpaceIdx + 1)\n\n if (lastWord.endsWith('ng')) {\n return segmentWord // Already has linker\n }\n return prefix + addLinker(lastWord)\n}\n\n// Precompute segments with linker for scale word usage\nconst SEGMENTS_WITH_LINKER = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_WITH_LINKER[i] = buildSegmentWithLinker(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for large numbers using BigInt division.\n * @param {bigint} n - Number >= 1000\n * @returns {string} Filipino words\n */\nfunction buildLargeNumberWords (n) {\n // Extract segments using BigInt division (faster than string slicing)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Build result string directly\n let result = ''\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0) continue\n\n const scaleWord = SCALE_WORDS[i] || ''\n\n if (result) result += ' '\n\n if (i === 0) {\n result += SEGMENTS[segment]\n } else {\n // Add linker to segment before scale word\n const segmentWord = SEGMENTS_WITH_LINKER[segment]\n result += segmentWord + ' ' + scaleWord\n }\n }\n\n return result\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Filipino words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Filipino words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * French language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * French-specific rules (handled in precomputation):\n * - Vigesimal patterns: 70 = soixante-dix, 80 = quatre-vingts, 90 = quatre-vingt-dix\n * - \"et\" conjunction: vingt et un (21), soixante et onze (71), but NOT quatre-vingt-un\n * - Pluralization: \"cents\" loses 's' when followed by more digits\n * - Long scale with -ard forms: milliard, billiard, trilliard\n * - Omit \"un\" before mille\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf']\nconst TEENS = ['dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf']\nconst TENS = ['', '', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante']\n\n// Scale words (even indices: million, billion, trillion, quadrillion)\nconst SCALES = ['million', 'billion', 'trillion', 'quadrillion']\nconst SCALES_ARD = ['milliard', 'billiard', 'trilliard', 'quadrilliard']\n\nconst THOUSAND = 'mille'\nconst HUNDRED = 'cent'\nconst ZERO = 'zéro'\nconst NEGATIVE = 'moins'\nconst DECIMAL_SEP = 'virgule'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Returns object with { word, endsWithCents, endsWithVingts } for pluralization handling.\n */\nfunction buildSegment (n) {\n if (n === 0) return { word: '', endsWithCents: false, endsWithVingts: false }\n\n const tensOnes = n % 100\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n let endsWithCents = false\n let endsWithVingts = false\n\n // Hundreds\n if (hundreds > 0) {\n if (hundreds === 1) {\n if (tensOnes === 0) {\n parts.push(HUNDRED)\n } else {\n parts.push(HUNDRED)\n }\n } else {\n if (tensOnes === 0) {\n // \"deux cents\", \"trois cents\" (with 's')\n parts.push(ONES[hundreds] + ' ' + HUNDRED + 's')\n endsWithCents = true\n } else {\n // \"deux cent\", \"trois cent\" (no 's' when followed by more)\n parts.push(ONES[hundreds] + ' ' + HUNDRED)\n }\n }\n }\n\n // Tens and ones - vigesimal pattern\n if (tensOnes === 0) {\n // Just hundreds, nothing more\n } else if (tensOnes < 10) {\n // Single digit\n parts.push(ONES[tensOnes])\n } else if (tensOnes < 17) {\n // 10-16: regular teens\n parts.push(TEENS[tensOnes - 10])\n } else if (tensOnes < 20) {\n // 17-19: dix-sept, dix-huit, dix-neuf\n parts.push(TEENS[tensOnes - 10])\n } else if (tensOnes < 70) {\n // 20-69: standard tens + ones\n const t = Math.floor(tensOnes / 10)\n const o = tensOnes % 10\n if (o === 0) {\n parts.push(TENS[t])\n } else if (o === 1) {\n // \"et un\" for 21, 31, 41, 51, 61\n parts.push(TENS[t] + ' et ' + ONES[1])\n } else {\n parts.push(TENS[t] + '-' + ONES[o])\n }\n } else if (tensOnes < 80) {\n // 70-79: soixante-dix, soixante et onze, soixante-douze...\n const remainder = tensOnes - 60\n if (remainder === 11) {\n // 71: soixante et onze\n parts.push('soixante et onze')\n } else {\n // 70, 72-79: soixante-dix, soixante-douze...\n parts.push('soixante-' + TEENS[remainder - 10])\n }\n } else if (tensOnes === 80) {\n // 80: quatre-vingts (with 's')\n parts.push('quatre-vingts')\n endsWithVingts = true\n } else if (tensOnes < 100) {\n // 81-99: quatre-vingt-un, quatre-vingt-dix...\n const remainder = tensOnes - 80\n if (remainder < 10) {\n // 81-89\n parts.push('quatre-vingt-' + ONES[remainder])\n } else {\n // 90-99\n parts.push('quatre-vingt-' + TEENS[remainder - 10])\n }\n }\n\n // Join parts with space (between hundreds and rest)\n return { word: parts.join(' '), endsWithCents, endsWithVingts }\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_ENDS_CENTS = new Array(1000)\nconst SEGMENTS_ENDS_VINGTS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n SEGMENTS_ENDS_CENTS[i] = result.endsWithCents\n SEGMENTS_ENDS_VINGTS[i] = result.endsWithVingts\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Gets scale word for French long scale with -ard pattern.\n *\n * @param {number} scaleIndex - Scale level (1 = thousand, 2 = million, etc.)\n * @param {bigint} segment - Segment value for pluralization\n * @returns {string} Scale word\n */\nfunction getScaleWord (scaleIndex, segment) {\n if (scaleIndex === 1) return THOUSAND\n\n // Even indices (2, 4, 6, 8): million, billion, trillion, quadrillion\n // Odd indices > 1 (3, 5, 7, 9): milliard, billiard, trilliard, quadrilliard\n if (scaleIndex % 2 === 0) {\n const arrayIndex = (scaleIndex / 2) - 1\n const baseWord = SCALES[arrayIndex]\n if (!baseWord) return ''\n return segment > 1n ? baseWord + 's' : baseWord\n } else {\n const arrayIndex = ((scaleIndex - 1) / 2) - 1\n const ardWord = SCALES_ARD[arrayIndex]\n if (!ardWord) return THOUSAND\n return segment > 1n ? ardWord + 's' : ardWord\n }\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to French words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {boolean} withHyphen - Whether to use hyphen separators\n * @returns {string} French words\n */\nfunction integerToWords (n, withHyphen = false) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n const word = SEGMENTS[Number(n)]\n return withHyphen ? word.replace(/ /g, '-') : word\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n // \"mille\" not \"un mille\"\n result = THOUSAND\n } else {\n // Check if segment ends with \"cents\" or \"vingts\" - need to strip 's' before mille\n let thousandsWord = SEGMENTS[thousands]\n if (SEGMENTS_ENDS_CENTS[thousands] || SEGMENTS_ENDS_VINGTS[thousands]) {\n thousandsWord = thousandsWord.slice(0, -1) // Remove trailing 's'\n }\n result = thousandsWord + (withHyphen ? '-' : ' ') + THOUSAND\n }\n\n if (remainder > 0) {\n result += (withHyphen ? '-' : ' ') + SEGMENTS[remainder]\n }\n\n if (withHyphen) {\n result = result.replace(/ /g, '-')\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n, withHyphen)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @param {boolean} withHyphen - Whether to use hyphen separators\n * @returns {string} French words\n */\nfunction buildLargeNumberWords (n, withHyphen) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = scaleIndex > 0 ? getScaleWord(scaleIndex, BigInt(segment)) : ''\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push(SEGMENTS[segment])\n } else if (scaleIndex === 1) {\n // Thousands: \"mille\" not \"un mille\"\n if (segment === 1) {\n parts.push(THOUSAND)\n } else {\n let segWords = SEGMENTS[segment]\n // Strip 's' from cents/vingts before mille\n if (SEGMENTS_ENDS_CENTS[segment] || SEGMENTS_ENDS_VINGTS[segment]) {\n segWords = segWords.slice(0, -1)\n }\n parts.push(segWords)\n parts.push(scaleWord)\n }\n } else {\n // Million and above\n parts.push(SEGMENTS[segment])\n parts.push(scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n const sep = withHyphen ? '-' : ' '\n let result = parts.join(sep)\n\n if (withHyphen) {\n result = result.replace(/ /g, '-')\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to French words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {boolean} withHyphen - Whether to use hyphen separators\n * @returns {string} French words for decimal part\n */\nfunction decimalPartToWords (decimalPart, withHyphen) {\n let result = ''\n const sep = withHyphen ? '-' : ' '\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += sep\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += sep\n result += integerToWords(BigInt(remainder), withHyphen)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to French words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.withHyphenSeparator=false] - Use hyphens between all words\n * @returns {string} The number in French words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'vingt et un'\n * toWords(80) // 'quatre-vingts'\n * toWords(1000000) // 'un million'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n const withHyphen = options.withHyphenSeparator || false\n\n let result = ''\n const sep = withHyphen ? '-' : ' '\n\n if (isNegative) {\n result = NEGATIVE + sep\n }\n\n result += integerToWords(integerPart, withHyphen)\n\n if (decimalPart) {\n result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, withHyphen)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * French (Belgium) language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Belgian French differences from standard French:\n * - septante (70) instead of soixante-dix\n * - nonante (90) instead of quatre-vingt-dix\n * - Keeps quatre-vingts (80) like standard French\n * - Uses \"septante et un\" (71), \"nonante et un\" (91)\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf']\nconst TEENS = ['dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf']\nconst TENS = ['', '', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'septante', 'quatre-vingt', 'nonante']\n\n// Scale words (long scale with -ard forms)\nconst SCALES = ['million', 'billion', 'trillion', 'quadrillion']\nconst SCALES_ARD = ['milliard', 'billiard', 'trilliard', 'quadrilliard']\n\nconst THOUSAND = 'mille'\nconst HUNDRED = 'cent'\nconst ZERO = 'zéro'\nconst NEGATIVE = 'moins'\nconst DECIMAL_SEP = 'virgule'\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return { word: '', endsWithCents: false, endsWithVingts: false }\n\n const tensOnes = n % 100\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n let endsWithCents = false\n let endsWithVingts = false\n\n // Hundreds\n if (hundreds > 0) {\n if (hundreds === 1) {\n parts.push(HUNDRED)\n } else {\n if (tensOnes === 0) {\n parts.push(ONES[hundreds] + ' ' + HUNDRED + 's')\n endsWithCents = true\n } else {\n parts.push(ONES[hundreds] + ' ' + HUNDRED)\n }\n }\n }\n\n // Tens and ones - Belgian pattern\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[tensOnes])\n } else if (tensOnes < 17) {\n parts.push(TEENS[tensOnes - 10])\n } else if (tensOnes < 20) {\n parts.push(TEENS[tensOnes - 10])\n } else if (tensOnes < 70) {\n // 20-69: standard pattern\n const t = Math.floor(tensOnes / 10)\n const o = tensOnes % 10\n if (o === 0) {\n parts.push(TENS[t])\n } else if (o === 1) {\n parts.push(TENS[t] + ' et ' + ONES[1])\n } else {\n parts.push(TENS[t] + '-' + ONES[o])\n }\n } else if (tensOnes < 80) {\n // 70-79: septante pattern (Belgian)\n const o = tensOnes % 10\n if (o === 0) {\n parts.push('septante')\n } else if (o === 1) {\n parts.push('septante et ' + ONES[1])\n } else {\n parts.push('septante-' + ONES[o])\n }\n } else if (tensOnes === 80) {\n // 80: quatre-vingts (same as standard)\n parts.push('quatre-vingts')\n endsWithVingts = true\n } else if (tensOnes < 90) {\n // 81-89: quatre-vingt-X (same as standard)\n const remainder = tensOnes - 80\n parts.push('quatre-vingt-' + ONES[remainder])\n } else {\n // 90-99: nonante pattern (Belgian)\n const o = tensOnes % 10\n if (o === 0) {\n parts.push('nonante')\n } else if (o === 1) {\n parts.push('nonante et ' + ONES[1])\n } else {\n parts.push('nonante-' + ONES[o])\n }\n }\n\n return { word: parts.join(' '), endsWithCents, endsWithVingts }\n}\n\n// Precompute all 1000 segment words\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_ENDS_CENTS = new Array(1000)\nconst SEGMENTS_ENDS_VINGTS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n SEGMENTS_ENDS_CENTS[i] = result.endsWithCents\n SEGMENTS_ENDS_VINGTS[i] = result.endsWithVingts\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction getScaleWord (scaleIndex, segment) {\n if (scaleIndex === 1) return THOUSAND\n\n if (scaleIndex % 2 === 0) {\n const arrayIndex = (scaleIndex / 2) - 1\n const baseWord = SCALES[arrayIndex]\n if (!baseWord) return ''\n return segment > 1n ? baseWord + 's' : baseWord\n } else {\n const arrayIndex = ((scaleIndex - 1) / 2) - 1\n const ardWord = SCALES_ARD[arrayIndex]\n if (!ardWord) return THOUSAND\n return segment > 1n ? ardWord + 's' : ardWord\n }\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, withHyphen = false) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n const word = SEGMENTS[Number(n)]\n return withHyphen ? word.replace(/ /g, '-') : word\n }\n\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n result = THOUSAND\n } else {\n let thousandsWord = SEGMENTS[thousands]\n if (SEGMENTS_ENDS_CENTS[thousands] || SEGMENTS_ENDS_VINGTS[thousands]) {\n thousandsWord = thousandsWord.slice(0, -1)\n }\n result = thousandsWord + (withHyphen ? '-' : ' ') + THOUSAND\n }\n\n if (remainder > 0) {\n result += (withHyphen ? '-' : ' ') + SEGMENTS[remainder]\n }\n\n if (withHyphen) {\n result = result.replace(/ /g, '-')\n }\n\n return result\n }\n\n return buildLargeNumberWords(n, withHyphen)\n}\n\nfunction buildLargeNumberWords (n, withHyphen) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = scaleIndex > 0 ? getScaleWord(scaleIndex, BigInt(segment)) : ''\n\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else if (scaleIndex === 1) {\n if (segment === 1) {\n parts.push(THOUSAND)\n } else {\n let segWords = SEGMENTS[segment]\n if (SEGMENTS_ENDS_CENTS[segment] || SEGMENTS_ENDS_VINGTS[segment]) {\n segWords = segWords.slice(0, -1)\n }\n parts.push(segWords)\n parts.push(scaleWord)\n }\n } else {\n parts.push(SEGMENTS[segment])\n parts.push(scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n const sep = withHyphen ? '-' : ' '\n let result = parts.join(sep)\n\n if (withHyphen) {\n result = result.replace(/ /g, '-')\n }\n\n return result\n}\n\nfunction decimalPartToWords (decimalPart, withHyphen) {\n let result = ''\n const sep = withHyphen ? '-' : ' '\n\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += sep\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += sep\n result += integerToWords(BigInt(remainder), withHyphen)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Belgian French words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.withHyphenSeparator=false] - Use hyphens between words\n * @returns {string} The number in Belgian French words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n const withHyphen = options.withHyphenSeparator || false\n\n let result = ''\n const sep = withHyphen ? '-' : ' '\n\n if (isNegative) {\n result = NEGATIVE + sep\n }\n\n result += integerToWords(integerPart, withHyphen)\n\n if (decimalPart) {\n result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, withHyphen)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Gujarati language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (હજાર, લાખ, કરોડ)\n * - Gujarati script\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'શૂન્ય'\nconst NEGATIVE = 'ઋણ'\nconst DECIMAL_SEP = 'દશાંશ'\nconst HUNDRED = 'સો'\n\nconst BELOW_HUNDRED = [\n 'શૂન્ય', 'એક', 'બે', 'ત્રણ', 'ચાર', 'પાંચ', 'છ', 'સાત', 'આઠ', 'નવ',\n 'દસ', 'અગિયાર', 'બાર', 'તેર', 'ચૌદ', 'પંદર', 'સોળ', 'સત્તર', 'અઢાર', 'ઓગણીસ',\n 'વીસ', 'એકવીસ', 'બાવીસ', 'ત્રેવીસ', 'ચોવીસ', 'પચીસ', 'છવ્વીસ', 'સત્તાવીસ', 'અઠ્ઠાવીસ', 'ઓગણત્રીસ',\n 'ત્રીસ', 'એકત્રીસ', 'બત્રીસ', 'તેત્રીસ', 'ચોત્રીસ', 'પાંત્રીસ', 'છત્રીસ', 'સાડત્રીસ', 'અડત્રીસ', 'ઓગણચાલીસ',\n 'ચાલીસ', 'એકતાલીસ', 'બેતાળીસ', 'ત્રેતાળીસ', 'ચુંમાલીસ', 'પિસ્તાલીસ', 'છેતાળીસ', 'સુડતાળીસ', 'અડતાળીસ', 'ઓગણપચાસ',\n 'પચાસ', 'એકાવન', 'બાવન', 'ત્રેપન', 'ચોપન', 'પંચાવન', 'છપ્પન', 'સત્તાવન', 'અઠ્ઠાવન', 'ઓગણસાઠ',\n 'સાઠ', 'એકસઠ', 'બાસઠ', 'ત્રેસઠ', 'ચોસઠ', 'પાંસઠ', 'છાસઠ', 'સડસઠ', 'અડસઠ', 'અગણોસિત્તેર',\n 'સિત્તેર', 'એકોતેર', 'બોતેર', 'તોતેર', 'ચુમોતેર', 'પંચોતેર', 'છોતેર', 'સિત્યોતેર', 'ઇઠ્યોતેર', 'ઓગણાએંસી',\n 'એંસી', 'એક્યાસી', 'બ્યાસી', 'ત્યાસી', 'ચોર્યાસી', 'પંચાસી', 'છ્યાસી', 'સિત્યાસી', 'અઠ્યાસી', 'નેવ્યાસી',\n 'નેવું', 'એકાણું', 'બાણું', 'ત્રાણું', 'ચોરાણું', 'પંચાણું', 'છન્નું', 'સત્તાણું', 'અઠ્ઠાણું', 'નવ્વાણું'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'હજાર', 'લાખ', 'કરોડ', 'અબજ', 'ખરબ', 'નીલ', 'પદ્મ', 'શંખ']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const segments = []\n segments.unshift(Number(numStr.slice(-3)))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n segments.unshift(Number(remaining.slice(-2)))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const segments = groupByThreeThenTwos(n)\n const segmentCount = segments.length\n const words = []\n\n for (let i = 0; i < segmentCount; i++) {\n const segmentValue = segments[i]\n if (segmentValue === 0) continue\n\n const scaleIndex = segmentCount - i - 1\n words.push(segmentToWords(segmentValue))\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : BELOW_HUNDRED[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Gujarati words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Gujarati words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Hausa language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - Authentic Boko orthography with ɗ (hooked d) and ' (glottal stop)\n * - Teens with \"sha\" prefix (sha ɗaya = 11)\n * - Compound numbers with \"da\" connector (ashirin da ɗaya = 21)\n * - Arabic loanwords for tens (ashirin, talatin, arba'in, etc.)\n * - Reversed multiplier order: \"biyu ɗari\" (200), \"biyu dubu\" (2000)\n * - Implicit one before ɗari and dubu\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'ɗaya', 'biyu', 'uku', 'huɗu', 'biyar', 'shida', 'bakwai', 'takwas', 'tara']\nconst TEENS = ['goma', 'sha ɗaya', 'sha biyu', 'sha uku', 'sha huɗu', 'sha biyar', 'sha shida', 'sha bakwai', 'sha takwas', 'sha tara']\n// Arabic loanwords for tens\nconst TENS = ['', '', 'ashirin', 'talatin', \"arba'in\", 'hamsin', 'sittin', \"saba'in\", 'tamanin', \"tis'in\"]\n\nconst HUNDRED = 'ɗari'\nconst THOUSAND = 'dubu'\n\nconst ZERO = 'sifiri'\nconst NEGATIVE = 'babu'\nconst DECIMAL_SEP = 'digo'\n\n// Short scale\nconst SCALE_WORDS = ['', THOUSAND, 'miliyan', 'biliyan']\n\n// ============================================================================\n// Precomputed Lookup Table\n// ============================================================================\n\n/**\n * Build segment for 0-999 with Hausa patterns.\n * Hausa uses reversed order for hundreds: \"biyu ɗari\" (200)\n * And \"da\" connector for ones: \"ashirin da ɗaya\" (21)\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds: implicit one, or \"biyu ɗari\" (reversed order)\n if (hundredsDigit > 0) {\n if (hundredsDigit === 1) {\n parts.push(HUNDRED)\n } else {\n // Reversed: multiplier + hundredWord\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED)\n }\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit - with \"da\" connector if after hundreds\n if (hundredsDigit > 0) {\n parts.push('da ' + ONES[ones])\n } else {\n parts.push(ONES[ones])\n }\n } else if (tensOnes < 20) {\n // Teens (10-19): \"sha X\"\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n // Even tens (20, 30, 40, etc.)\n parts.push(TENS[tensDigit])\n } else {\n // Tens + ones with \"da\" connector\n parts.push(TENS[tensDigit] + ' da ' + ONES[ones])\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n return buildLargeNumberWords(n)\n}\n\n/**\n * Checks if a word is a single digit (1-9).\n */\nfunction isSingleDigit (word) {\n return ONES.slice(1).includes(word)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Build raw parts (segment words and scale words)\n const rawParts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const scaleWord = SCALE_WORDS[scaleIndex] || ''\n\n if (scaleIndex === 0) {\n rawParts.push(SEGMENTS[segment])\n } else {\n rawParts.push(SEGMENTS[segment])\n rawParts.push(scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n // Filter out implicit \"ɗaya\" before ɗari or dubu\n const filtered = []\n for (let i = 0; i < rawParts.length; i++) {\n const part = rawParts[i]\n const nextPart = rawParts[i + 1]\n\n // Skip \"ɗaya\" before ɗari or dubu (implicit one)\n if (part === 'ɗaya' && nextPart && (nextPart === HUNDRED || nextPart === THOUSAND)) {\n continue\n }\n\n filtered.push(part)\n }\n\n // Join with correct separators\n const result = []\n for (let i = 0; i < filtered.length; i++) {\n const part = filtered[i]\n const prevPart = i > 0 ? filtered[i - 1] : null\n\n // Determine if we need \"da\" connector\n // Use \"da\" when current is a single digit following a scale word\n if (prevPart && isSingleDigit(part) &&\n (prevPart === THOUSAND || prevPart === HUNDRED ||\n SCALE_WORDS.includes(prevPart))) {\n result.push(' da ')\n } else if (i > 0) {\n result.push(' ')\n }\n\n result.push(part)\n }\n\n return result.join('')\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Hausa words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Hausa words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Biblical Hebrew language converter - Functional Implementation\n *\n * Self-contained converter with segment-based decomposition.\n *\n * Key features:\n * - Gender agreement (masculine default, feminine via option)\n * - Dual forms for 2, 200, 2000\n * - Special 1-9 thousands construct state\n * - \"ו\" (ve) conjunction rules vary by position\n * - Per-digit decimal reading\n *\n * Optimization: Precomputed segment lookup tables for both genders.\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (arrays for indexed access - faster than object property lookup)\n// ============================================================================\n\n// Masculine forms (default in Biblical Hebrew) - index 0 unused\nconst ONES_MASC = ['', 'אחד', 'שניים', 'שלשה', 'ארבעה', 'חמשה', 'ששה', 'שבעה', 'שמונה', 'תשעה']\nconst TEENS_MASC = ['עשרה', 'אחד עשר', 'שנים עשר', 'שלשה עשר', 'ארבעה עשר', 'חמשה עשר', 'ששה עשר', 'שבעה עשר', 'שמונה עשר', 'תשעה עשר']\nconst THOUSANDS_MASC = ['', 'אלף', 'אלפיים', 'שלשה אלפים', 'ארבעה אלפים', 'חמשה אלפים', 'ששה אלפים', 'שבעה אלפים', 'שמונה אלפים', 'תשעה אלפים']\n\n// Feminine forms - index 0 unused\nconst ONES_FEM = ['', 'אחת', 'שתים', 'שלש', 'ארבע', 'חמש', 'שש', 'שבע', 'שמונה', 'תשע']\nconst TEENS_FEM = ['עשר', 'אחת עשרה', 'שתים עשרה', 'שלש עשרה', 'ארבע עשרה', 'חמש עשרה', 'שש עשרה', 'שבע עשרה', 'שמונה עשרה', 'תשע עשרה']\nconst THOUSANDS_FEM = ['', 'אלף', 'אלפיים', 'שלשת אלפים', 'ארבעת אלפים', 'חמשת אלפים', 'ששת אלפים', 'שבעת אלפים', 'שמונת אלפים', 'תשעת אלפים']\n\n// Shared vocabulary\nconst TENS = ['', '', 'עשרים', 'שלשים', 'ארבעים', 'חמישים', 'ששים', 'שבעים', 'שמונים', 'תשעים']\nconst HUNDREDS = ['', 'מאה', 'מאתיים', 'שלשה מאות', 'ארבעה מאות', 'חמשה מאות', 'ששה מאות', 'שבעה מאות', 'שמונה מאות', 'תשעה מאות']\nconst HUNDREDS_FEM = ['', 'מאה', 'מאתיים', 'שלש מאות', 'ארבע מאות', 'חמש מאות', 'שש מאות', 'שבע מאות', 'שמונה מאות', 'תשע מאות']\n\n// Scale words (index 1 = thousands, 2 = millions, etc.)\nconst SCALE = ['', 'אלף', 'מיליון', 'מיליארד', 'טריליון', 'קוודרליון', 'קווינטיליון']\nconst SCALE_PLURAL = ['', 'אלפים', 'מיליונים', 'מיליארדים', 'טריליונים', 'קוודרליונים', 'קווינטיליונים']\n\nconst ZERO = 'אפס'\nconst NEGATIVE = 'מינוס'\nconst DECIMAL_SEP = 'נקודה'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for scale segments (thousands, millions, etc.).\n * \"ו\" is added before tens and ones when following hundreds.\n */\nfunction buildScaleSegment (n, andWord, ONES, TEENS, HUNDREDS_ARR) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n result = HUNDREDS_ARR[hundreds]\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens (10-19)\n const teenWord = TEENS[ones]\n if (result) {\n result += ' ' + andWord + teenWord\n } else {\n result = teenWord\n }\n } else {\n // Tens (20-90)\n if (tens >= 2) {\n if (result) {\n result += ' ' + andWord + TENS[tens]\n } else {\n result = TENS[tens]\n }\n }\n\n // Ones\n if (ones > 0) {\n if (result) {\n result += ' ' + andWord + ONES[ones]\n } else {\n result = ONES[ones]\n }\n }\n }\n\n return result\n}\n\n/**\n * Builds segment word for units segment (no scale word).\n * \"ו\" is only added before the final ones digit.\n */\nfunction buildUnitsSegment (n, andWord, ONES, TEENS, HUNDREDS_ARR) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n result = HUNDREDS_ARR[hundreds]\n }\n\n // Tens (no conjunction)\n if (tens === 1) {\n // Teens (10-19)\n if (result) {\n result += ' ' + TEENS[ones]\n } else {\n result = TEENS[ones]\n }\n } else {\n if (tens >= 2) {\n if (result) {\n result += ' ' + TENS[tens]\n } else {\n result = TENS[tens]\n }\n }\n\n // Ones - conjunction only here\n if (ones > 0) {\n if (result) {\n result += ' ' + andWord + ONES[ones]\n } else {\n result = ONES[ones]\n }\n }\n }\n\n return result\n}\n\n// Precompute all 1000 segment words for masculine (default) with default conjunction\nconst SCALE_SEGMENTS_MASC = new Array(1000)\nconst UNITS_SEGMENTS_MASC = new Array(1000)\nconst SCALE_SEGMENTS_FEM = new Array(1000)\nconst UNITS_SEGMENTS_FEM = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SCALE_SEGMENTS_MASC[i] = buildScaleSegment(i, 'ו', ONES_MASC, TEENS_MASC, HUNDREDS)\n UNITS_SEGMENTS_MASC[i] = buildUnitsSegment(i, 'ו', ONES_MASC, TEENS_MASC, HUNDREDS)\n SCALE_SEGMENTS_FEM[i] = buildScaleSegment(i, 'ו', ONES_FEM, TEENS_FEM, HUNDREDS_FEM)\n UNITS_SEGMENTS_FEM[i] = buildUnitsSegment(i, 'ו', ONES_FEM, TEENS_FEM, HUNDREDS_FEM)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Biblical Hebrew words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Biblical Hebrew words\n */\nfunction integerToWords (n, options) {\n if (n === 0n) return ZERO\n\n const andWord = options.andWord ?? 'ו'\n const gender = options.gender || 'masculine'\n const isFeminine = gender === 'feminine'\n const usePrecomputed = andWord === 'ו'\n\n // Select vocabulary based on gender\n const ONES = isFeminine ? ONES_FEM : ONES_MASC\n const TEENS = isFeminine ? TEENS_FEM : TEENS_MASC\n const THOUSANDS_SPECIAL = isFeminine ? THOUSANDS_FEM : THOUSANDS_MASC\n const HUNDREDS_ARR = isFeminine ? HUNDREDS_FEM : HUNDREDS\n const SCALE_SEGS = isFeminine ? SCALE_SEGMENTS_FEM : SCALE_SEGMENTS_MASC\n const UNITS_SEGS = isFeminine ? UNITS_SEGMENTS_FEM : UNITS_SEGMENTS_MASC\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return usePrecomputed ? UNITS_SEGS[Number(n)] : buildUnitsSegment(Number(n), andWord, ONES, TEENS, HUNDREDS_ARR)\n }\n\n // Extract segments using BigInt modulo\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Build result string directly\n let result = ''\n\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i]\n if (segment === 0) continue\n\n if (i === 0) {\n // Units segment (no scale word)\n const segmentWord = usePrecomputed ? UNITS_SEGS[segment] : buildUnitsSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)\n if (result) {\n // Add \"ו\" before single-digit units when following scale words\n if (segment <= 9) {\n result += ' ' + andWord + segmentWord\n } else {\n result += ' ' + segmentWord\n }\n } else {\n result = segmentWord\n }\n } else if (i === 1) {\n // Thousands - special handling for 1-9\n if (segment <= 9) {\n if (result) result += ' '\n result += THOUSANDS_SPECIAL[segment]\n } else {\n const segmentWord = usePrecomputed ? SCALE_SEGS[segment] : buildScaleSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)\n if (result) result += ' '\n result += segmentWord + ' ' + SCALE[1]\n }\n } else {\n // Millions and above\n if (segment === 1) {\n if (result) result += ' '\n result += SCALE[i]\n } else {\n const segmentWord = usePrecomputed ? SCALE_SEGS[segment] : buildScaleSegment(segment, andWord, ONES, TEENS, HUNDREDS_ARR)\n if (result) result += ' '\n result += segmentWord + ' ' + SCALE_PLURAL[i]\n }\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Biblical Hebrew words (digit by digit).\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Biblical Hebrew words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n const gender = options.gender || 'masculine'\n const ONES = gender === 'feminine' ? ONES_FEM : ONES_MASC\n\n let result = ''\n for (let i = 0; i < decimalPart.length; i++) {\n const d = parseInt(decimalPart[i], 10)\n if (result) result += ' '\n result += d === 0 ? ZERO : ONES[d]\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Biblical Hebrew words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @param {string} [options.andWord] - Custom conjunction word\n * @returns {string} The number in Biblical Hebrew words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Modern Hebrew language converter - Functional Implementation\n *\n * Self-contained converter with segment-based decomposition.\n *\n * Key features:\n * - Feminine grammatical forms (default in Modern Hebrew)\n * - Dual forms for 2, 200, 2000\n * - Special 1-9 thousands construct state\n * - \"ו\" (ve) conjunction rules vary by position\n * - Per-digit decimal reading\n *\n * Optimization: Precomputed segment lookup tables for 0-999.\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (arrays for indexed access - faster than object property lookup)\n// ============================================================================\n\n// Feminine forms (default in Modern Hebrew) - index 0 unused\nconst ONES = ['', 'אחת', 'שתים', 'שלש', 'ארבע', 'חמש', 'שש', 'שבע', 'שמונה', 'תשע']\nconst TEENS = ['עשר', 'אחת עשרה', 'שתים עשרה', 'שלש עשרה', 'ארבע עשרה', 'חמש עשרה', 'שש עשרה', 'שבע עשרה', 'שמונה עשרה', 'תשע עשרה']\nconst TENS = ['', '', 'עשרים', 'שלשים', 'ארבעים', 'חמישים', 'ששים', 'שבעים', 'שמונים', 'תשעים']\nconst HUNDREDS = ['', 'מאה', 'מאתיים', 'שלש מאות', 'ארבע מאות', 'חמש מאות', 'שש מאות', 'שבע מאות', 'שמונה מאות', 'תשע מאות']\n\n// Special forms for 1-9 thousand (index 0 unused)\nconst THOUSANDS_SPECIAL = ['', 'אלף', 'אלפיים', 'שלשת אלפים', 'ארבעת אלפים', 'חמשת אלפים', 'ששת אלפים', 'שבעת אלפים', 'שמונת אלפים', 'תשעת אלפים']\n\n// Scale words (index 1 = thousands, 2 = millions, etc.)\nconst SCALE = ['', 'אלף', 'מיליון', 'מיליארד', 'טריליון', 'קוודרליון', 'קווינטיליון']\nconst SCALE_PLURAL = ['', 'אלפים', 'מיליונים', 'מיליארדים', 'טריליונים', 'קוודרליונים', 'קווינטיליונים']\n\nconst ZERO = 'אפס'\nconst NEGATIVE = 'מינוס'\nconst DECIMAL_SEP = 'נקודה'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for scale segments (thousands, millions, etc.).\n * \"ו\" is added before tens and ones when following hundreds.\n */\nfunction buildScaleSegment (n, andWord) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n result = HUNDREDS[hundreds]\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens (10-19)\n const teenWord = TEENS[ones]\n if (result) {\n result += ' ' + andWord + teenWord\n } else {\n result = teenWord\n }\n } else {\n // Tens (20-90)\n if (tens >= 2) {\n if (result) {\n result += ' ' + andWord + TENS[tens]\n } else {\n result = TENS[tens]\n }\n }\n\n // Ones\n if (ones > 0) {\n if (result) {\n result += ' ' + andWord + ONES[ones]\n } else {\n result = ONES[ones]\n }\n }\n }\n\n return result\n}\n\n/**\n * Builds segment word for units segment (no scale word).\n * \"ו\" is only added before the final ones digit.\n */\nfunction buildUnitsSegment (n, andWord) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n result = HUNDREDS[hundreds]\n }\n\n // Tens (no conjunction)\n if (tens === 1) {\n // Teens (10-19)\n if (result) {\n result += ' ' + TEENS[ones]\n } else {\n result = TEENS[ones]\n }\n } else {\n if (tens >= 2) {\n if (result) {\n result += ' ' + TENS[tens]\n } else {\n result = TENS[tens]\n }\n }\n\n // Ones - conjunction only here\n if (ones > 0) {\n if (result) {\n result += ' ' + andWord + ONES[ones]\n } else {\n result = ONES[ones]\n }\n }\n }\n\n return result\n}\n\n// Precompute all 1000 segment words with default conjunction\nconst SCALE_SEGMENTS = new Array(1000)\nconst UNITS_SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SCALE_SEGMENTS[i] = buildScaleSegment(i, 'ו')\n UNITS_SEGMENTS[i] = buildUnitsSegment(i, 'ו')\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Hebrew words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Hebrew words\n */\nfunction integerToWords (n, options) {\n if (n === 0n) return ZERO\n\n const andWord = options.andWord ?? 'ו'\n const usePrecomputed = andWord === 'ו'\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return usePrecomputed ? UNITS_SEGMENTS[Number(n)] : buildUnitsSegment(Number(n), andWord)\n }\n\n // Extract segments using BigInt modulo\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Build result string directly\n let result = ''\n\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i]\n if (segment === 0) continue\n\n if (i === 0) {\n // Units segment (no scale word)\n const segmentWord = usePrecomputed ? UNITS_SEGMENTS[segment] : buildUnitsSegment(segment, andWord)\n if (result) {\n // Add \"ו\" before single-digit units when following scale words\n if (segment <= 9) {\n result += ' ' + andWord + segmentWord\n } else {\n result += ' ' + segmentWord\n }\n } else {\n result = segmentWord\n }\n } else if (i === 1) {\n // Thousands - special handling for 1-9\n if (segment <= 9) {\n if (result) result += ' '\n result += THOUSANDS_SPECIAL[segment]\n } else {\n const segmentWord = usePrecomputed ? SCALE_SEGMENTS[segment] : buildScaleSegment(segment, andWord)\n if (result) result += ' '\n result += segmentWord + ' ' + SCALE[1]\n }\n } else {\n // Millions and above\n if (segment === 1) {\n if (result) result += ' '\n result += SCALE[i]\n } else {\n const segmentWord = usePrecomputed ? SCALE_SEGMENTS[segment] : buildScaleSegment(segment, andWord)\n if (result) result += ' '\n result += segmentWord + ' ' + SCALE_PLURAL[i]\n }\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Hebrew words (digit by digit).\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Hebrew words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n for (let i = 0; i < decimalPart.length; i++) {\n const d = parseInt(decimalPart[i], 10)\n if (result) result += ' '\n result += d === 0 ? ZERO : ONES[d]\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Modern Hebrew words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @param {string} [options.andWord] - Custom conjunction word\n * @returns {string} The number in Modern Hebrew words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Hindi language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (हज़ार, लाख, करोड़)\n * - Devanagari script\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'शून्य'\nconst NEGATIVE = 'माइनस'\nconst DECIMAL_SEP = 'दशमलव'\nconst HUNDRED = 'सौ'\n\nconst BELOW_HUNDRED = [\n 'शून्य', 'एक', 'दो', 'तीन', 'चार', 'पाँच', 'छह', 'सात', 'आठ', 'नौ',\n 'दस', 'ग्यारह', 'बारह', 'तेरह', 'चौदह', 'पंद्रह', 'सोलह', 'सत्रह', 'अठारह', 'उन्नीस',\n 'बीस', 'इक्कीस', 'बाईस', 'तेईस', 'चौबीस', 'पच्चीस', 'छब्बीस', 'सत्ताईस', 'अट्ठाईस', 'उनतीस',\n 'तीस', 'इकतीस', 'बत्तीस', 'तैंतीस', 'चौंतीस', 'पैंतीस', 'छत्तीस', 'सैंतीस', 'अड़तीस', 'उनतालीस',\n 'चालीस', 'इकतालीस', 'बयालीस', 'तेतालीस', 'चवालीस', 'पैंतालीस', 'छियालीस', 'सैंतालीस', 'अड़तालीस', 'उनचास',\n 'पचास', 'इक्यावन', 'बावन', 'तिरपन', 'चौवन', 'पचपन', 'छप्पन', 'सत्तावन', 'अट्ठावन', 'उनसठ',\n 'साठ', 'इकसठ', 'बासठ', 'तिरसठ', 'चौंसठ', 'पैंसठ', 'छियासठ', 'सड़सठ', 'अड़सठ', 'उनहत्तर',\n 'सत्तर', 'इकहत्तर', 'बहत्तर', 'तिहत्तर', 'चौहत्तर', 'पचहत्तर', 'छिहत्तर', 'सतहत्तर', 'अठहत्तर', 'उन्यासी',\n 'अस्सी', 'इक्यासी', 'बयासी', 'तिरासी', 'चौरासी', 'पचासी', 'छियासी', 'सत्तासी', 'अट्ठासी', 'नवासी',\n 'नब्बे', 'इक्यानवे', 'बानवे', 'तिरानवे', 'चौरानवे', 'पचानवे', 'छियानवे', 'सत्तानवे', 'अट्ठानवे', 'निन्यानवे'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'हज़ार', 'लाख', 'करोड़', 'अरब', 'खरब', 'नील', 'पद्म', 'शंख']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const segments = []\n segments.unshift(Number(numStr.slice(-3)))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n segments.unshift(Number(remaining.slice(-2)))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const segments = groupByThreeThenTwos(n)\n const segmentCount = segments.length\n const words = []\n\n for (let i = 0; i < segmentCount; i++) {\n const segmentValue = segments[i]\n if (segmentValue === 0) continue\n\n const scaleIndex = segmentCount - i - 1\n words.push(segmentToWords(segmentValue))\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Hindi words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Hindi words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Croatian language converter - Functional Implementation\n *\n * Self-contained converter using shared Slavic utilities.\n *\n * Key features:\n * - Three-form pluralization (one/few/many)\n * - Gender: thousands are feminine, millions+ are masculine\n * - Irregular hundreds (dvjesto, tristo, etc.)\n * - Long scale naming with -ard forms\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Slavic Utilities (inlined for performance)\n// ============================================================================\n\nfunction pluralize (n, forms) {\n const num = typeof n === 'bigint' ? Number(n) : n\n const lastDigit = num % 10\n const lastTwoDigits = num % 100\n\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n if (lastDigit === 1) return forms[0]\n if (lastDigit >= 2 && lastDigit <= 4) return forms[1]\n return forms[2]\n}\n\nfunction buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {\n const masc = new Array(1000)\n const fem = new Array(1000)\n\n for (let i = 0; i < 1000; i++) {\n masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)\n fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)\n }\n\n return { masc, fem }\n}\n\nfunction buildSegment (n, ones, teens, tens, hundreds) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n parts.push(hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1) {\n parts.push(tens[tensDigit])\n }\n\n if (tensDigit === 1) {\n parts.push(teens[onesDigit])\n } else if (onesDigit > 0) {\n parts.push(ones[onesDigit])\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES_MASC = ['', 'jedan', 'dva', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']\nconst ONES_FEM = ['', 'jedna', 'dvije', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']\n\nconst TEENS = ['deset', 'jedanaest', 'dvanaest', 'trinaest', 'četrnaest', 'petnaest', 'šesnaest', 'sedamnaest', 'osamnaest', 'devetnaest']\nconst TENS = ['', '', 'dvadeset', 'trideset', 'četrdeset', 'pedeset', 'šezdeset', 'sedamdeset', 'osamdeset', 'devedeset']\n\n// Croatian has irregular hundreds\nconst HUNDREDS = ['', 'sto', 'dvjesto', 'tristo', 'četiristo', 'petsto', 'šesto', 'sedamsto', 'osamsto', 'devetsto']\n\nconst ZERO = 'nula'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'zarez'\n\n// Scale words: [singular, few, many]\n// Thousands (index 0) are feminine, rest are masculine\nconst SCALE_FORMS = [\n ['tisuća', 'tisuće', 'tisuća'],\n ['milijun', 'milijuna', 'milijuna'],\n ['milijarda', 'milijarde', 'milijarda'],\n ['bilijun', 'bilijuna', 'bilijuna'],\n ['bilijarda', 'bilijarde', 'bilijarda'],\n ['trilijun', 'trilijuna', 'trilijuna'],\n ['trilijarda', 'trilijarde', 'trilijarda'],\n ['kvadrilijun', 'kvadrilijuna', 'kvadrilijuna'],\n ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nconst { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n return buildLargeNumberWords(n, options)\n}\n\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment])\n } else {\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n // Thousands (scaleIndex=1) are feminine, others masculine\n const isFeminine = scaleIndex === 1\n const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Croatian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Croatian words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Hungarian language converter - Functional Implementation\n *\n * Self-contained converter with agglutinative word formation.\n *\n * Key features:\n * - Agglutinative structure (no spaces between compound parts)\n * - Special handling for \"egy\" (one) omission\n * - Pre-composed twenties (huszonegy through huszonkilenc)\n * - \"két\" instead of \"kettő\" in compound forms\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\n// Word map using BigInt keys for scale values\nconst WORDS = new Map([\n [1_000_000_000_000_000_000_000_000_000n, 'quadrilliárd'],\n [1_000_000_000_000_000_000_000_000n, 'quadrillió'],\n [1_000_000_000_000_000_000_000n, 'trilliárd'],\n [1_000_000_000_000_000_000n, 'trillió'],\n [1_000_000_000_000_000n, 'billiárd'],\n [1_000_000_000_000n, 'billió'],\n [1_000_000_000n, 'milliárd'],\n [1_000_000n, 'millió'],\n [1000n, 'ezer'],\n [100n, 'száz'],\n [90n, 'kilencven'],\n [80n, 'nyolcvan'],\n [70n, 'hetven'],\n [60n, 'hatvan'],\n [50n, 'ötven'],\n [40n, 'negyven'],\n [30n, 'harminc'],\n [29n, 'huszonkilenc'],\n [28n, 'huszonnyolc'],\n [27n, 'huszonhét'],\n [26n, 'huszonhat'],\n [25n, 'huszonöt'],\n [24n, 'huszonnégy'],\n [23n, 'huszonhárom'],\n [22n, 'huszonkettő'],\n [21n, 'huszonegy'],\n [20n, 'húsz'],\n [19n, 'tizenkilenc'],\n [18n, 'tizennyolc'],\n [17n, 'tizenhét'],\n [16n, 'tizenhat'],\n [15n, 'tizenöt'],\n [14n, 'tizennégy'],\n [13n, 'tizenhárom'],\n [12n, 'tizenkettő'],\n [11n, 'tizenegy'],\n [10n, 'tíz'],\n [9n, 'kilenc'],\n [8n, 'nyolc'],\n [7n, 'hét'],\n [6n, 'hat'],\n [5n, 'öt'],\n [4n, 'négy'],\n [3n, 'három'],\n [2n, 'kettő'],\n [1n, 'egy'],\n [0n, 'nulla']\n])\n\nconst ZERO = 'nulla'\nconst NEGATIVE = 'mínusz'\nconst DECIMAL_SEP = 'egész'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction wordForScale (value) {\n return WORDS.get(value)\n}\n\nfunction tensToCardinal (n) {\n if (WORDS.has(n)) {\n return WORDS.get(n)\n }\n const tens = n / 10n\n const units = n % 10n\n return wordForScale(tens * 10n) + integerToWordsInner(units)\n}\n\nfunction hundredsToCardinal (n) {\n const hundreds = n / 100n\n let prefix = 'száz'\n if (hundreds !== 1n) {\n prefix = integerToWordsInner(hundreds, '') + prefix\n }\n const postfix = integerToWordsInner(n % 100n, '')\n return prefix + postfix\n}\n\nfunction thousandsToCardinal (n) {\n const thousands = n / 1000n\n let prefix = 'ezer'\n if (thousands !== 1n) {\n prefix = integerToWordsInner(thousands, '') + prefix\n }\n const postfix = integerToWordsInner(n % 1000n, '')\n const middle = (n <= 2000n || postfix === '') ? '' : '-'\n return prefix + middle + postfix\n}\n\n// Scale values for finding appropriate scale (avoids toString)\nconst SCALES = [\n 1_000_000_000_000_000_000_000_000_000n,\n 1_000_000_000_000_000_000_000_000n,\n 1_000_000_000_000_000_000_000n,\n 1_000_000_000_000_000_000n,\n 1_000_000_000_000_000n,\n 1_000_000_000_000n,\n 1_000_000_000n,\n 1_000_000n\n]\n\nfunction bigNumberToCardinal (n) {\n // Find appropriate scale using BigInt comparison (avoids toString)\n let exp = 1_000_000n\n for (const scale of SCALES) {\n if (n >= scale) {\n exp = scale\n break\n }\n }\n\n const prefix = integerToWordsInner(n / exp, '')\n const rest = integerToWordsInner(n % exp, '')\n const postfix = (rest === '') ? '' : ('-' + rest)\n return prefix + wordForScale(exp) + postfix\n}\n\nfunction integerToWordsInner (n, zeroWord = ZERO) {\n // Normalize to BigInt for consistent comparisons\n if (typeof n !== 'bigint') n = BigInt(n)\n\n if (n === 0n) {\n return zeroWord\n }\n if (zeroWord === '' && n === 2n) {\n return 'két'\n }\n if (n < 30n) {\n return wordForScale(n)\n }\n if (n < 100n) {\n return tensToCardinal(n)\n }\n if (n < 1000n) {\n return hundredsToCardinal(n)\n }\n if (n < 1_000_000n) {\n return thousandsToCardinal(n)\n }\n return bigNumberToCardinal(n)\n}\n\nfunction integerToWords (n) {\n return integerToWordsInner(n, ZERO)\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Hungarian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Hungarian words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Indonesian language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - \"Se-\" prefix for 100 (seratus) and 1000 (seribu)\n * - Regular patterns (puluh for tens, ratus for hundreds)\n * - Teens with \"belas\" suffix\n * - Indonesian uses \"satu juta\" (not \"sejuta\") for millions+\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'sembilan']\nconst TEENS = ['sepuluh', 'sebelas', 'dua belas', 'tiga belas', 'empat belas', 'lima belas', 'enam belas', 'tujuh belas', 'delapan belas', 'sembilan belas']\nconst TENS = ['', '', 'dua puluh', 'tiga puluh', 'empat puluh', 'lima puluh', 'enam puluh', 'tujuh puluh', 'delapan puluh', 'sembilan puluh']\n\nconst HUNDRED_WORD = 'ratus'\nconst THOUSAND_WORD = 'ribu'\nconst SCALE_WORDS = ['juta', 'miliar', 'triliun', 'kuadriliun', 'kuantiliun', 'sekstiliun', 'septiliun', 'oktiliun', 'noniliun', 'desiliun']\n\nconst ZERO = 'nol'\nconst NEGATIVE = 'min'\nconst DECIMAL_SEP = 'koma'\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds: seratus (100) or N ratus (200-900)\n if (hundredsDigit > 0) {\n if (hundredsDigit === 1) {\n parts.push('se' + HUNDRED_WORD)\n } else {\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED_WORD)\n }\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[tensOnes])\n } else if (tensOnes < 20) {\n parts.push(TEENS[tensOnes - 10])\n } else if (onesDigit === 0) {\n parts.push(TENS[tensDigit])\n } else {\n parts.push(TENS[tensDigit] + ' ' + ONES[onesDigit])\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n result = 'se' + THOUSAND_WORD\n } else {\n result = SEGMENTS[thousands] + ' ' + THOUSAND_WORD\n }\n\n if (remainder > 0) {\n result += ' ' + SEGMENTS[remainder]\n }\n\n return result\n }\n\n return buildLargeNumberWords(n)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else if (scaleIndex === 1) {\n if (segment === 1) {\n parts.push('se' + THOUSAND_WORD)\n } else {\n parts.push(SEGMENTS[segment] + ' ' + THOUSAND_WORD)\n }\n } else {\n // Indonesian: \"satu juta\" not \"sejuta\"\n const scaleWord = SCALE_WORDS[scaleIndex - 2]\n parts.push(SEGMENTS[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Indonesian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Indonesian words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Italian language converter - Functional Implementation v2\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all 1000 segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Italian-specific rules (handled in precomputation):\n * - Concatenation without spaces within segments (\"ventotto\" not \"venti otto\")\n * - Phonetic vowel elision: \"venti\" + \"otto\" → \"ventotto\"\n * - Accent on final \"tre\" in compounds: \"ventitré\"\n * - mille/mila alternation for thousands\n * - Scale words: milione/milioni, miliardo/miliardi, etc.\n * - \"e\" connector before simple final remainder\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\n// Base vocabulary for building lookup tables\nconst ONES = ['', 'uno', 'due', 'tre', 'quattro', 'cinque', 'sei', 'sette', 'otto', 'nove']\nconst TEENS = ['dieci', 'undici', 'dodici', 'tredici', 'quattordici', 'quindici', 'sedici', 'diciassette', 'diciotto', 'diciannove']\nconst TENS = ['', '', 'venti', 'trenta', 'quaranta', 'cinquanta', 'sessanta', 'settanta', 'ottanta', 'novanta']\nconst HUNDREDS = ['', 'cento', 'duecento', 'trecento', 'quattrocento', 'cinquecento', 'seicento', 'settecento', 'ottocento', 'novecento']\n\nconst ZERO = 'zero'\nconst NEGATIVE = 'meno'\nconst DECIMAL_SEP = 'virgola'\n\n// Thousands\nconst THOUSAND_SINGULAR = 'mille'\nconst THOUSAND_PLURAL_SUFFIX = 'mila'\n\n// Scale word generation\nconst SCALE_PREFIXES = ['m', 'b', 'tr', 'quadr', 'quint', 'sest', 'sett', 'ott', 'nov', 'dec']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Applies Italian phonetic vowel elision rules.\n * Only used during table construction.\n */\nfunction applyPhoneticRules (str) {\n return str\n .replace(/io/g, 'o')\n .replace(/ao/g, 'o')\n .replace(/oo/g, 'o')\n .replace(/iu/g, 'u')\n .replace(/au/g, 'u')\n}\n\n/**\n * Adds accent to final \"tre\" in a word.\n * Only used during table construction.\n */\nfunction accentuateTre (word) {\n if (word.length > 3 && word.slice(-3) === 'tre') {\n return word.slice(0, -3) + 'tré'\n }\n return word\n}\n\n/**\n * Builds the segment word for a number 0-999.\n * Only used during table construction.\n */\nfunction buildSegmentWord (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n result = HUNDREDS[hundreds]\n }\n\n // Tens and ones\n if (tens === 0 && ones === 0) {\n // Nothing more\n } else if (tens === 1) {\n // Teens: 10-19\n result += TEENS[ones]\n } else if (tens >= 2) {\n // 20-99\n result += TENS[tens]\n if (ones > 0) {\n result += ONES[ones]\n }\n } else if (ones > 0) {\n // 1-9 (tens === 0)\n result += ONES[ones]\n }\n\n // Apply phonetic rules and accent\n return accentuateTre(applyPhoneticRules(result))\n}\n\n/**\n * Builds segment word with \"un\" for scale context (millions, billions).\n * Only used during table construction.\n */\nfunction buildSegmentWordForScale (n) {\n if (n === 0) return ''\n if (n === 1) return 'un' // \"un milione\" not \"uno milione\"\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n let result = ''\n\n if (hundreds > 0) {\n result = HUNDREDS[hundreds]\n }\n\n if (tens === 0 && ones === 0) {\n // Nothing more\n } else if (tens === 1) {\n result += TEENS[ones]\n } else if (tens >= 2) {\n result += TENS[tens]\n if (ones > 0) {\n result += ONES[ones]\n }\n } else if (ones > 0) {\n // 1-9 with tens === 0\n // \"un\" only for exactly 1, others normal\n result += ONES[ones]\n }\n\n return accentuateTre(applyPhoneticRules(result))\n}\n\n// Precompute all 1000 segment words (0-999)\n// SEGMENTS[n] gives the Italian word for n within a segment\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegmentWord(i)\n}\n\n// Precompute segment words for scale context (uses \"un\" for 1)\nconst SEGMENTS_SCALE = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_SCALE[i] = buildSegmentWordForScale(i)\n}\n\n// Precompute thousands words (1-999) + \"mila\" suffix\n// THOUSANDS[n] gives the word for n thousand (e.g., THOUSANDS[2] = \"duemila\")\nconst THOUSANDS = new Array(1000)\nTHOUSANDS[0] = ''\nTHOUSANDS[1] = THOUSAND_SINGULAR // \"mille\"\nfor (let i = 2; i < 1000; i++) {\n THOUSANDS[i] = applyPhoneticRules(SEGMENTS[i] + THOUSAND_PLURAL_SUFFIX)\n}\n\n// ============================================================================\n// Scale Word Functions\n// ============================================================================\n\n/**\n * Gets singular scale word for index.\n * @param {number} scaleIndex - 2=million, 3=billion, etc.\n */\nfunction getScaleWordSingular (scaleIndex) {\n if (scaleIndex < 2) return ''\n const prefixIndex = Math.floor((scaleIndex - 2) / 2)\n const isIardo = (scaleIndex - 2) % 2 === 1\n const prefix = SCALE_PREFIXES[prefixIndex]\n if (!prefix) return ''\n return prefix + (isIardo ? 'iliardo' : 'ilione')\n}\n\n/**\n * Gets plural scale word for index.\n * @param {number} scaleIndex - 2=million, 3=billion, etc.\n */\nfunction getScaleWordPlural (scaleIndex) {\n if (scaleIndex < 2) return ''\n const prefixIndex = Math.floor((scaleIndex - 2) / 2)\n const isIardo = (scaleIndex - 2) % 2 === 1\n const prefix = SCALE_PREFIXES[prefixIndex]\n if (!prefix) return ''\n return prefix + (isIardo ? 'iliardi' : 'ilioni')\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Italian words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Italian words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n if (remainder === 0) {\n return THOUSANDS[thousands]\n }\n\n // Concatenate thousands + remainder\n return THOUSANDS[thousands] + SEGMENTS[remainder]\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Italian words\n */\nfunction buildLargeNumberWords (n) {\n const parts = []\n let remaining = n\n\n // Find the highest scale\n let maxScale = 2\n let testValue = 1_000_000n\n while (testValue * 1000n <= remaining) {\n testValue *= 1000n\n maxScale++\n }\n\n // Process from highest scale down\n for (let scaleIndex = maxScale; scaleIndex >= 0; scaleIndex--) {\n const divisor = 1000n ** BigInt(scaleIndex)\n const segment = remaining / divisor\n remaining = remaining % divisor\n\n if (segment === 0n) continue\n\n const segNum = Number(segment)\n\n if (scaleIndex >= 2) {\n // Millions and above: \"segment scaleWord\"\n const segmentWords = SEGMENTS_SCALE[segNum]\n const scaleWord = segment === 1n\n ? getScaleWordSingular(scaleIndex)\n : getScaleWordPlural(scaleIndex)\n parts.push(segmentWords + ' ' + scaleWord)\n } else if (scaleIndex === 1) {\n // Thousands: use precomputed table\n parts.push(THOUSANDS[segNum])\n } else {\n // Units (scaleIndex === 0): just the segment\n parts.push(SEGMENTS[segNum])\n }\n }\n\n return joinPartsWithConnector(parts)\n}\n\n/**\n * Joins parts with Italian connector rules.\n * Uses \"e\" before simple (non-compound) final segment.\n *\n * @param {string[]} parts - Parts to join\n * @returns {string} Joined string\n */\nfunction joinPartsWithConnector (parts) {\n const len = parts.length\n if (len === 0) return ''\n if (len === 1) return parts[0]\n\n // Check if last part is \"simple\" (no space = no scale word)\n const lastPart = parts[len - 1]\n if (lastPart.indexOf(' ') === -1) {\n // Join all but last with space, then add \"e\" connector\n let result = parts[0]\n for (let i = 1; i < len - 1; i++) {\n result += ' ' + parts[i]\n }\n return result + ' e ' + lastPart\n }\n\n // Join with spaces\n let result = parts[0]\n for (let i = 1; i < len; i++) {\n result += ' ' + parts[i]\n }\n return result\n}\n\n/**\n * Converts decimal digits to Italian words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Italian words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Italian words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Italian words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(28) // 'ventotto'\n * toWords(23) // 'ventitré'\n * toWords(1000) // 'mille'\n * toWords(2000) // 'duemila'\n * toWords(1000000) // 'un milione'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Japanese language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-9999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Japanese-specific rules (handled in precomputation):\n * - Myriad (万-based) grouping: 4 digits per segment instead of 3\n * - 一 omission: Omit \"一\" before 十, 百, 千 but NOT before 万 and higher scales\n * - Kanji numerals: 零一二三四五六七八九\n * - No spaces between characters\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\n// Ones words (1-9), index 0 unused\nconst ONES = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']\n\n// Scale words for powers of 10,000 (万-based system)\n// Index 0 = 万 (10^4), 1 = 億 (10^8), 2 = 兆 (10^12), etc.\nconst SCALES = [\n '万', // 10^4 (man)\n '億', // 10^8 (oku)\n '兆', // 10^12 (chō)\n '京', // 10^16 (kei)\n '垓', // 10^20 (gai)\n '秭', // 10^24 (jo/shi)\n '穣', // 10^28 (jō)\n '溝', // 10^32 (kō)\n '澗', // 10^36 (kan)\n '正', // 10^40 (sei)\n '載', // 10^44 (sai)\n '極', // 10^48 (goku)\n '恒河沙', // 10^52 (gōgasha)\n '阿僧祇', // 10^56 (asōgi)\n '那由他', // 10^60 (nayuta)\n '不可思議', // 10^64 (fukashigi)\n '無量大数' // 10^68 (muryōtaisū)\n]\n\nconst ZERO = '零'\nconst NEGATIVE = 'マイナス'\nconst DECIMAL_SEP = '点'\n\n// Internal scale words (within 4-digit segments)\nconst TEN = '十'\nconst HUNDRED = '百'\nconst THOUSAND = '千'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-9999 with 一 omission rules.\n * - Omit 一 before 十, 百, 千\n * Only used during table construction.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100) % 10\n const thousands = Math.floor(n / 1000)\n\n let result = ''\n\n // Thousands (千) - omit 一 when 1\n if (thousands > 0) {\n if (thousands === 1) {\n result += THOUSAND\n } else {\n result += ONES[thousands] + THOUSAND\n }\n }\n\n // Hundreds (百) - omit 一 when 1\n if (hundreds > 0) {\n if (hundreds === 1) {\n result += HUNDRED\n } else {\n result += ONES[hundreds] + HUNDRED\n }\n }\n\n // Tens (十) - omit 一 when 1\n if (tens > 0) {\n if (tens === 1) {\n result += TEN\n } else {\n result += ONES[tens] + TEN\n }\n }\n\n // Ones\n if (ones > 0) {\n result += ONES[ones]\n }\n\n return result\n}\n\n// Precompute all 10000 segment words (0-9999)\n// SEGMENTS[n] gives the Japanese word for n within a segment\nconst SEGMENTS = new Array(10000)\nfor (let i = 0; i < 10000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Japanese words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Japanese kanji words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 10000 (direct lookup)\n if (n < 10000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 100,000,000 (万 range)\n if (n < 100_000_000n) {\n const man = Number(n / 10000n)\n const remainder = Number(n % 10000n)\n\n // For 万 and above, we need 一 before the scale word when segment is 1\n let result\n if (man === 1) {\n result = '一' + SCALES[0] // 一万\n } else {\n result = SEGMENTS[man] + SCALES[0]\n }\n\n if (remainder > 0) {\n result += SEGMENTS[remainder]\n }\n\n return result\n }\n\n // For numbers >= 100,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 100,000,000.\n * Uses BigInt modulo for 4-digit (myriad) segment extraction.\n *\n * @param {bigint} n - Number >= 100,000,000\n * @returns {string} Japanese kanji words\n */\nfunction buildLargeNumberWords (n) {\n // Extract segments using BigInt modulo (faster than string slicing)\n // Segments stored least-significant first (index 0 = units, 1 = 万, etc.)\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 10000n))\n temp = temp / 10000n\n }\n\n // Build result string directly (process from most-significant to least)\n let result = ''\n\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i]\n if (segment === 0) continue\n\n if (i > 0) {\n // For scales >= 万, we need 一 before scale word when segment is 1\n if (segment === 1) {\n result += '一' + SCALES[i - 1]\n } else {\n result += SEGMENTS[segment] + SCALES[i - 1]\n }\n } else {\n // Units segment (no scale word)\n result += SEGMENTS[segment]\n }\n }\n\n return result || ZERO\n}\n\n/**\n * Converts decimal digits to Japanese words (digit by digit).\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Japanese kanji words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n for (let i = 0; i < decimalPart.length; i++) {\n const digit = parseInt(decimalPart[i], 10)\n if (digit === 0) {\n result += ZERO\n } else {\n result += ONES[digit]\n }\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Japanese words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Japanese kanji words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // '四十二'\n * toWords(10000) // '一万'\n * toWords(100000000) // '一億'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += DECIMAL_SEP + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Kannada language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (ಸಾವಿರ, ಲಕ್ಷ, ಕೋಟಿ)\n * - Kannada script\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'ಸೊನ್ನೆ'\nconst NEGATIVE = 'ಋಣಾತ್ಮಕ'\nconst DECIMAL_SEP = 'ದಶಮಾಂಶ'\nconst HUNDRED = 'ನೂರು'\n\nconst BELOW_HUNDRED = [\n 'ಸೊನ್ನೆ', 'ಒಂದು', 'ಎರಡು', 'ಮೂರು', 'ನಾಲ್ಕು', 'ಐದು', 'ಆರು', 'ಏಳು', 'ಎಂಟು', 'ಒಂಬತ್ತು',\n 'ಹತ್ತು', 'ಹನ್ನೊಂದು', 'ಹನ್ನೆರಡು', 'ಹದಿಮೂರು', 'ಹದಿನಾಲ್ಕು', 'ಹದಿನೈದು', 'ಹದಿನಾರು', 'ಹದಿನೇಳು', 'ಹದಿನೆಂಟು', 'ಹತ್ತೊಂಬತ್ತು',\n 'ಇಪ್ಪತ್ತು', 'ಇಪ್ಪತ್ತೊಂದು', 'ಇಪ್ಪತ್ತೆರಡು', 'ಇಪ್ಪತ್ತಮೂರು', 'ಇಪ್ಪತ್ತನಾಲ್ಕು', 'ಇಪ್ಪತ್ತೈದು', 'ಇಪ್ಪತ್ತಾರು', 'ಇಪ್ಪತ್ತೇಳು', 'ಇಪ್ಪತ್ತೆಂಟು', 'ಇಪ್ಪತ್ತೊಂಬತ್ತು',\n 'ಮೂವತ್ತು', 'ಮೂವತ್ತೊಂದು', 'ಮೂವತ್ತೆರಡು', 'ಮೂವತ್ತಮೂರು', 'ಮೂವತ್ತನಾಲ್ಕು', 'ಮೂವತ್ತೈದು', 'ಮೂವತ್ತಾರು', 'ಮೂವತ್ತೇಳು', 'ಮೂವತ್ತೆಂಟು', 'ಮೂವತ್ತೊಂಬತ್ತು',\n 'ನಲವತ್ತು', 'ನಲವತ್ತೊಂದು', 'ನಲವತ್ತೆರಡು', 'ನಲವತ್ತಮೂರು', 'ನಲವತ್ತನಾಲ್ಕು', 'ನಲವತ್ತೈದು', 'ನಲವತ್ತಾರು', 'ನಲವತ್ತೇಳು', 'ನಲವತ್ತೆಂಟು', 'ನಲವತ್ತೊಂಬತ್ತು',\n 'ಐವತ್ತು', 'ಐವತ್ತೊಂದು', 'ಐವತ್ತೆರಡು', 'ಐವತ್ತಮೂರು', 'ಐವತ್ತನಾಲ್ಕು', 'ಐವತ್ತೈದು', 'ಐವತ್ತಾರು', 'ಐವತ್ತೇಳು', 'ಐವತ್ತೆಂಟು', 'ಐವತ್ತೊಂಬತ್ತು',\n 'ಅರವತ್ತು', 'ಅರವತ್ತೊಂದು', 'ಅರವತ್ತೆರಡು', 'ಅರವತ್ತಮೂರು', 'ಅರವತ್ತನಾಲ್ಕು', 'ಅರವತ್ತೈದು', 'ಅರವತ್ತಾರು', 'ಅರವತ್ತೇಳು', 'ಅರವತ್ತೆಂಟು', 'ಅರವತ್ತೊಂಬತ್ತು',\n 'ಎಪ್ಪತ್ತು', 'ಎಪ್ಪತ್ತೊಂದು', 'ಎಪ್ಪತ್ತೆರಡು', 'ಎಪ್ಪತ್ತಮೂರು', 'ಎಪ್ಪತ್ತನಾಲ್ಕು', 'ಎಪ್ಪತ್ತೈದು', 'ಎಪ್ಪತ್ತಾರು', 'ಎಪ್ಪತ್ತೇಳು', 'ಎಪ್ಪತ್ತೆಂಟು', 'ಎಪ್ಪತ್ತೊಂಬತ್ತು',\n 'ಎಂಬತ್ತು', 'ಎಂಬತ್ತೊಂದು', 'ಎಂಬತ್ತೆರಡು', 'ಎಂಬತ್ತಮೂರು', 'ಎಂಬತ್ತನಾಲ್ಕು', 'ಎಂಬತ್ತೈದು', 'ಎಂಬತ್ತಾರು', 'ಎಂಬತ್ತೇಳು', 'ಎಂಬತ್ತೆಂಟು', 'ಎಂಬತ್ತೊಂಬತ್ತು',\n 'ತೊಂಬತ್ತು', 'ತೊಂಬತ್ತೊಂದು', 'ತೊಂಬತ್ತೆರಡು', 'ತೊಂಬತ್ತಮೂರು', 'ತೊಂಬತ್ತನಾಲ್ಕು', 'ತೊಂಬತ್ತೈದು', 'ತೊಂಬತ್ತಾರು', 'ತೊಂಬತ್ತೇಳು', 'ತೊಂಬತ್ತೆಂಟು', 'ತೊಂಬತ್ತೊಂಬತ್ತು'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'ಸಾವಿರ', 'ಲಕ್ಷ', 'ಕೋಟಿ', 'ಅಬ್ಜ', 'ಖರ್ವ', 'ನೀಲ', 'ಪದ್ಮ', 'ಶಂಖ']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const segments = []\n segments.unshift(Number(numStr.slice(-3)))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n segments.unshift(Number(remaining.slice(-2)))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const segments = groupByThreeThenTwos(n)\n const segmentCount = segments.length\n const words = []\n\n for (let i = 0; i < segmentCount; i++) {\n const segmentValue = segments[i]\n if (segmentValue === 0) continue\n\n const scaleIndex = segmentCount - i - 1\n words.push(segmentToWords(segmentValue))\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : BELOW_HUNDRED[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Kannada words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Kannada words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Korean language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Myriad-based (만) grouping - 4 digits\n * - Implicit '일' (one) omission before scale words\n * - Space separation after 만+ scales\n * - Hangul numerals\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구']\n\nconst TEN = '십'\nconst HUNDRED = '백'\nconst THOUSAND = '천'\n\nconst ZERO = '영'\nconst NEGATIVE = '마이너스'\nconst DECIMAL_SEP = '점'\n\n// Myriad scale words (powers of 10,000)\n// 만 (10^4), 억 (10^8), 조 (10^12), 경 (10^16), etc.\nconst SCALES = ['만', '억', '조', '경', '해', '자', '양']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-9999 (4-digit myriad segment).\n * Korean omits \"일\" before 십, 백, 천.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100) % 10\n const thousands = Math.floor(n / 1000)\n\n let result = ''\n\n // Thousands\n if (thousands > 0) {\n if (thousands === 1) {\n result += THOUSAND\n } else {\n result += ONES[thousands] + THOUSAND\n }\n }\n\n // Hundreds\n if (hundreds > 0) {\n if (hundreds === 1) {\n result += HUNDRED\n } else {\n result += ONES[hundreds] + HUNDRED\n }\n }\n\n // Tens\n if (tens > 0) {\n if (tens === 1) {\n result += TEN\n } else {\n result += ONES[tens] + TEN\n }\n }\n\n // Ones\n if (ones > 0) {\n result += ONES[ones]\n }\n\n return result\n}\n\n// Precompute all 10000 segment words (0-9999) for myriad grouping\nconst SEGMENTS = new Array(10000)\n\nfor (let i = 0; i < 10000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Korean words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Korean words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 10000 (direct lookup)\n if (n < 10000n) {\n return SEGMENTS[Number(n)]\n }\n\n // For numbers >= 10000, use myriad decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 10000.\n * Uses myriad (만) grouping - 4 digits per segment.\n *\n * @param {bigint} n - Number >= 10000\n * @returns {string} Korean words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 4 digits from right to left\n const segments = []\n const segmentSize = 4\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n // Units segment (no scale word)\n parts.push({ word: SEGMENTS[segment], isScale: false })\n } else {\n // Segment with scale word\n const scaleWord = SCALES[scaleIndex - 1]\n\n // Korean omits segment when it's 1 before scale words\n if (segment === 1) {\n parts.push({ word: scaleWord, isScale: true })\n } else {\n parts.push({ word: SEGMENTS[segment], isScale: false })\n parts.push({ word: scaleWord, isScale: true })\n }\n }\n }\n\n scaleIndex--\n }\n\n // Join with Korean spacing rules\n return joinKoreanParts(parts)\n}\n\n/**\n * Joins parts with Korean spacing rules.\n * - Concatenate without spaces within segments\n * - Space after scale words before next number\n *\n * @param {Array} parts - Parts with isScale metadata\n * @returns {string} Joined string\n */\nfunction joinKoreanParts (parts) {\n if (parts.length === 0) return ZERO\n if (parts.length === 1) return parts[0].word\n\n const result = []\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const prevPart = i > 0 ? parts[i - 1] : null\n\n // Add space after scale words before next number\n if (prevPart && prevPart.isScale && !part.isScale) {\n result.push(' ')\n }\n\n result.push(part.word)\n }\n\n return result.join('')\n}\n\n/**\n * Converts decimal digits to Korean words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Korean words for decimal part (space-separated)\n */\nfunction decimalPartToWords (decimalPart) {\n const parts = []\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n parts.push(ZERO)\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n parts.push(integerToWords(BigInt(remainder)))\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts a numeric value to Korean words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Korean words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // '이십일'\n * toWords(10000) // '만'\n * toWords(1000000) // '백만'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n const parts = []\n\n if (isNegative) {\n parts.push(NEGATIVE)\n }\n\n parts.push(integerToWords(integerPart))\n\n if (decimalPart) {\n parts.push(DECIMAL_SEP)\n parts.push(decimalPartToWords(decimalPart))\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Lithuanian language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Three-form pluralization (singular/plural/genitive)\n * - Gender agreement (masculine/feminine for numbers < 1000)\n * - Two-form hundreds (šimtas/šimtai)\n * - Long scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES_MASC = ['', 'vienas', 'du', 'trys', 'keturi', 'penki', 'šeši', 'septyni', 'aštuoni', 'devyni']\nconst ONES_FEM = ['', 'viena', 'dvi', 'trys', 'keturios', 'penkios', 'šešios', 'septynios', 'aštuonios', 'devynios']\n\nconst TEENS = ['dešimt', 'vienuolika', 'dvylika', 'trylika', 'keturiolika', 'penkiolika', 'šešiolika', 'septyniolika', 'aštuoniolika', 'devyniolika']\nconst TENS = ['', '', 'dvidešimt', 'trisdešimt', 'keturiasdešimt', 'penkiasdešimt', 'šešiasdešimt', 'septyniasdešimt', 'aštuoniasdešimt', 'devyniasdešimt']\n\n// Hundreds: šimtas (singular), šimtai (plural)\nconst HUNDRED_SINGULAR = 'šimtas'\nconst HUNDRED_PLURAL = 'šimtai'\n\nconst ZERO = 'nulis'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'kablelis'\n\n// Scale words: [singular, plural, genitive]\nconst SCALE_FORMS = [\n ['tūkstantis', 'tūkstančiai', 'tūkstančių'],\n ['milijonas', 'milijonai', 'milijonų'],\n ['milijardas', 'milijardai', 'milijardų'],\n ['trilijonas', 'trilijonai', 'trilijonų'],\n ['kvadrilijonas', 'kvadrilijonai', 'kvadrilijonų'],\n ['kvintilijonas', 'kvintilijonai', 'kvintilijonų'],\n ['sikstilijonas', 'sikstilijonai', 'sikstilijonų'],\n ['septilijonas', 'septilijonai', 'septilijonų'],\n ['oktilijonas', 'oktilijonai', 'oktilijonų']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 (masculine form).\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - Lithuanian always includes the numeral\n if (hundreds > 0) {\n parts.push(ONES_MASC[hundreds])\n parts.push(hundreds === 1 ? HUNDRED_SINGULAR : HUNDRED_PLURAL)\n }\n\n // Tens\n if (tens > 1) {\n parts.push(TENS[tens])\n }\n\n // Teens or ones\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else if (ones > 0) {\n parts.push(ONES_MASC[ones])\n }\n\n return parts.join(' ')\n}\n\n/**\n * Builds segment word for 0-999 (feminine form - only differs in ones).\n */\nfunction buildSegmentFeminine (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - always masculine\n if (hundreds > 0) {\n parts.push(ONES_MASC[hundreds])\n parts.push(hundreds === 1 ? HUNDRED_SINGULAR : HUNDRED_PLURAL)\n }\n\n // Tens\n if (tens > 1) {\n parts.push(TENS[tens])\n }\n\n // Teens or ones - feminine for ones only\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else if (ones > 0) {\n parts.push(ONES_FEM[ones])\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS_MASC = new Array(1000)\nconst SEGMENTS_FEM = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_MASC[i] = buildSegment(i)\n SEGMENTS_FEM[i] = buildSegmentFeminine(i)\n}\n\n// ============================================================================\n// Pluralization\n// ============================================================================\n\n/**\n * Lithuanian pluralization rules.\n * - Singular: ends in 1 (except 11)\n * - Plural: ends in 2-9 (except 12-19)\n * - Genitive: 0, 10-19, or ends in 0\n *\n * @param {number} n - The segment value\n * @param {string[]} forms - [singular, plural, genitive]\n * @returns {string} The appropriate form\n */\nfunction pluralize (n, forms) {\n if (n === 0) return forms[2]\n\n const lastDigit = n % 10\n const lastTwoDigits = n % 100\n\n // 10-19 always use genitive\n if (lastTwoDigits >= 10 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n // Ends in 0 → genitive\n if (lastDigit === 0) {\n return forms[2]\n }\n\n // Ends in 1 → singular\n if (lastDigit === 1) {\n return forms[0]\n }\n\n // Ends in 2-9 → plural\n return forms[1]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Lithuanian words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Lithuanian words\n */\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n // For numbers >= 1000, feminine only applies to final segment if < 1000\n // But the fixture shows feminine NOT applying for n >= 1000\n // So we use masculine for all segments when n >= 1000\n return buildLargeNumberWords(n, options)\n}\n\n/**\n * Builds words for numbers >= 1000.\n *\n * @param {bigint} n - Number >= 1000\n * @param {Object} options - Conversion options\n * @returns {string} Lithuanian words\n */\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS_MASC[segment]\n\n if (scaleIndex === 0) {\n // Units segment - use masculine (feminine doesn't apply when n >= 1000)\n parts.push(segmentWord)\n } else {\n // Segment with scale word\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n parts.push(segmentWord + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts decimal digits to Lithuanian words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Lithuanian words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Lithuanian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Conversion options\n * @param {string} [options.gender='masculine'] - Gender for numbers < 1000\n * @returns {string} The number in Lithuanian words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // 'keturiasdešimt du'\n * toWords(1, { gender: 'feminine' }) // 'viena'\n * toWords(1000000) // 'vienas milijonas'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Latvian language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Two-form pluralization (singular for 1 except 11, plural otherwise)\n * - Gender agreement (masculine/feminine for numbers < 1000)\n * - Special hundreds forms (simts/simti/simtu)\n * - Omit \"one\" before scale words\n * - Long scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES_MASC = ['', 'viens', 'divi', 'trīs', 'četri', 'pieci', 'seši', 'septiņi', 'astoņi', 'deviņi']\nconst ONES_FEM = ['', 'viena', 'divas', 'trīs', 'četras', 'piecas', 'sešas', 'septiņas', 'astoņas', 'deviņas']\n\nconst TEENS = ['desmit', 'vienpadsmit', 'divpadsmit', 'trīspadsmit', 'četrpadsmit', 'piecpadsmit', 'sešpadsmit', 'septiņpadsmit', 'astoņpadsmit', 'deviņpadsmit']\nconst TENS = ['', '', 'divdesmit', 'trīsdesmit', 'četrdesmit', 'piecdesmit', 'sešdesmit', 'septiņdesmit', 'astoņdesmit', 'deviņdesmit']\n\n// Hundreds: simts (100, 110-199), simti (200-999), simtu (101-109)\nconst HUNDRED_SINGULAR = 'simts'\nconst HUNDRED_PLURAL = 'simti'\nconst HUNDRED_GENITIVE = 'simtu'\n\nconst ZERO = 'nulle'\nconst NEGATIVE = 'mīnus'\nconst DECIMAL_SEP = 'komats'\n\n// Scale words: [singular, plural, genitive]\nconst SCALE_FORMS = [\n ['tūkstotis', 'tūkstoši', 'tūkstošu'],\n ['miljons', 'miljoni', 'miljonu'],\n ['miljards', 'miljardi', 'miljardu'],\n ['triljons', 'triljoni', 'triljonu'],\n ['kvadriljons', 'kvadriljoni', 'kvadriljonu'],\n ['kvintiljons', 'kvintiljoni', 'kvintiljonu'],\n ['sikstiljons', 'sikstiljoni', 'sikstiljonu'],\n ['septiljons', 'septiljoni', 'septiljonu'],\n ['oktiljons', 'oktiljoni', 'oktiljonu']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 (masculine form).\n * Does NOT include special handling for segment=1 (omitOneBeforeScale).\n * That's handled at join time.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - Latvian has special forms\n if (hundreds > 0) {\n if (hundreds === 1 && tens === 0 && ones > 0) {\n // 101-109: use genitive form \"simtu\"\n parts.push(HUNDRED_GENITIVE)\n } else if (hundreds > 1) {\n // 200-999: use plural \"simti\"\n parts.push(ONES_MASC[hundreds])\n parts.push(HUNDRED_PLURAL)\n } else {\n // 100, 110-199: use singular \"simts\"\n parts.push(HUNDRED_SINGULAR)\n }\n }\n\n // Tens\n if (tens > 1) {\n parts.push(TENS[tens])\n }\n\n // Teens or ones\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else if (ones > 0) {\n parts.push(ONES_MASC[ones])\n }\n\n return parts.join(' ')\n}\n\n/**\n * Builds segment word for 0-999 (feminine form - only differs in ones).\n */\nfunction buildSegmentFeminine (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - always masculine\n if (hundreds > 0) {\n if (hundreds === 1 && tens === 0 && ones > 0) {\n parts.push(HUNDRED_GENITIVE)\n } else if (hundreds > 1) {\n parts.push(ONES_MASC[hundreds])\n parts.push(HUNDRED_PLURAL)\n } else {\n parts.push(HUNDRED_SINGULAR)\n }\n }\n\n // Tens\n if (tens > 1) {\n parts.push(TENS[tens])\n }\n\n // Teens or ones - feminine for ones only\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else if (ones > 0) {\n parts.push(ONES_FEM[ones])\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS_MASC = new Array(1000)\nconst SEGMENTS_FEM = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_MASC[i] = buildSegment(i)\n SEGMENTS_FEM[i] = buildSegmentFeminine(i)\n}\n\n// ============================================================================\n// Pluralization\n// ============================================================================\n\n/**\n * Latvian pluralization - simpler than Slavic.\n * Singular: ends in 1 (except 11)\n * Plural: everything else\n *\n * @param {number} n - The segment value\n * @param {string[]} forms - [singular, plural, genitive]\n * @returns {string} The appropriate form\n */\nfunction pluralize (n, forms) {\n if (n === 0) return forms[2]\n\n const lastDigit = n % 10\n const lastTwoDigits = n % 100\n\n if (lastDigit === 1 && lastTwoDigits !== 11) {\n return forms[0]\n }\n\n return forms[1]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Latvian words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Latvian words\n */\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n // For numbers >= 1000, feminine only applies to final segment if < 1000\n // But we use masculine for all segments when n >= 1000\n return buildLargeNumberWords(n, options)\n}\n\n/**\n * Builds words for numbers >= 1000.\n *\n * @param {bigint} n - Number >= 1000\n * @param {Object} options - Conversion options\n * @returns {string} Latvian words\n */\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS_MASC[segment]\n\n if (scaleIndex === 0) {\n // Units segment - use masculine (feminine doesn't apply when n >= 1000)\n parts.push(segmentWord)\n } else {\n // Segment with scale word\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n\n // Latvian omits \"one\" before scale words\n if (segment === 1) {\n parts.push(scaleWord)\n } else {\n parts.push(segmentWord + ' ' + scaleWord)\n }\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\n/**\n * Converts decimal digits to Latvian words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Latvian words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Latvian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Conversion options\n * @param {string} [options.gender='masculine'] - Gender for numbers < 1000\n * @returns {string} The number in Latvian words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // 'četrdesmit divi'\n * toWords(1, { gender: 'feminine' }) // 'viena'\n * toWords(1000) // 'tūkstotis'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Marathi language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (हजार, लाख, कोटी)\n * - Devanagari script\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'शून्य'\nconst NEGATIVE = 'उणे'\nconst DECIMAL_SEP = 'दशांश'\nconst HUNDRED = 'शंभर'\n\nconst BELOW_HUNDRED = [\n 'शून्य', 'एक', 'दोन', 'तीन', 'चार', 'पाच', 'सहा', 'सात', 'आठ', 'नऊ',\n 'दहा', 'अकरा', 'बारा', 'तेरा', 'चौदा', 'पंधरा', 'सोळा', 'सतरा', 'अठरा', 'एकोणीस',\n 'वीस', 'एकवीस', 'बावीस', 'तेवीस', 'चोवीस', 'पंचवीस', 'सव्वीस', 'सत्तावीस', 'अठ्ठावीस', 'एकोणतीस',\n 'तीस', 'एकतीस', 'बत्तीस', 'तेहेतीस', 'चौतीस', 'पस्तीस', 'छत्तीस', 'सदतीस', 'अडतीस', 'एकोणचाळीस',\n 'चाळीस', 'एकेचाळीस', 'बेचाळीस', 'त्रेचाळीस', 'चव्वेचाळीस', 'पंचेचाळीस', 'सेहेचाळीस', 'सत्तेचाळीस', 'अठ्ठेचाळीस', 'एकोणपन्नास',\n 'पन्नास', 'एक्काव्वन', 'बावन्न', 'त्रेपन्न', 'चोपन्न', 'पंचाव्वन', 'छप्पन्न', 'सत्तावन्न', 'अठ्ठावन्न', 'एकोणसाठ',\n 'साठ', 'एकसष्ठ', 'बासष्ठ', 'त्रेसष्ठ', 'चौसष्ठ', 'पासष्ठ', 'सहासष्ठ', 'सदुसष्ठ', 'अडुसष्ठ', 'एकोणसत्तर',\n 'सत्तर', 'एकाहत्तर', 'बाहत्तर', 'त्र्याहत्तर', 'चौऱ्याहत्तर', 'पंच्याहत्तर', 'शहात्तर', 'सत्याहत्तर', 'अठ्ठ्याहत्तर', 'एकोणऐंशी',\n 'ऐंशी', 'एक्याऐंशी', 'ब्याऐंशी', 'त्र्याऐंशी', 'चौऱ्याऐंशी', 'पंच्याऐंशी', 'शहाऐंशी', 'सत्याऐंशी', 'अठ्ठ्याऐंशी', 'एकोणनव्वद',\n 'नव्वद', 'एक्याण्णव', 'ब्याण्णव', 'त्र्याण्णव', 'चौऱ्याण्णव', 'पंच्याण्णव', 'शहाण्णव', 'सत्याण्णव', 'अठ्ठ्याण्णव', 'नव्याण्णव'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'हजार', 'लाख', 'कोटी', 'अब्ज', 'खर्व', 'निखर्व', 'महापद्म', 'शंकू']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n if (numStr.length <= 3) return [Number(numStr)]\n\n const segments = []\n segments.unshift(Number(numStr.slice(-3)))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n segments.unshift(Number(remaining.slice(-2)))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const segments = groupByThreeThenTwos(n)\n const segmentCount = segments.length\n const words = []\n\n for (let i = 0; i < segmentCount; i++) {\n const segmentValue = segments[i]\n if (segmentValue === 0) continue\n\n const scaleIndex = segmentCount - i - 1\n words.push(segmentToWords(segmentValue))\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : BELOW_HUNDRED[d])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Marathi words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Marathi words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Malay (Bahasa Melayu) language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - \"Se-\" prefix for ALL singular scale units (seratus, seribu, sejuta, sebilion)\n * - Regular patterns (puluh for tens, ratus for hundreds)\n * - Teens with \"belas\" suffix\n * - Note: \"lapan\" (8) differs from Indonesian \"delapan\"\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'lapan', 'sembilan']\nconst TEENS = ['sepuluh', 'sebelas', 'dua belas', 'tiga belas', 'empat belas', 'lima belas', 'enam belas', 'tujuh belas', 'lapan belas', 'sembilan belas']\nconst TENS = ['', '', 'dua puluh', 'tiga puluh', 'empat puluh', 'lima puluh', 'enam puluh', 'tujuh puluh', 'lapan puluh', 'sembilan puluh']\n\nconst HUNDRED_WORD = 'ratus'\nconst THOUSAND_WORD = 'ribu'\nconst SCALE_WORDS = ['juta', 'bilion', 'trilion']\n\nconst ZERO = 'sifar'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'perpuluhan'\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds: seratus (100) or N ratus (200-900)\n if (hundredsDigit > 0) {\n if (hundredsDigit === 1) {\n parts.push('se' + HUNDRED_WORD)\n } else {\n parts.push(ONES[hundredsDigit] + ' ' + HUNDRED_WORD)\n }\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[tensOnes])\n } else if (tensOnes < 20) {\n parts.push(TEENS[tensOnes - 10])\n } else if (onesDigit === 0) {\n parts.push(TENS[tensDigit])\n } else {\n parts.push(TENS[tensDigit] + ' ' + ONES[onesDigit])\n }\n\n return parts.join(' ')\n}\n\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n result = 'se' + THOUSAND_WORD\n } else {\n result = SEGMENTS[thousands] + ' ' + THOUSAND_WORD\n }\n\n if (remainder > 0) {\n result += ' ' + SEGMENTS[remainder]\n }\n\n return result\n }\n\n return buildLargeNumberWords(n)\n}\n\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n parts.push(SEGMENTS[segment])\n } else if (scaleIndex === 1) {\n if (segment === 1) {\n parts.push('se' + THOUSAND_WORD)\n } else {\n parts.push(SEGMENTS[segment] + ' ' + THOUSAND_WORD)\n }\n } else {\n // Malay: \"se-\" prefix for ALL scale words when segment is 1\n const scaleWord = SCALE_WORDS[scaleIndex - 2]\n if (segment === 1) {\n parts.push('se' + scaleWord)\n } else {\n parts.push(SEGMENTS[segment] + ' ' + scaleWord)\n }\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Malay words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Malay words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Norwegian Bokmål language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Hyphenated tens+ones: \"tjue-en\" (21)\n * - \"og\" conjunction after hundreds\n * - Comma separator after thousands before hundreds\n * - Short scale: million, milliard, billion, etc.\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'en', 'to', 'tre', 'fire', 'fem', 'seks', 'syv', 'åtte', 'ni']\n\nconst TEENS = ['ti', 'elleve', 'tolv', 'tretten', 'fjorten', 'femten', 'seksten', 'sytten', 'atten', 'nitten']\nconst TENS = ['', '', 'tjue', 'tretti', 'førti', 'femti', 'seksti', 'sytti', 'åtti', 'nitti']\n\nconst HUNDRED = 'hundre'\nconst THOUSAND = 'tusen'\n\nconst ZERO = 'null'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'komma'\n\n// Short scale: million, milliard, billion, etc.\nconst SCALES = ['million', 'milliard', 'billion', 'billiard', 'kvintillion', 'sekstillion', 'septillion', 'oktillion']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Returns object with word and hasHundred flag.\n */\nfunction buildSegment (n) {\n if (n === 0) return { word: '', hasHundred: false }\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n let hasHundred = false\n\n // Hundreds: \"en hundre\", \"to hundre\"\n if (hundreds > 0) {\n hasHundred = true\n parts.push(ONES[hundreds] + ' ' + HUNDRED)\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n // Teens\n parts.push(TEENS[ones])\n } else if (ones === 0) {\n // Even tens\n parts.push(TENS[tens])\n } else {\n // Hyphenated: \"tjue-en\"\n parts.push(TENS[tens] + '-' + ONES[ones])\n }\n\n // Combine with \" og \" between hundreds and remainder\n if (parts.length === 2) {\n return { word: parts[0] + ' og ' + parts[1], hasHundred: true }\n }\n return { word: parts[0] || '', hasHundred }\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_HAS_HUNDRED = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n SEGMENTS_HAS_HUNDRED[i] = result.hasHundred\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Norwegian Bokmål words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Norwegian words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result = SEGMENTS[thousands] + ' ' + THOUSAND\n\n if (remainder > 0) {\n // Comma before hundreds, \" og \" before small numbers\n if (SEGMENTS_HAS_HUNDRED[remainder]) {\n result += ', ' + SEGMENTS[remainder]\n } else {\n result += ' og ' + SEGMENTS[remainder]\n }\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Norwegian words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = SEGMENTS[segment]\n const hasHundred = SEGMENTS_HAS_HUNDRED[segment]\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push({ word: segmentWord, hasHundred, type: 'units' })\n } else if (scaleIndex === 1) {\n // Thousands\n parts.push({ word: segmentWord + ' ' + THOUSAND, hasHundred: false, type: 'thousand' })\n } else {\n // Millions+\n const scaleWord = SCALES[scaleIndex - 2]\n parts.push({ word: segmentWord + ' ' + scaleWord, hasHundred: false, type: 'million' })\n }\n }\n\n scaleIndex--\n }\n\n // Join parts with Norwegian rules\n return joinNorwegianParts(parts)\n}\n\n/**\n * Joins parts with Norwegian spacing and comma rules.\n *\n * @param {Array} parts - Parts with type metadata\n * @returns {string} Joined string\n */\nfunction joinNorwegianParts (parts) {\n if (parts.length === 0) return ZERO\n if (parts.length === 1) return parts[0].word\n\n const result = []\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const nextPart = parts[i + 1]\n\n result.push(part.word)\n\n if (nextPart) {\n if (part.type === 'thousand') {\n // After thousands: comma if next has hundred, else \" og \"\n if (nextPart.hasHundred) {\n result.push(', ')\n } else {\n result.push(' og ')\n }\n } else if (part.type === 'million') {\n // After millions: \" og \" for units without hundred, space otherwise\n if (nextPart.type === 'units' && !nextPart.hasHundred) {\n result.push(' og ')\n } else {\n result.push(' ')\n }\n } else {\n result.push(' ')\n }\n }\n }\n\n return result.join('')\n}\n\n/**\n * Converts decimal digits to Norwegian words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Norwegian words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Norwegian Bokmål words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Norwegian words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'tjue-en'\n * toWords(101) // 'en hundre og en'\n * toWords(1000000) // 'en million'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Dutch language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Dutch-specific rules (handled in precomputation):\n * - Inverted tens-ones: eenentwintig (one-and-twenty)\n * - \"ën\" connector when ones ends in 'e' (twee, drie)\n * - Compound words without spaces\n * - Hundred pairing for 1100-9999 (elfhonderd style)\n * - \"één\" vs \"een\" (accentOne option)\n * - Optional \"en\" separator (includeOptionalAnd option)\n * - Long scale with -ard forms\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'een', 'twee', 'drie', 'vier', 'vijf', 'zes', 'zeven', 'acht', 'negen']\nconst TEENS = ['tien', 'elf', 'twaalf', 'dertien', 'veertien', 'vijftien', 'zestien', 'zeventien', 'achttien', 'negentien']\nconst TENS = ['', '', 'twintig', 'dertig', 'veertig', 'vijftig', 'zestig', 'zeventig', 'tachtig', 'negentig']\n\nconst HUNDRED = 'honderd'\n\n// Scale words (long scale with -ard forms)\nconst SCALES = ['duizend', 'miljoen', 'miljard', 'biljoen', 'biljard', 'triljoen', 'triljard', 'quadriljoen', 'quadriljard']\n\nconst ZERO = 'nul'\nconst NEGATIVE = 'min'\nconst DECIMAL_SEP = 'komma'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * @param {number} n - Segment value\n * @param {boolean} withAnd - Include \"en\" for values < 13 after hundreds\n * @returns {string} Dutch word (compound, no spaces)\n */\nfunction buildSegment (n, withAnd) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n const tensOnes = n % 100\n\n let result = ''\n\n // Hundreds\n if (hundreds > 0) {\n if (hundreds === 1) {\n result = HUNDRED\n } else {\n result = ONES[hundreds] + HUNDRED\n }\n }\n\n // Tens and ones\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n // Single digit - add \"en\" if withAnd and after hundreds\n if (hundreds > 0 && withAnd) {\n result += 'en' + ONES[tensOnes]\n } else {\n result += ONES[tensOnes]\n }\n } else if (tensOnes < 20) {\n // Teens - add \"en\" if withAnd and after hundreds and < 13\n if (hundreds > 0 && withAnd && tensOnes < 13) {\n result += 'en' + TEENS[ones]\n } else {\n result += TEENS[ones]\n }\n } else {\n // 20-99: Dutch inverts with connector\n if (ones === 0) {\n result += TENS[tens]\n } else {\n // \"ën\" if ones ends in 'e' (twee, drie)\n const onesWord = ONES[ones]\n const connector = onesWord.endsWith('e') ? 'ën' : 'en'\n result += onesWord + connector + TENS[tens]\n }\n }\n\n return result\n}\n\n// Precompute all 1000 segment words (0-999) - standard form\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i, false)\n}\n\n// Precompute all 1000 segment words (0-999) - with optional \"en\"\nconst SEGMENTS_WITH_AND = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_WITH_AND[i] = buildSegment(i, true)\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Dutch words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Dutch words\n */\nfunction integerToWords (n, options) {\n if (n === 0n) return ZERO\n\n const { accentOne, includeOptionalAnd, noHundredPairing } = options\n const segments = includeOptionalAnd ? SEGMENTS_WITH_AND : SEGMENTS\n\n // Apply één/een replacement\n const applyAccent = (word) => {\n if (accentOne) {\n return word.replace(/\\been\\b/g, 'één')\n }\n return word\n }\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return applyAccent(segments[Number(n)])\n }\n\n // Hundred pairing for 1100-9999\n if (!noHundredPairing && n >= 1100n && n < 10000n) {\n const high = Number(n / 100n)\n const low = Number(n % 100n)\n\n // Only use pairing when high is not a multiple of 10\n if (high % 10 !== 0) {\n let result = segments[high] + HUNDRED\n if (low > 0) {\n const lowWord = segments[low]\n if (includeOptionalAnd && low < 13) {\n result += ' en ' + lowWord\n } else {\n result += ' ' + lowWord\n }\n }\n return applyAccent(result)\n }\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n // \"duizend\" not \"eenduizend\"\n result = SCALES[0]\n } else {\n // Compound: \"vijfduizend\"\n result = segments[thousands] + SCALES[0]\n }\n\n if (remainder > 0) {\n const remainderWord = segments[remainder]\n if (includeOptionalAnd && remainder < 13) {\n result += ' en ' + remainderWord\n } else {\n result += ' ' + remainderWord\n }\n }\n\n return applyAccent(result)\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return applyAccent(buildLargeNumberWords(n, options))\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction (4x faster than string slicing).\n *\n * @param {bigint} n - Number >= 1,000,000\n * @param {Object} options - Conversion options\n * @returns {string} Dutch words\n */\nfunction buildLargeNumberWords (n, options) {\n const { includeOptionalAnd } = options\n const segmentLookup = includeOptionalAnd ? SEGMENTS_WITH_AND : SEGMENTS\n\n // Extract segments using BigInt division (faster than string slicing)\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Build result string directly (avoids object allocation and join)\n let result = ''\n let prevWasScale = false\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0) continue\n\n if (i === 0) {\n // Units segment\n const word = segmentLookup[segment]\n if (result) {\n if (prevWasScale && includeOptionalAnd && segment < 13) {\n result += ' en ' + word\n } else {\n result += ' ' + word\n }\n } else {\n result = word\n }\n prevWasScale = false\n } else if (i === 1) {\n // Thousands - compound\n if (result) result += ' '\n if (segment === 1) {\n result += SCALES[0]\n } else {\n result += segmentLookup[segment] + SCALES[0]\n }\n prevWasScale = true\n } else {\n // Million and above - space around scale\n const scaleWord = SCALES[i - 1]\n if (result) result += ' '\n if (segment === 1) {\n result += 'een ' + scaleWord\n } else {\n result += segmentLookup[segment] + ' ' + scaleWord\n }\n prevWasScale = true\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Dutch words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Dutch words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n const word = integerToWords(BigInt(remainder), { ...options, noHundredPairing: true })\n result += word\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Dutch words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.accentOne=true] - Use \"één\" instead of \"een\"\n * @param {boolean} [options.includeOptionalAnd=false] - Include \"en\" before small numbers\n * @param {boolean} [options.noHundredPairing=false] - Disable hundred pairing (1104→duizend honderdvier)\n * @returns {string} The number in Dutch words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'eenentwintig'\n * toWords(1) // 'één'\n * toWords(1, {accentOne: false}) // 'een'\n * toWords(1104) // 'elfhonderd vier'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n const opts = {\n accentOne: options.accentOne !== false, // default true\n includeOptionalAnd: options.includeOptionalAnd || false,\n noHundredPairing: options.noHundredPairing || false\n }\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, opts)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, opts)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Punjabi language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (ਹਜ਼ਾਰ, ਲੱਖ, ਕਰੋੜ)\n * - Gurmukhi script\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'ਸਿਫ਼ਰ'\nconst NEGATIVE = 'ਮਾਇਨਸ'\nconst DECIMAL_SEP = 'ਦਸ਼ਮਲਵ'\nconst HUNDRED = 'ਸੌ'\n\nconst BELOW_HUNDRED = [\n 'ਸਿਫ਼ਰ', 'ਇੱਕ', 'ਦੋ', 'ਤਿੰਨ', 'ਚਾਰ', 'ਪੰਜ', 'ਛੇ', 'ਸੱਤ', 'ਅੱਠ', 'ਨੌਂ',\n 'ਦੱਸ', 'ਗਿਆਰਾਂ', 'ਬਾਰਾਂ', 'ਤੇਰਾਂ', 'ਚੌਦਾਂ', 'ਪੰਦਰਾਂ', 'ਸੋਲਾਂ', 'ਸਤਾਰਾਂ', 'ਅਠਾਰਾਂ', 'ਉੱਨੀ',\n 'ਵੀਹ', 'ਇੱਕੀ', 'ਬਾਈ', 'ਤੇਈ', 'ਚੌਬੀ', 'ਪੱਚੀ', 'ਛੱਬੀ', 'ਸਤਾਈ', 'ਅਠਾਈ', 'ਉਨੱਤੀ',\n 'ਤੀਹ', 'ਇਕੱਤੀ', 'ਬੱਤੀ', 'ਤੇਤੀ', 'ਚੌਂਤੀ', 'ਪੈਂਤੀ', 'ਛੱਤੀ', 'ਸੈਂਤੀ', 'ਅਠੱਤੀ', 'ਉਨਤਾਲੀ',\n 'ਚਾਲੀ', 'ਇਕਤਾਲੀ', 'ਬਿਆਲੀ', 'ਤਿਰਤਾਲੀ', 'ਚੁਵਾਲੀ', 'ਪੰਤਾਲੀ', 'ਛਿਆਲੀ', 'ਸੈਂਤਾਲੀ', 'ਅਠਤਾਲੀ', 'ਉਨੰਜਾ',\n 'ਪੰਜਾਹ', 'ਇਕਵੰਜਾ', 'ਬਵੰਜਾ', 'ਤਰਵੰਜਾ', 'ਚੁਰਵੰਜਾ', 'ਪੰਜਵੰਜਾ', 'ਛਪੰਜਾ', 'ਸੱਤਵੰਜਾ', 'ਅਠਵੰਜਾ', 'ਉਨਾਹਠ',\n 'ਸੱਠ', 'ਇਕਾਹਠ', 'ਬਾਹਠ', 'ਤਰਸਠ', 'ਚੌਂਸਠ', 'ਪੈਂਸਠ', 'ਛਿਆਸਠ', 'ਸੜਸਠ', 'ਅੜਸਠ', 'ਉਣਹੱਤਰ',\n 'ਸਤੱਰ', 'ਇਕਹੱਤਰ', 'ਬਹੱਤਰ', 'ਤਹੱਤਰ', 'ਚੌਹੱਤਰ', 'ਪੰਝਹੱਤਰ', 'ਛਿਹੱਤਰ', 'ਸਤੱਤਰ', 'ਅਠੱਤਰ', 'ਉਨਾਸੀ',\n 'ਅੱਸੀ', 'ਇਕਿਆਸੀ', 'ਬਿਆਸੀ', 'ਤਰਿਆਸੀ', 'ਚੌਰਿਆਸੀ', 'ਪਚਾਸੀ', 'ਛਿਆਸੀ', 'ਸੱਤਾਸੀ', 'ਅਠਾਸੀ', 'ਨਵਾਸੀ',\n 'ਨੱਬੇ', 'ਇਕਾਨਵੇਂ', 'ਬਾਨਵੇਂ', 'ਤਰਾਨਵੇਂ', 'ਚੁਰਾਨਵੇਂ', 'ਪੰਚਾਨਵੇਂ', 'ਛਿਆਨਵੇਂ', 'ਸਤਾਨਵੇਂ', 'ਅਠਾਨਵੇਂ', 'ਨਿਨਾਨਵੇਂ'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'ਹਜ਼ਾਰ', 'ਲੱਖ', 'ਕਰੋੜ', 'ਅਰਬ', 'ਖਰਬ', 'ਨੀਲ', 'ਪਦਮ', 'ਸ਼ੰਖ']\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts 0-999 to Punjabi words.\n */\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n/**\n * Converts a non-negative integer to Punjabi words.\n * Uses recursive approach for Indian 3-2-2 grouping pattern.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Punjabi words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return segmentToWords(Number(n))\n }\n\n return buildLargeNumberWords(n, 0)\n}\n\n/**\n * Recursively builds words for numbers >= 1000.\n * Indian grouping: first 3 digits, then 2-digit groups.\n *\n * @param {bigint} n - Number to convert\n * @param {number} scale - Current scale index (0=units, 1=thousands, etc.)\n * @returns {string} Punjabi words\n */\nfunction buildLargeNumberWords (n, scale) {\n if (n === 0n) return ''\n\n // Determine divisor: 1000 for first split, 100 for rest\n const divisor = scale === 0 ? 1000n : 100n\n const segment = Number(n % divisor)\n const rest = n / divisor\n\n // Build higher segments first (recursive)\n let result = ''\n if (rest > 0n) {\n result = buildLargeNumberWords(rest, scale + 1)\n }\n\n // Add current segment\n if (segment > 0) {\n if (result) result += ' '\n\n if (scale === 0) {\n // Units segment (0-999)\n result += segmentToWords(segment)\n } else {\n // Scale segments (0-99)\n result += BELOW_HUNDRED[segment] + ' ' + SCALE_WORDS[scale]\n }\n }\n\n return result\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Punjabi words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Punjabi words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Polish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Polish-specific rules (handled in precomputation):\n * - Three-form pluralization: 1 = singular, 2-4 = few, 5+ = many\n * - Gender agreement (masculine/feminine for numbers < 1000)\n * - Omit \"jeden\" before scale words (tysiąc, milion, etc.)\n * - Irregular hundreds: dwieście, trzysta, czterysta, pięćset...\n * - Long scale with -ard forms: miliard, biliard, tryliard\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES_MASC = ['', 'jeden', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć', 'siedem', 'osiem', 'dziewięć']\nconst ONES_FEM = ['', 'jedna', 'dwie', 'trzy', 'cztery', 'pięć', 'sześć', 'siedem', 'osiem', 'dziewięć']\n\nconst TEENS = ['dziesięć', 'jedenaście', 'dwanaście', 'trzynaście', 'czternaście', 'piętnaście', 'szesnaście', 'siedemnaście', 'osiemnaście', 'dziewiętnaście']\n\nconst TENS = ['', '', 'dwadzieścia', 'trzydzieści', 'czterdzieści', 'pięćdziesiąt', 'sześćdziesiąt', 'siedemdziesiąt', 'osiemdziesiąt', 'dziewięćdziesiąt']\n\n// Irregular hundreds\nconst HUNDREDS = ['', 'sto', 'dwieście', 'trzysta', 'czterysta', 'pięćset', 'sześćset', 'siedemset', 'osiemset', 'dziewięćset']\n\n// Scale words: [singular, few (2-4), many (5+)]\nconst PLURAL_FORMS = {\n 1: ['tysiąc', 'tysiące', 'tysięcy'],\n 2: ['milion', 'miliony', 'milionów'],\n 3: ['miliard', 'miliardy', 'miliardów'],\n 4: ['bilion', 'biliony', 'bilionów'],\n 5: ['biliard', 'biliardy', 'biliardów'],\n 6: ['trylion', 'tryliony', 'trylionów'],\n 7: ['tryliard', 'tryliardy', 'tryliardów'],\n 8: ['kwadrylion', 'kwadryliony', 'kwadrylionów'],\n 9: ['kwaryliard', 'kwadryliardy', 'kwadryliardów'],\n 10: ['kwintylion', 'kwintyliony', 'kwintylionów']\n}\n\nconst ZERO = 'zero'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'przecinek'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 (masculine form).\n * @param {number} n - Segment value\n * @returns {string} Polish word\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens (10-19)\n parts.push(TEENS[ones])\n } else {\n if (tens >= 2) {\n parts.push(TENS[tens])\n }\n if (ones > 0) {\n parts.push(ONES_MASC[ones])\n }\n }\n\n return parts.join(' ')\n}\n\n/**\n * Builds segment word for 0-999 (feminine form - only differs in ones).\n * @param {number} n - Segment value\n * @returns {string} Polish word\n */\nfunction buildSegmentFeminine (n) {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones - feminine for ones only\n if (tens === 1) {\n parts.push(TEENS[ones])\n } else {\n if (tens >= 2) {\n parts.push(TENS[tens])\n }\n if (ones > 0) {\n parts.push(ONES_FEM[ones])\n }\n }\n\n return parts.join(' ')\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS_MASC = new Array(1000)\nconst SEGMENTS_FEM = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS_MASC[i] = buildSegment(i)\n SEGMENTS_FEM[i] = buildSegmentFeminine(i)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Polish pluralization: 1 = singular, 2-4 = few, else = many.\n * Special case: 11-19 always use many form.\n *\n * @param {bigint} n - Number to pluralize\n * @param {string[]} forms - [singular, few, many]\n * @returns {string} Correct plural form\n */\nfunction pluralize (n, forms) {\n if (n === 1n) {\n return forms[0]\n }\n\n const lastDigit = n % 10n\n const lastTwoDigits = n % 100n\n\n // Teens (11-19) always use many form\n // 2-4 use few form (but not 12-14)\n if (lastDigit >= 2n && lastDigit <= 4n && (lastTwoDigits < 10n || lastTwoDigits > 20n)) {\n return forms[1]\n }\n\n return forms[2]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Polish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Polish words\n */\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n const scaleWord = pluralize(BigInt(thousands), PLURAL_FORMS[1])\n\n let result\n if (thousands === 1) {\n // Omit \"jeden\" before tysiąc\n result = scaleWord\n } else {\n result = SEGMENTS_MASC[thousands] + ' ' + scaleWord\n }\n\n if (remainder > 0) {\n result += ' ' + SEGMENTS_MASC[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n, options)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @param {Object} options - Conversion options\n * @returns {string} Polish words\n */\nfunction buildLargeNumberWords (n, options) {\n // Extract segments using BigInt division (faster than string slicing)\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(temp % 1000n)\n temp = temp / 1000n\n }\n\n // Build result string directly\n let result = ''\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0n) continue\n\n const segmentWord = SEGMENTS_MASC[Number(segment)]\n\n if (result) result += ' '\n\n if (i === 0) {\n // Units segment\n result += segmentWord\n } else {\n // Scale word needed\n const forms = PLURAL_FORMS[i]\n if (forms) {\n const scaleWord = pluralize(segment, forms)\n\n if (segment === 1n) {\n // Omit \"jeden\" before scale words\n result += scaleWord\n } else {\n result += segmentWord + ' ' + scaleWord\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Polish words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Polish words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Polish words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Conversion options\n * @param {string} [options.gender='masculine'] - Gender for numbers < 1000\n * @returns {string} The number in Polish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(1) // 'jeden'\n * toWords(1, { gender: 'feminine' }) // 'jedna'\n * toWords(1000) // 'tysiąc'\n * toWords(2000) // 'dwa tysiące'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Portuguese language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Portuguese-specific rules (handled in precomputation):\n * - \"e\" conjunction everywhere: vinte e um, cento e um, mil e um\n * - \"cem\" for exact 100, \"cento\" for 100+ remainder\n * - Irregular hundreds: duzentos, trezentos, quatrocentos, etc.\n * - Compound scale: milhão (10^6), mil milhões (10^9), bilião (10^12)\n * - Omit \"um\" before \"mil\"\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'um', 'dois', 'três', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove']\nconst TEENS = ['dez', 'onze', 'doze', 'treze', 'catorze', 'quinze', 'dezasseis', 'dezassete', 'dezoito', 'dezanove']\nconst TENS = ['', '', 'vinte', 'trinta', 'quarenta', 'cinquenta', 'sessenta', 'setenta', 'oitenta', 'noventa']\n\n// Irregular hundreds\nconst HUNDREDS = ['', 'cento', 'duzentos', 'trezentos', 'quatrocentos', 'quinhentos', 'seiscentos', 'setecentos', 'oitocentos', 'novecentos']\n\nconst THOUSAND = 'mil'\nconst ZERO = 'zero'\nconst NEGATIVE = 'menos'\nconst DECIMAL_SEP = 'vírgula'\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999 with Portuguese \"e\" rules.\n * Returns the word and whether it's an exact hundred (for \"cem\" handling).\n */\nfunction buildSegment (n) {\n if (n === 0) return { word: '', isExactHundred: false }\n\n // Special case: exact 100 is \"cem\"\n if (n === 100) return { word: 'cem', isExactHundred: true }\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds\n if (hundreds > 0) {\n parts.push(HUNDREDS[hundreds])\n }\n\n // Tens and ones\n if (tens === 1) {\n // Teens (10-19)\n parts.push(TEENS[ones])\n } else if (tens >= 2) {\n if (ones > 0) {\n // Tens + ones with \"e\": \"vinte e um\"\n parts.push(TENS[tens] + ' e ' + ONES[ones])\n } else {\n parts.push(TENS[tens])\n }\n } else if (ones > 0) {\n parts.push(ONES[ones])\n }\n\n // Join hundreds with \"e\": \"cento e um\", \"duzentos e trinta e um\"\n const word = parts.join(' e ')\n\n return { word, isExactHundred: hundreds > 0 && tens === 0 && ones === 0 }\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_STARTS_WITH_HUNDREDS = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n // Precompute whether segment starts with hundreds (100-999)\n SEGMENTS_STARTS_WITH_HUNDREDS[i] = i >= 100\n}\n\n// ============================================================================\n// Scale Word Lookup (precomputed for common scales)\n// ============================================================================\n\n// Precompute scale words for singular and plural forms\n// Index 1 = thousands, 2 = millions, 3 = billions (mil milhões), etc.\nconst SCALE_WORDS_SINGULAR = [\n '', // 0 unused\n THOUSAND, // 1: mil\n 'milhão', // 2: 10^6\n 'mil milhões', // 3: 10^9 (compound)\n 'bilião', // 4: 10^12\n 'mil biliões', // 5: 10^15 (compound)\n 'trilião', // 6: 10^18\n 'mil triliões', // 7: 10^21 (compound)\n 'quatrilião' // 8: 10^24\n]\n\nconst SCALE_WORDS_PLURAL = [\n '', // 0 unused\n THOUSAND, // 1: mil (same)\n 'milhões', // 2: 10^6\n 'mil milhões', // 3: 10^9 (compound, same)\n 'biliões', // 4: 10^12\n 'mil biliões', // 5: 10^15 (compound, same)\n 'triliões', // 6: 10^18\n 'mil triliões', // 7: 10^21 (compound, same)\n 'quatriliões' // 8: 10^24\n]\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Portuguese words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Portuguese words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n let result\n if (thousands === 1) {\n // \"mil\" not \"um mil\"\n result = THOUSAND\n } else {\n result = SEGMENTS[thousands] + ' ' + THOUSAND\n }\n\n if (remainder > 0) {\n // Insert \"e\" before remainder if it doesn't start with hundreds (< 100)\n if (!SEGMENTS_STARTS_WITH_HUNDREDS[remainder]) {\n result += ' e ' + SEGMENTS[remainder]\n } else {\n result += ' ' + SEGMENTS[remainder]\n }\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Portuguese words\n */\nfunction buildLargeNumberWords (n) {\n // Extract segments using BigInt division\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Find the first non-zero segment index (lowest scale with value)\n let firstNonZeroIdx = 0\n for (let i = 0; i < segments.length; i++) {\n if (segments[i] !== 0) {\n firstNonZeroIdx = i\n break\n }\n }\n\n // Build result string directly\n let result = ''\n let prevWasScale = false\n\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i]\n if (segment === 0) continue\n\n const segmentWord = SEGMENTS[segment]\n const isLastSegment = (i === firstNonZeroIdx)\n\n // Add \"e\" before final segment if previous was scale and this doesn't start with hundreds\n if (result && isLastSegment && prevWasScale && !SEGMENTS_STARTS_WITH_HUNDREDS[segment]) {\n result += ' e'\n }\n\n if (result) result += ' '\n\n if (i === 0) {\n // Units segment\n result += segmentWord\n prevWasScale = false\n } else if (i === 1) {\n // Thousands\n if (segment === 1) {\n result += THOUSAND\n } else {\n result += segmentWord + ' ' + THOUSAND\n }\n prevWasScale = true\n } else {\n // Million and above - use precomputed scale arrays\n const scaleWord = segment === 1 ? SCALE_WORDS_SINGULAR[i] : SCALE_WORDS_PLURAL[i]\n if (segment === 1) {\n result += 'um ' + scaleWord\n } else {\n result += segmentWord + ' ' + scaleWord\n }\n prevWasScale = true\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Portuguese words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Portuguese words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Portuguese words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Portuguese words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'vinte e um'\n * toWords(100) // 'cem'\n * toWords(1000000) // 'um milhão'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Romanian language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Gender agreement (unu/una, doi/două)\n * - \"De\" preposition insertion for groups >= 20\n * - Complex scale word handling (mie/mii, milion/milioane)\n * - Feminine units for thousands\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES_MASC = ['', 'unu', 'doi', 'trei', 'patru', 'cinci', 'șase', 'șapte', 'opt', 'nouă']\nconst ONES_FEM = ['', 'una', 'două', 'trei', 'patru', 'cinci', 'șase', 'șapte', 'opt', 'nouă']\n\nconst TEENS = ['zece', 'unsprezece', 'douăsprezece', 'treisprezece', 'paisprezece', 'cincisprezece', 'șaisprezece', 'șaptesprezece', 'optsprezece', 'nouăsprezece']\nconst TEENS_MASC = ['zece', 'unsprezece', 'doisprezece', 'treisprezece', 'paisprezece', 'cincisprezece', 'șaisprezece', 'șaptesprezece', 'optsprezece', 'nouăsprezece']\n\nconst TWENTIES = ['', '', 'douăzeci', 'treizeci', 'patruzeci', 'cincizeci', 'șaizeci', 'șaptezeci', 'optzeci', 'nouăzeci']\n\nconst HUNDREDS = ['', 'o sută', 'două sute', 'trei sute', 'patru sute', 'cinci sute', 'șase sute', 'șapte sute', 'opt sute', 'nouă sute']\n\nconst ZERO = 'zero'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'virgulă'\n\n// Scale metadata: [singular, plural, article, feminine, needsDe]\n// - singular: form for 1\n// - plural: form for 2+\n// - article: 'o' for feminine, 'un' for masculine\n// - feminine: whether units should be feminine\n// - needsDe: whether \"de\" is inserted for segment >= 20\nconst SCALE_META = [\n { singular: 'mie', plural: 'mii', article: 'o', feminine: true, needsDe: true },\n { singular: 'milion', plural: 'milioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'miliard', plural: 'miliarde', article: 'un', feminine: false, needsDe: true },\n { singular: 'trilion', plural: 'trilioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'cvadrilion', plural: 'cvadrilioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'cvintilion', plural: 'cvintilioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'sextilion', plural: 'sextilioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'septilion', plural: 'septilioane', article: 'un', feminine: false, needsDe: true },\n { singular: 'octilion', plural: 'octilioane', article: 'un', feminine: false, needsDe: true }\n]\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Spells number under 100.\n */\nfunction spellUnder100 (n, feminine = false, masculineTeens = false) {\n if (n === 0) return ''\n if (n < 10) {\n return feminine ? ONES_FEM[n] : ONES_MASC[n]\n }\n if (n < 20) {\n return masculineTeens ? TEENS_MASC[n - 10] : TEENS[n - 10]\n }\n const t = Math.floor(n / 10)\n const u = n % 10\n if (u === 0) {\n return TWENTIES[t]\n }\n const onesWord = feminine ? ONES_FEM[u] : ONES_MASC[u]\n return TWENTIES[t] + ' și ' + onesWord\n}\n\n/**\n * Spells number under 1000.\n */\nfunction spellUnder1000 (n, feminine = false, masculineTeens = false) {\n if (n === 0) return ''\n if (n < 100) return spellUnder100(n, feminine, masculineTeens)\n\n const h = Math.floor(n / 100)\n const r = n % 100\n const hundredWord = HUNDREDS[h]\n\n if (r === 0) return hundredWord\n return hundredWord + ' ' + spellUnder100(r, feminine, masculineTeens)\n}\n\n/**\n * Builds scale word with proper pluralization and \"de\" insertion.\n * Romanian always uses feminine forms (două, not doi) when counting scale words.\n */\nfunction buildScalePhrase (segment, scaleIndex) {\n const meta = SCALE_META[scaleIndex - 1]\n if (!meta) return spellUnder1000(segment, true)\n\n if (segment === 1) {\n return meta.article + ' ' + meta.singular\n }\n\n // Special case: 21 with scale words uses feminine \"una\"\n if (segment === 21 && meta.needsDe) {\n return 'douăzeci și una de ' + meta.plural\n }\n\n // Romanian always uses feminine when counting scale words (două milioane, not doi milioane)\n const words = spellUnder1000(segment, true)\n\n // \"de\" after >= 20\n const needsDe = meta.needsDe && segment >= 20\n const separator = needsDe ? ' de ' : ' '\n\n return words + separator + meta.plural\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Romanian words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Romanian words\n */\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000\n if (n < 1000n) {\n const feminine = options.gender === 'feminine'\n return spellUnder1000(Number(n), feminine)\n }\n\n return buildLargeNumberWords(n, options)\n}\n\n/**\n * Builds words for numbers >= 1000.\n * Uses BigInt division for faster segment extraction.\n *\n * @param {bigint} n - Number >= 1000\n * @param {Object} options - Conversion options\n * @returns {string} Romanian words\n */\nfunction buildLargeNumberWords (n, options) {\n // Extract segments using BigInt division (faster than string slicing)\n // Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)\n const segmentValues = []\n let temp = n\n while (temp > 0n) {\n segmentValues.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n\n // Build result string directly (avoid regex cleanup)\n let result = ''\n\n for (let i = segmentValues.length - 1; i >= 0; i--) {\n const segment = segmentValues[i]\n if (segment === 0) continue\n\n let segmentWords\n if (i === 0) {\n // Units segment - use gender from options\n const feminine = options.gender === 'feminine'\n segmentWords = spellUnder1000(segment, feminine)\n } else {\n // Scale segment\n segmentWords = buildScalePhrase(segment, i)\n }\n\n if (result && segmentWords) {\n result += ' ' + segmentWords\n } else if (segmentWords) {\n result = segmentWords\n }\n }\n\n return result\n}\n\n/**\n * Converts decimal digits to Romanian words.\n * Decimals always use masculine forms.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Romanian words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n // Handle leading zeros\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number (masculine, with masculine teens)\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n const n = BigInt(remainder)\n if (n < 1000n) {\n result += spellUnder1000(Number(n), false, true)\n } else {\n result += integerToWords(n, { gender: 'masculine' })\n }\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Romanian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Conversion options\n * @param {string} [options.gender='masculine'] - Gender for numbers\n * @returns {string} The number in Romanian words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'douăzeci și unu'\n * toWords(1, { gender: 'feminine' }) // 'una'\n * toWords(1000) // 'o mie'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Russian language converter - Functional Implementation\n *\n * Self-contained converter using shared Slavic utilities.\n *\n * Key features:\n * - Three-form pluralization (one/few/many)\n * - Gender: thousands are feminine, millions+ are masculine\n * - Irregular hundreds (двести, триста, etc.)\n * - Long scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Slavic Utilities (inlined for performance)\n// ============================================================================\n\nfunction pluralize (n, forms) {\n const num = typeof n === 'bigint' ? Number(n) : n\n const lastDigit = num % 10\n const lastTwoDigits = num % 100\n\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n if (lastDigit === 1) return forms[0]\n if (lastDigit >= 2 && lastDigit <= 4) return forms[1]\n return forms[2]\n}\n\nfunction buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {\n const masc = new Array(1000)\n const fem = new Array(1000)\n\n for (let i = 0; i < 1000; i++) {\n masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)\n fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)\n }\n\n return { masc, fem }\n}\n\nfunction buildSegment (n, ones, teens, tens, hundreds) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n parts.push(hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1) {\n parts.push(tens[tensDigit])\n }\n\n if (tensDigit === 1) {\n parts.push(teens[onesDigit])\n } else if (onesDigit > 0) {\n parts.push(ones[onesDigit])\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES_MASC = ['', 'один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять']\nconst ONES_FEM = ['', 'одна', 'две', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять']\n\nconst TEENS = ['десять', 'одиннадцать', 'двенадцать', 'тринадцать', 'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать', 'восемнадцать', 'девятнадцать']\nconst TENS = ['', '', 'двадцать', 'тридцать', 'сорок', 'пятьдесят', 'шестьдесят', 'семьдесят', 'восемьдесят', 'девяносто']\n\n// Irregular hundreds\nconst HUNDREDS = ['', 'сто', 'двести', 'триста', 'четыреста', 'пятьсот', 'шестьсот', 'семьсот', 'восемьсот', 'девятьсот']\n\nconst ZERO = 'ноль'\nconst NEGATIVE = 'минус'\nconst DECIMAL_SEP = 'запятая'\n\n// Scale words: [singular, few, many]\n// Thousands (index 0) are feminine, rest are masculine\nconst SCALE_FORMS = [\n ['тысяча', 'тысячи', 'тысяч'],\n ['миллион', 'миллиона', 'миллионов'],\n ['миллиард', 'миллиарда', 'миллиардов'],\n ['триллион', 'триллиона', 'триллионов'],\n ['квадриллион', 'квадриллиона', 'квадриллионов'],\n ['квинтиллион', 'квинтиллиона', 'квинтиллионов'],\n ['секстиллион', 'секстиллиона', 'секстиллионов'],\n ['септиллион', 'септиллиона', 'септиллионов'],\n ['октиллион', 'октиллиона', 'октиллионов'],\n ['нониллион', 'нониллиона', 'нониллионов']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nconst { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n const feminine = options.gender === 'feminine'\n\n if (n < 1000n) {\n const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Thousands are always feminine in Russian\n const thousandsWord = SEGMENTS_FEM[thousands]\n const scaleWord = pluralize(thousands, SCALE_FORMS[0])\n\n let result = thousandsWord + ' ' + scaleWord\n\n if (remainder > 0) {\n const segments = feminine ? SEGMENTS_FEM : SEGMENTS_MASC\n result += ' ' + segments[remainder]\n }\n\n return result\n }\n\n return buildLargeNumberWords(n, options)\n}\n\nfunction buildLargeNumberWords (n, options) {\n const feminine = options.gender === 'feminine'\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n const segmentWords = feminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment])\n } else {\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n // Thousands (scaleIndex=1) are feminine, others masculine\n const isFeminine = scaleIndex === 1\n const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Russian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Russian words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Serbian Cyrillic language converter - Functional Implementation\n *\n * Self-contained converter using shared Slavic utilities.\n *\n * Key features:\n * - Three-form pluralization (one/few/many)\n * - Gender: thousands are feminine, millions+ are masculine\n * - Irregular hundreds\n * - Long scale naming with -ard forms\n * - Cyrillic script\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Slavic Utilities (inlined for performance)\n// ============================================================================\n\nfunction pluralize (n, forms) {\n const num = typeof n === 'bigint' ? Number(n) : n\n const lastDigit = num % 10\n const lastTwoDigits = num % 100\n\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n if (lastDigit === 1) return forms[0]\n if (lastDigit >= 2 && lastDigit <= 4) return forms[1]\n return forms[2]\n}\n\nfunction buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {\n const masc = new Array(1000)\n const fem = new Array(1000)\n\n for (let i = 0; i < 1000; i++) {\n masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)\n fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)\n }\n\n return { masc, fem }\n}\n\nfunction buildSegment (n, ones, teens, tens, hundreds) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n parts.push(hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1) {\n parts.push(tens[tensDigit])\n }\n\n if (tensDigit === 1) {\n parts.push(teens[onesDigit])\n } else if (onesDigit > 0) {\n parts.push(ones[onesDigit])\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES_MASC = ['', 'један', 'два', 'три', 'четири', 'пет', 'шест', 'седам', 'осам', 'девет']\nconst ONES_FEM = ['', 'једна', 'две', 'три', 'четири', 'пет', 'шест', 'седам', 'осам', 'девет']\nconst TEENS = ['десет', 'једанаест', 'дванаест', 'тринаест', 'четрнаест', 'петнаест', 'шеснаест', 'седамнаест', 'осамнаест', 'деветнаест']\nconst TENS = ['', '', 'двадесет', 'тридесет', 'четрдесет', 'педесет', 'шездесет', 'седамдесет', 'осамдесет', 'деведесет']\nconst HUNDREDS = ['', 'сто', 'двеста', 'триста', 'четиристо', 'петсто', 'шесто', 'седамсто', 'осамсто', 'девестo']\n\nconst ZERO = 'нула'\nconst NEGATIVE = 'минус'\nconst DECIMAL_SEP = 'запета'\n\n// Scale words: [singular, few, many]\nconst SCALE_FORMS = [\n ['хиљада', 'хиљаде', 'хиљада'],\n ['милион', 'милиона', 'милиона'],\n ['милијарда', 'милијарде', 'милијарда'],\n ['билион', 'билиона', 'билиона'],\n ['билијарда', 'билијарде', 'билијарда'],\n ['трилион', 'трилиона', 'трилиона'],\n ['трилијарда', 'трилијарде', 'трилијарда'],\n ['квадрилион', 'квадрилиона', 'квадрилиона'],\n ['квадрилијарда', 'квадрилијарде', 'квадрилијарда']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nconst { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n return buildLargeNumberWords(n, options)\n}\n\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment])\n } else {\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n // Thousands (scaleIndex=1) are feminine, others masculine\n const isFeminine = scaleIndex === 1\n const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Serbian (Cyrillic) words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Serbian Cyrillic words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Serbian Latin language converter - Functional Implementation\n *\n * Self-contained converter using shared Slavic utilities.\n *\n * Key features:\n * - Three-form pluralization (one/few/many)\n * - Gender: thousands are feminine, millions+ are masculine\n * - Irregular hundreds (dvesta, trista, etc.)\n * - Long scale naming with -ard forms\n * - Latin script\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Slavic Utilities (inlined for performance)\n// ============================================================================\n\nfunction pluralize (n, forms) {\n const num = typeof n === 'bigint' ? Number(n) : n\n const lastDigit = num % 10\n const lastTwoDigits = num % 100\n\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n if (lastDigit === 1) return forms[0]\n if (lastDigit >= 2 && lastDigit <= 4) return forms[1]\n return forms[2]\n}\n\nfunction buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {\n const masc = new Array(1000)\n const fem = new Array(1000)\n\n for (let i = 0; i < 1000; i++) {\n masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)\n fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)\n }\n\n return { masc, fem }\n}\n\nfunction buildSegment (n, ones, teens, tens, hundreds) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n parts.push(hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1) {\n parts.push(tens[tensDigit])\n }\n\n if (tensDigit === 1) {\n parts.push(teens[onesDigit])\n } else if (onesDigit > 0) {\n parts.push(ones[onesDigit])\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES_MASC = ['', 'jedan', 'dva', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']\nconst ONES_FEM = ['', 'jedna', 'dve', 'tri', 'četiri', 'pet', 'šest', 'sedam', 'osam', 'devet']\nconst TEENS = ['deset', 'jedanaest', 'dvanaest', 'trinaest', 'četrnaest', 'petnaest', 'šesnaest', 'sedamnaest', 'osamnaest', 'devetnaest']\nconst TENS = ['', '', 'dvadeset', 'trideset', 'četrdeset', 'pedeset', 'šezdeset', 'sedamdeset', 'osamdeset', 'devedeset']\nconst HUNDREDS = ['', 'sto', 'dvesta', 'trista', 'četiristo', 'petsto', 'šesto', 'sedamsto', 'osamsto', 'devetsto']\n\nconst ZERO = 'nula'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'zapeta'\n\n// Scale words: [singular, few, many]\nconst SCALE_FORMS = [\n ['hiljada', 'hiljade', 'hiljada'],\n ['milion', 'miliona', 'miliona'],\n ['milijarda', 'milijarde', 'milijarda'],\n ['bilion', 'biliona', 'biliona'],\n ['bilijarda', 'bilijarde', 'bilijarda'],\n ['trilion', 'triliona', 'triliona'],\n ['trilijarda', 'trilijarde', 'trilijarda'],\n ['kvadrilion', 'kvadriliona', 'kvadriliona'],\n ['kvadrilijarda', 'kvadrilijarde', 'kvadrilijarda']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nconst { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n return buildLargeNumberWords(n, options)\n}\n\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment])\n } else {\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n // Thousands (scaleIndex=1) are feminine, others masculine\n const isFeminine = scaleIndex === 1\n const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Serbian (Latin) words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Serbian Latin words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Swedish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Hyphenation for tens-ones (tjugo-ett)\n * - \"och\" after hundreds before small numbers\n * - Omit \"ett\" before hundra and tusen\n * - Use \"en\" (not \"ett\") before million+ scales\n * - Long scale naming with -ard forms\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'ett', 'två', 'tre', 'fyra', 'fem', 'sex', 'sju', 'åtta', 'nio']\n\nconst TEENS = ['tio', 'elva', 'tolv', 'tretton', 'fjorton', 'femton', 'sexton', 'sjutton', 'arton', 'nitton']\nconst TENS = ['', '', 'tjugo', 'trettio', 'fyrtio', 'femtio', 'sextio', 'sjuttio', 'åttio', 'nittio']\n\nconst HUNDRED = 'hundra'\n\nconst ZERO = 'noll'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'komma'\n\n// Scale words (long scale with -ard forms)\nconst SCALES = ['tusen', 'miljon', 'miljard', 'biljon', 'biljard', 'triljon', 'triljard', 'kvadriljon']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Returns object with word and metadata for \"och\" logic.\n */\nfunction buildSegment (n) {\n if (n === 0) return { word: '', hasHundred: false, lessThan100: false }\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n let hasHundred = false\n\n // Hundreds - omit \"ett\" before hundra\n if (hundreds > 0) {\n hasHundred = true\n if (hundreds === 1) {\n parts.push(HUNDRED)\n } else {\n parts.push(ONES[hundreds] + ' ' + HUNDRED)\n }\n }\n\n // Tens and ones with hyphenation\n let tensOnesWord = ''\n if (tens === 1) {\n tensOnesWord = TEENS[ones]\n } else if (tens >= 2) {\n if (ones > 0) {\n tensOnesWord = TENS[tens] + '-' + ONES[ones]\n } else {\n tensOnesWord = TENS[tens]\n }\n } else if (ones > 0) {\n tensOnesWord = ONES[ones]\n }\n\n // Combine with \"och\" after hundreds if there's a remainder\n if (hasHundred && tensOnesWord) {\n return { word: parts[0] + ' och ' + tensOnesWord, hasHundred: true, lessThan100: false }\n } else if (hasHundred) {\n return { word: parts[0], hasHundred: true, lessThan100: false }\n } else {\n return { word: tensOnesWord, hasHundred: false, lessThan100: true }\n }\n}\n\n// Precompute all 1000 segment words (0-999)\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_HAS_HUNDRED = new Array(1000)\nconst SEGMENTS_LESS_THAN_100 = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n const result = buildSegment(i)\n SEGMENTS[i] = result.word\n SEGMENTS_HAS_HUNDRED[i] = result.hasHundred\n SEGMENTS_LESS_THAN_100[i] = result.lessThan100\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Swedish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Swedish words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Omit \"ett\" before tusen\n let result = thousands === 1 ? SCALES[0] : SEGMENTS[thousands] + ' ' + SCALES[0]\n\n if (remainder > 0) {\n const remainderWord = SEGMENTS[remainder]\n // Insert \"och\" if remainder < 100 (doesn't have hundred)\n if (SEGMENTS_LESS_THAN_100[remainder]) {\n result += ' och ' + remainderWord\n } else {\n result += ' ' + remainderWord\n }\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Swedish words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n // Units segment\n parts.push({\n word: SEGMENTS[segment],\n hasHundred: SEGMENTS_HAS_HUNDRED[segment],\n isScale: false\n })\n } else {\n // Segment with scale word\n const scaleWord = SCALES[scaleIndex - 1]\n\n let segmentWord\n if (segment === 1) {\n // Omit \"ett\" before tusen, use \"en\" before million+\n if (scaleIndex === 1) {\n segmentWord = '' // Just \"tusen\"\n } else {\n segmentWord = 'en' // \"en miljon\"\n }\n } else {\n segmentWord = SEGMENTS[segment]\n }\n\n if (segmentWord) {\n parts.push({ word: segmentWord, hasHundred: false, isScale: false })\n }\n parts.push({ word: scaleWord, hasHundred: false, isScale: true })\n }\n }\n\n scaleIndex--\n }\n\n // Join with Swedish \"och\" rules\n return joinSwedishParts(parts)\n}\n\n/**\n * Joins parts with Swedish \"och\" rules.\n * Insert \"och\" before final segment if it follows a scale word and doesn't have \"hundra\".\n *\n * @param {Array} parts - Parts with metadata\n * @returns {string} Joined string\n */\nfunction joinSwedishParts (parts) {\n if (parts.length === 0) return ZERO\n if (parts.length === 1) return parts[0].word\n\n const result = []\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const isLast = i === parts.length - 1\n\n if (isLast && parts.length > 1) {\n const prevPart = parts[i - 1]\n // Insert \"och\" if previous was scale and this doesn't have hundred\n if (prevPart.isScale && !part.hasHundred) {\n result.push('och')\n }\n }\n\n result.push(part.word)\n }\n\n return result.join(' ')\n}\n\n/**\n * Converts decimal digits to Swedish words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Swedish words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Swedish words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Swedish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // 'fyrtio-två'\n * toWords(101) // 'hundra och ett'\n * toWords(1000000) // 'en miljon'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Swahili language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - \"na\" connector for compound numbers\n * - Reversed hundreds: \"mia moja\" (one hundred)\n * - Scale words: elfu, milioni, bilioni\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['sifuri', 'moja', 'mbili', 'tatu', 'nne', 'tano', 'sita', 'saba', 'nane', 'tisa']\nconst TENS = { 10: 'kumi', 20: 'ishirini', 30: 'thelathini', 40: 'arobaini', 50: 'hamsini', 60: 'sitini', 70: 'sabini', 80: 'themanini', 90: 'tisini' }\n\nconst SCALE_WORDS = ['', 'elfu', 'milioni', 'bilioni', 'trilioni', 'kwadrilioni', 'kwintilioni']\n\nconst ZERO = 'sifuri'\nconst NEGATIVE = 'minus'\nconst DECIMAL_SEP = 'nukta'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction wordsUnder100 (n) {\n if (n < 10) return ONES[n]\n if (n === 10) return TENS[10]\n if (n < 20) {\n // 11-19: 'kumi na <digit>'\n return TENS[10] + ' na ' + ONES[n - 10]\n }\n const tens = Math.trunc(n / 10) * 10\n const ones = n % 10\n if (ones === 0) return TENS[tens]\n return TENS[tens] + ' na ' + ONES[ones]\n}\n\nfunction wordsUnder1000 (n) {\n if (n < 100) return wordsUnder100(n)\n if (n === 100) return 'mia moja'\n const hundreds = Math.trunc(n / 100)\n const rest = n % 100\n const parts = []\n\n // Hundreds: 'mia <digit>'\n parts.push('mia ' + ONES[hundreds])\n if (rest > 0) {\n if (rest < 10) {\n parts.push('na ' + ONES[rest])\n } else {\n parts.push(wordsUnder100(rest))\n }\n }\n\n return parts.join(' ')\n}\n\nfunction extractSegments (n) {\n const segments = []\n let temp = n\n while (temp > 0n) {\n segments.push(Number(temp % 1000n))\n temp = temp / 1000n\n }\n return segments\n}\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // segments stored least-significant first: [ones, thousands, millions, ...]\n const segments = extractSegments(n)\n const parts = []\n\n // Iterate from highest scale to lowest\n for (let scaleIndex = segments.length - 1; scaleIndex >= 0; scaleIndex--) {\n const val = segments[scaleIndex]\n if (val === 0) continue\n\n if (scaleIndex === 0) {\n // Units segment\n if (val < 10 && parts.length > 0) {\n parts.push('na ' + ONES[val])\n } else if (val === 100 && parts.length > 0) {\n // In compound numbers (e.g., 1100 -> 'elfu moja mia'), use 'mia' not 'mia moja'\n parts.push('mia')\n } else {\n parts.push(wordsUnder1000(val))\n }\n } else {\n // Scale segments: 'elfu moja', 'milioni mbili'\n const unit = (val === 1) ? 'moja' : wordsUnder1000(val)\n parts.push(SCALE_WORDS[scaleIndex] + ' ' + unit)\n }\n }\n\n return parts.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Swahili words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Swahili words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Tamil language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (ஆயிரம், லட்சம், கோடி)\n * - Tamil script\n * - 3-2-2 grouping pattern\n * - Complete word forms for 0-99\n * - Special hundred word transformations\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'பூஜ்ஜியம்'\nconst NEGATIVE = 'மைனஸ்'\nconst DECIMAL_SEP = 'புள்ளி'\n\nconst BELOW_HUNDRED = [\n 'பூஜ்ஜியம்', 'ஒன்று', 'இரண்டு', 'மூன்று', 'நான்கு', 'ஐந்து', 'ஆறு', 'ஏழு', 'எட்டு', 'ஒன்பது',\n 'பத்து', 'பதினொன்று', 'பன்னிரண்டு', 'பதிமூன்று', 'பதினான்கு', 'பதினைந்து', 'பதினாறு', 'பதினேழு', 'பதினெட்டு', 'பத்தொன்பது',\n 'இருபது', 'இருபத்தொன்று', 'இருபத்திரண்டு', 'இருபத்திமூன்று', 'இருபத்திநான்கு', 'இருபத்தைந்து', 'இருபத்தாறு', 'இருபத்தேழு', 'இருபத்தெட்டு', 'இருபத்தொன்பது',\n 'முப்பது', 'முப்பத்தொன்று', 'முப்பத்திரண்டு', 'முப்பத்திமூன்று', 'முப்பத்திநான்கு', 'முப்பத்தைந்து', 'முப்பத்தாறு', 'முப்பத்தேழு', 'முப்பத்தெட்டு', 'முப்பத்தொன்பது',\n 'நாற்பது', 'நாற்பத்தொன்று', 'நாற்பத்திரண்டு', 'நாற்பத்திமூன்று', 'நாற்பத்திநான்கு', 'நாற்பத்தைந்து', 'நாற்பத்தாறு', 'நாற்பத்தேழு', 'நாற்பத்தெட்டு', 'நாற்பத்தொன்பது',\n 'ஐம்பது', 'ஐம்பத்தொன்று', 'ஐம்பத்திரண்டு', 'ஐம்பத்திமூன்று', 'ஐம்பத்திநான்கு', 'ஐம்பத்தைந்து', 'ஐம்பத்தாறு', 'ஐம்பத்தேழு', 'ஐம்பத்தெட்டு', 'ஐம்பத்தொன்பது',\n 'அறுபது', 'அறுபத்தொன்று', 'அறுபத்திரண்டு', 'அறுபத்திமூன்று', 'அறுபத்திநான்கு', 'அறுபத்தைந்து', 'அறுபத்தாறு', 'அறுபத்தேழு', 'அறுபத்தெட்டு', 'அறுபத்தொன்பது',\n 'எழுபது', 'எழுபத்தொன்று', 'எழுபத்திரண்டு', 'எழுபத்திமூன்று', 'எழுபத்திநான்கு', 'எழுபத்தைந்து', 'எழுபத்தாறு', 'எழுபத்தேழு', 'எழுபத்தெட்டு', 'எழுபத்தொன்பது',\n 'எண்பது', 'எண்பத்தொன்று', 'எண்பத்திரண்டு', 'எண்பத்திமூன்று', 'எண்பத்திநான்கு', 'எண்பத்தைந்து', 'எண்பத்தாறு', 'எண்பத்தேழு', 'எண்பத்தெட்டு', 'எண்பத்தொன்பது',\n 'தொண்ணூறு', 'தொண்ணூற்று ஒன்று', 'தொண்ணூற்று இரண்டு', 'தொண்ணூற்று மூன்று', 'தொண்ணூற்று நான்கு', 'தொண்ணூற்று ஐந்து', 'தொண்ணூற்று ஆறு', 'தொண்ணூற்று ஏழு', 'தொண்ணூற்று எட்டு', 'தொண்ணூற்று ஒன்பது'\n]\n\n// Standalone hundreds (when not followed by remainder)\nconst HUNDREDS = ['', 'நூறு', 'இருநூறு', 'முன்னூறு', 'நானூறு', 'ஐநூறு', 'அறுநூறு', 'எழுநூறு', 'எண்நூறு', 'தொள்ளாயிரம்']\n\n// Connected form of hundreds (when followed by remainder) - precomputed\nconst HUNDREDS_CONNECTED = ['', 'நூற்று', 'இருநூற்று', 'முன்னூற்று', 'நானூற்று', 'ஐநூற்று', 'அறுநூற்று', 'எழுநூற்று', 'எண்நூற்று', 'தொள்ளாயிரத்து']\n\n// Ones for decimal reading\nconst ONES = ['ஒன்று', 'இரண்டு', 'மூன்று', 'நான்கு', 'ஐந்து', 'ஆறு', 'ஏழு', 'எட்டு', 'ஒன்பது']\n\n// Scale words: index 0 = units, 1 = thousand, 2 = lakh, etc.\nconst SCALE_WORDS = ['', 'ஆயிரம்', 'லட்சம்', 'கோடி', 'அரபு', 'கராபு', 'நீல்', 'பத்ம', 'சங்கு']\n\n// ============================================================================\n// Segment Splitting (inlined for performance)\n// ============================================================================\n\nfunction groupByThreeThenTwos (n) {\n const numStr = n.toString()\n\n if (numStr.length <= 3) {\n return [Number(numStr)]\n }\n\n const segments = []\n const last3 = numStr.slice(-3)\n segments.unshift(Number(last3))\n\n let remaining = numStr.slice(0, -3)\n while (remaining.length > 0) {\n const segment = remaining.slice(-2)\n segments.unshift(Number(segment))\n remaining = remaining.slice(0, -2)\n }\n\n return segments\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction convertBelowThousand (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return HUNDREDS[hundreds]\n }\n\n // Use precomputed connected form\n return HUNDREDS_CONNECTED[hundreds] + ' ' + BELOW_HUNDRED[remainder]\n}\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const groups = groupByThreeThenTwos(n)\n const groupCount = groups.length\n const words = []\n\n for (let i = 0; i < groupCount; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n const scaleIndex = groupCount - i - 1\n const groupWords = (groupValue === 1 && scaleIndex > 0) ? 'ஒரு' : convertBelowThousand(groupValue)\n words.push(groupWords)\n if (scaleIndex > 0 && SCALE_WORDS[scaleIndex]) {\n words.push(SCALE_WORDS[scaleIndex])\n }\n }\n\n return words.join(' ').trim()\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d - 1])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Tamil words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Tamil words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Telugu language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (వెయ్యి, లక్ష, కోటి)\n * - Telugu script\n * - 3-2-2 grouping pattern\n * - Complete word forms for 0-99\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'సున్నా'\nconst NEGATIVE = 'మైనస్'\nconst DECIMAL_SEP = 'పాయింట్'\n\nconst BELOW_HUNDRED = [\n 'సున్నా', 'ఒకటి', 'రెండు', 'మూడు', 'నాలుగు', 'ఐదు', 'ఆరు', 'ఏడు', 'ఎనిమిది', 'తొమ్మిది',\n 'పది', 'పదకొండు', 'పన్నెండు', 'పదమూడు', 'పద్నాలుగు', 'పదిహేను', 'పదహారు', 'పదిహేడు', 'పద్దెనిమిది', 'పంతొమ్మిది',\n 'ఇరవై', 'ఇరవై ఒక్కటి', 'ఇరవై రెండు', 'ఇరవై మూడు', 'ఇరవై నాలుగు', 'ఇరవై ఐదు', 'ఇరవై ఆరు', 'ఇరవై ఏడు', 'ఇరవై ఎనిమిది', 'ఇరవై తొమ్మిది',\n 'ముప్పై', 'ముప్పై ఒకటి', 'ముప్పై రెండు', 'ముప్పై మూడు', 'ముప్పై నాలుగు', 'ముప్పై ఐదు', 'ముప్పై ఆరు', 'ముప్పై ఏడు', 'ముప్పై ఎనిమిది', 'ముప్పై తొమ్మిది',\n 'నలభై', 'నలభై ఒకటి', 'నలభై రెండు', 'నలభై మూడు', 'నలభై నాలుగు', 'నలభై ఐదు', 'నలభై ఆరు', 'నలభై ఏడు', 'నలభై ఎనిమిది', 'నలభై తొమ్మిది',\n 'యాభై', 'యాభై ఒకటి', 'యాభై రెండు', 'యాభై మూడు', 'యాభై నాలుగు', 'యాభై ఐదు', 'యాభై ఆరు', 'యాభై ఏడు', 'యాభై ఎనిమిది', 'యాభై తొమ్మిది',\n 'అరవై', 'అరవై ఒకటి', 'అరవై రెండు', 'అరవై మూడు', 'అరవై నాలుగు', 'అరవై ఐదు', 'అరవై ఆరు', 'అరవై ఏడు', 'అరవై ఎనిమిది', 'అరవై తొమ్మిది',\n 'డెబ్బై', 'డెబ్బై ఒకటి', 'డెబ్బై రెండు', 'డెబ్బై మూడు', 'డెబ్బై నాలుగు', 'డెబ్బై ఐదు', 'డెబ్బై ఆరు', 'డెబ్బై ఏడు', 'డెబ్బై ఎనిమిది', 'డెబ్బై తొమ్మిది',\n 'ఎనభై', 'ఎనభై ఒకటి', 'ఎనభై రెండు', 'ఎనభై మూడు', 'ఎనభై నాలుగు', 'ఎనభై ఐదు', 'ఎనభై ఆరు', 'ఎనభై ఏడు', 'ఎనభై ఎనిమిది', 'ఎనభై తొమ్మిది',\n 'తొంభై', 'తొంభై ఒకటి', 'తొంభై రెండు', 'తొంభై మూడు', 'తొంభై నాలుగు', 'తొంభై ఐదు', 'తొంభై ఆరు', 'తొంభై ఏడు', 'తొంభై ఎనిమిది', 'తొంభై తొమ్మిది'\n]\n\n// ============================================================================\n// Vocabulary (continued)\n// ============================================================================\n\nconst HUNDREDS = ['', 'వంద', 'రెండు వందలు', 'మూడు వందలు', 'నాలుగు వందలు', 'ఐదు వందలు', 'ఆరు వందలు', 'ఏడు వందలు', 'ఎనిమిది వందలు', 'తొమ్మిది వందలు']\n\n// Ones for decimal reading\nconst ONES = ['ఒకటి', 'రెండు', 'మూడు', 'నాలుగు', 'ఐదు', 'ఆరు', 'ఏడు', 'ఎనిమిది', 'తొమ్మిది']\n\n// Scale words: index 0 = units, 1 = thousand, 2 = lakh, etc.\nconst SCALE_WORDS = ['', 'వెయ్యి', 'లక్ష', 'కోటి', 'అరబ్', 'ఖరబ్', 'నిల్', 'పడ్మ', 'శంకు']\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts 0-999 to Telugu words.\n */\nfunction convertBelowThousand (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return HUNDREDS[hundreds]\n }\n return HUNDREDS[hundreds] + ' ' + BELOW_HUNDRED[remainder]\n}\n\n/**\n * Converts a non-negative integer to Telugu words.\n * Uses recursive approach for Indian 3-2-2 grouping pattern.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Telugu words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return convertBelowThousand(Number(n))\n }\n\n return buildLargeNumberWords(n, 0)\n}\n\n/**\n * Recursively builds words for numbers >= 1000.\n * Indian grouping: first 3 digits, then 2-digit groups.\n *\n * @param {bigint} n - Number to convert\n * @param {number} scale - Current scale index (0=units, 1=thousands, etc.)\n * @returns {string} Telugu words\n */\nfunction buildLargeNumberWords (n, scale) {\n if (n === 0n) return ''\n\n // Determine divisor: 1000 for first split, 100 for rest\n const divisor = scale === 0 ? 1000n : 100n\n const segment = Number(n % divisor)\n const rest = n / divisor\n\n // Build higher segments first (recursive)\n let result = ''\n if (rest > 0n) {\n result = buildLargeNumberWords(rest, scale + 1)\n }\n\n // Add current segment\n if (segment > 0) {\n if (result) result += ' '\n\n if (scale === 0) {\n // Units segment (0-999)\n result += convertBelowThousand(segment)\n } else {\n // Scale segments (0-99)\n const groupWords = (segment === 1) ? 'ఒక' : BELOW_HUNDRED[segment]\n result += groupWords + ' ' + SCALE_WORDS[scale]\n }\n }\n\n return result\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d - 1])\n }\n return digits.join(' ')\n}\n\n/**\n * Converts a numeric value to Telugu words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Telugu words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Thai language converter - Functional Implementation\n *\n * Self-contained converter with precomputed lookup tables.\n *\n * Key features:\n * - No word separators (continuous Thai script)\n * - Million-based grouping (ล้าน)\n * - Special handling for 1 as \"เอ็ด\" in compounds\n * - 20 is \"ยี่สิบ\" (not \"สองสิบ\")\n * - Per-digit decimal reading\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES = ['หนึ่ง', 'สอง', 'สาม', 'สี่', 'ห้า', 'หก', 'เจ็ด', 'แปด', 'เก้า']\n\nconst ZERO = 'ศูนย์'\nconst NEGATIVE = 'ลบ'\nconst DECIMAL_SEP = 'จุด'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction convertBelowMillion (n) {\n if (n === 0) return ''\n\n let value = n\n const parts = []\n\n const hundredThousands = Math.trunc(value / 100000)\n value %= 100000\n const tenThousands = Math.trunc(value / 10000)\n value %= 10000\n const thousands = Math.trunc(value / 1000)\n value %= 1000\n const hundreds = Math.trunc(value / 100)\n value %= 100\n const tens = Math.trunc(value / 10)\n const ones = value % 10\n\n if (hundredThousands > 0) {\n parts.push(ONES[hundredThousands - 1] + 'แสน')\n }\n\n if (tenThousands > 0) {\n if (tenThousands === 1) {\n parts.push('หนึ่งหมื่น')\n } else {\n parts.push(ONES[tenThousands - 1] + 'หมื่น')\n }\n }\n\n if (thousands > 0) {\n parts.push(ONES[thousands - 1] + 'พัน')\n }\n\n if (hundreds > 0) {\n parts.push(ONES[hundreds - 1] + 'ร้อย')\n }\n\n if (tens > 0) {\n if (tens === 1) {\n parts.push('สิบ')\n } else if (tens === 2) {\n parts.push('ยี่สิบ')\n } else {\n parts.push(ONES[tens - 1] + 'สิบ')\n }\n }\n\n if (ones > 0) {\n const hasHigher = hundredThousands > 0 || tenThousands > 0 || thousands > 0 || hundreds > 0 || tens > 0\n if (ones === 1 && (tens > 0 || hasHigher)) {\n parts.push('เอ็ด')\n } else {\n parts.push(ONES[ones - 1])\n }\n }\n\n return parts.join('')\n}\n\nfunction splitMillionGroups (n) {\n const groups = []\n let remaining = n\n\n const million = 1_000_000n\n while (remaining > 0n) {\n const chunk = Number(remaining % million)\n groups.unshift(chunk)\n remaining = remaining / million\n }\n\n return groups\n}\n\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n const groups = splitMillionGroups(n)\n const parts = []\n\n for (let i = 0; i < groups.length; i++) {\n const groupValue = groups[i]\n if (groupValue === 0) continue\n\n parts.push(convertBelowMillion(groupValue))\n const remaining = groups.length - i - 1\n if (remaining > 0) {\n parts.push('ล้าน'.repeat(remaining))\n }\n }\n\n return parts.join('')\n}\n\nfunction decimalPartToWords (decimalPart) {\n // Per-digit decimal reading\n const digits = []\n for (const char of decimalPart) {\n const d = parseInt(char, 10)\n digits.push(d === 0 ? ZERO : ONES[d - 1])\n }\n return digits.join('')\n}\n\n/**\n * Converts a numeric value to Thai words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Thai words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += DECIMAL_SEP + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Turkish language converter - Functional Implementation\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n *\n * Key features:\n * - Omits 'bir' (one) before hundreds and thousands\n * - Optional dropSpaces for compound form\n * - Short scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\nconst ONES = ['', 'bir', 'iki', 'üç', 'dört', 'beş', 'altı', 'yedi', 'sekiz', 'dokuz']\n\nconst TEENS = ['on', 'on bir', 'on iki', 'on üç', 'on dört', 'on beş', 'on altı', 'on yedi', 'on sekiz', 'on dokuz']\nconst TENS = ['', '', 'yirmi', 'otuz', 'kırk', 'elli', 'altmış', 'yetmiş', 'seksen', 'doksan']\n\nconst HUNDRED = 'yüz'\nconst THOUSAND = 'bin'\n\nconst ZERO = 'sıfır'\nconst NEGATIVE = 'eksi'\nconst DECIMAL_SEP = 'virgül'\n\n// Short scale\nconst SCALES = ['milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon']\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds segment word for 0-999.\n * Omits \"bir\" before \"yüz\" (hundred).\n */\nfunction buildSegment (n, separator = ' ') {\n if (n === 0) return ''\n\n const ones = n % 10\n const tens = Math.floor(n / 10) % 10\n const hundreds = Math.floor(n / 100)\n\n const parts = []\n\n // Hundreds - omit \"bir\" before yüz\n if (hundreds > 0) {\n if (hundreds === 1) {\n parts.push(HUNDRED)\n } else {\n parts.push(ONES[hundreds] + separator + HUNDRED)\n }\n }\n\n // Tens and ones\n const tensOnes = n % 100\n\n if (tensOnes === 0) {\n // Just hundreds\n } else if (tensOnes < 10) {\n parts.push(ONES[ones])\n } else if (tensOnes < 20) {\n parts.push(TEENS[ones].replace(' ', separator))\n } else if (ones === 0) {\n parts.push(TENS[tens])\n } else {\n parts.push(TENS[tens] + separator + ONES[ones])\n }\n\n return parts.join(separator)\n}\n\n// Precompute all 1000 segment words (0-999) with space separator\nconst SEGMENTS = new Array(1000)\nconst SEGMENTS_NO_SPACE = new Array(1000)\n\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i, ' ')\n SEGMENTS_NO_SPACE[i] = buildSegment(i, '')\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Turkish words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @param {Object} options - Conversion options\n * @returns {string} Turkish words\n */\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n const sep = options.dropSpaces ? '' : ' '\n const segments = options.dropSpaces ? SEGMENTS_NO_SPACE : SEGMENTS\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return segments[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n // Omit \"bir\" before bin (thousand)\n let result\n if (thousands === 1) {\n result = THOUSAND\n } else {\n result = segments[thousands] + sep + THOUSAND\n }\n\n if (remainder > 0) {\n result += sep + segments[remainder]\n }\n\n return result\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n, options)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @param {Object} options - Conversion options\n * @returns {string} Turkish words\n */\nfunction buildLargeNumberWords (n, options) {\n const sep = options.dropSpaces ? '' : ' '\n const segmentsArr = options.dropSpaces ? SEGMENTS_NO_SPACE : SEGMENTS\n\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n const segmentWord = segmentsArr[segment]\n\n if (scaleIndex === 0) {\n // Units segment\n parts.push(segmentWord)\n } else if (scaleIndex === 1) {\n // Thousands - omit \"bir\" before bin\n if (segment === 1) {\n parts.push(THOUSAND)\n } else {\n parts.push(segmentWord + sep + THOUSAND)\n }\n } else {\n // Millions+ - \"bir\" is kept before scale words\n const scaleWord = SCALES[scaleIndex - 2]\n parts.push(segmentWord + sep + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(sep)\n}\n\n/**\n * Converts decimal digits to Turkish words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @param {Object} options - Conversion options\n * @returns {string} Turkish words for decimal part\n */\nfunction decimalPartToWords (decimalPart, options) {\n const sep = options.dropSpaces ? '' : ' '\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += sep\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += sep\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Turkish words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Conversion options\n * @param {boolean} [options.dropSpaces=false] - Remove spaces for compound form\n * @returns {string} The number in Turkish words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(21) // 'yirmi bir'\n * toWords(21, { dropSpaces: true }) // 'yirmibir'\n * toWords(1000) // 'bin'\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n const sep = options.dropSpaces ? '' : ' '\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + sep\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Ukrainian language converter - Functional Implementation\n *\n * Self-contained converter using shared Slavic utilities.\n *\n * Key features:\n * - Three-form pluralization (one/few/many)\n * - Gender: thousands are feminine, millions+ are masculine\n * - Irregular hundreds\n * - Long scale naming\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Slavic Utilities (inlined for performance)\n// ============================================================================\n\nfunction pluralize (n, forms) {\n const num = typeof n === 'bigint' ? Number(n) : n\n const lastDigit = num % 10\n const lastTwoDigits = num % 100\n\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return forms[2]\n }\n\n if (lastDigit === 1) return forms[0]\n if (lastDigit >= 2 && lastDigit <= 4) return forms[1]\n return forms[2]\n}\n\nfunction buildAllSegments (onesMasc, onesFem, teens, tens, hundreds) {\n const masc = new Array(1000)\n const fem = new Array(1000)\n\n for (let i = 0; i < 1000; i++) {\n masc[i] = buildSegment(i, onesMasc, teens, tens, hundreds)\n fem[i] = buildSegment(i, onesFem, teens, tens, hundreds)\n }\n\n return { masc, fem }\n}\n\nfunction buildSegment (n, ones, teens, tens, hundreds) {\n if (n === 0) return ''\n\n const onesDigit = n % 10\n const tensDigit = Math.floor(n / 10) % 10\n const hundredsDigit = Math.floor(n / 100)\n\n const parts = []\n\n if (hundredsDigit > 0) {\n parts.push(hundreds[hundredsDigit])\n }\n\n if (tensDigit > 1) {\n parts.push(tens[tensDigit])\n }\n\n if (tensDigit === 1) {\n parts.push(teens[onesDigit])\n } else if (onesDigit > 0) {\n parts.push(ones[onesDigit])\n }\n\n return parts.join(' ')\n}\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ONES_MASC = ['', 'один', 'два', 'три', 'чотири', 'п\\'ять', 'шiсть', 'сiм', 'вiсiм', 'дев\\'ять']\nconst ONES_FEM = ['', 'одна', 'двi', 'три', 'чотири', 'п\\'ять', 'шiсть', 'сiм', 'вiсiм', 'дев\\'ять']\n\nconst TEENS = ['десять', 'одинадцять', 'дванадцять', 'тринадцять', 'чотирнадцять', 'п\\'ятнадцять', 'шiстнадцять', 'сiмнадцять', 'вiсiмнадцять', 'дев\\'ятнадцять']\nconst TENS = ['', '', 'двадцять', 'тридцять', 'сорок', 'п\\'ятдесят', 'шiстдесят', 'сiмдесят', 'вiсiмдесят', 'дев\\'яносто']\n\n// Irregular hundreds\nconst HUNDREDS = ['', 'сто', 'двiстi', 'триста', 'чотириста', 'п\\'ятсот', 'шiстсот', 'сiмсот', 'вiсiмсот', 'дев\\'ятсот']\n\nconst ZERO = 'нуль'\nconst NEGATIVE = 'мiнус'\nconst DECIMAL_SEP = 'кома'\n\n// Scale words: [singular, few, many]\n// Thousands (index 0) are feminine, rest are masculine\nconst SCALE_FORMS = [\n ['тисяча', 'тисячi', 'тисяч'],\n ['мiльйон', 'мiльйони', 'мiльйонiв'],\n ['мiльярд', 'мiльярди', 'мiльярдiв'],\n ['трильйон', 'трильйони', 'трильйонiв'],\n ['квадрильйон', 'квадрильйони', 'квадрильйонiв'],\n ['квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'],\n ['секстильйон', 'секстильйони', 'секстильйонiв'],\n ['септильйон', 'септильйони', 'септильйонiв'],\n ['октильйон', 'октильйони', 'октильйонiв']\n]\n\n// ============================================================================\n// Precomputed Lookup Tables\n// ============================================================================\n\nconst { masc: SEGMENTS_MASC, fem: SEGMENTS_FEM } = buildAllSegments(ONES_MASC, ONES_FEM, TEENS, TENS, HUNDREDS)\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, options = {}) {\n if (n === 0n) return ZERO\n\n if (n < 1000n) {\n const segments = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n return segments[Number(n)]\n }\n\n return buildLargeNumberWords(n, options)\n}\n\nfunction buildLargeNumberWords (n, options) {\n const numStr = n.toString()\n const len = numStr.length\n\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n\n if (segment !== 0) {\n if (scaleIndex === 0) {\n const segmentWords = options.gender === 'feminine' ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment])\n } else {\n const scaleForms = SCALE_FORMS[scaleIndex - 1]\n const scaleWord = pluralize(segment, scaleForms)\n // Thousands (scaleIndex=1) are feminine, others masculine\n const isFeminine = scaleIndex === 1\n const segmentWords = isFeminine ? SEGMENTS_FEM : SEGMENTS_MASC\n parts.push(segmentWords[segment] + ' ' + scaleWord)\n }\n }\n\n scaleIndex--\n }\n\n return parts.join(' ')\n}\n\nfunction decimalPartToWords (decimalPart, options) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder), options)\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Ukrainian words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender\n * @returns {string} The number in Ukrainian words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart, options)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, options)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Urdu language converter - Functional Implementation\n *\n * Self-contained converter for South Asian numbering.\n *\n * Key features:\n * - Indian numbering system (ہزار, لاکھ, کروڑ)\n * - Urdu script (right-to-left)\n * - 3-2-2 grouping pattern (last 3 digits, then groups of 2)\n * - Complete word forms for 0-99\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\nconst ZERO = 'صفر'\nconst NEGATIVE = 'منفی'\nconst DECIMAL_SEP = 'اعشاریہ'\nconst HUNDRED = 'سو'\n\nconst BELOW_HUNDRED = [\n 'صفر', 'ایک', 'دو', 'تین', 'چار', 'پانچ', 'چھ', 'سات', 'آٹھ', 'نو',\n 'دس', 'گیارہ', 'بارہ', 'تیرہ', 'چودہ', 'پندرہ', 'سولہ', 'سترہ', 'اٹھارہ', 'انیس',\n 'بیس', 'اکیس', 'بائیس', 'تیئیس', 'چوبیس', 'پچیس', 'چھبیس', 'ستائیس', 'اٹھائیس', 'انتیس',\n 'تیس', 'اکتیس', 'بتیس', 'تینتیس', 'چونتیس', 'پینتیس', 'چھتیس', 'سینتیس', 'اڑتیس', 'انتالیس',\n 'چالیس', 'اکتالیس', 'بیالیس', 'تینتالیس', 'چوالیس', 'پینتالیس', 'چھالیس', 'سینتالیس', 'اڑتالیس', 'انچاس',\n 'پچاس', 'اکاون', 'باون', 'ترپن', 'چون', 'پچپن', 'چھپن', 'ستاون', 'اٹھاون', 'انسٹھ',\n 'ساٹھ', 'اکسٹھ', 'باسٹھ', 'ترسٹھ', 'چونسٹھ', 'پینسٹھ', 'چھیاسٹھ', 'سڑسٹھ', 'اڑسٹھ', 'انہتر',\n 'ستر', 'اکہتر', 'بہتر', 'تہتر', 'چوہتر', 'پچھتر', 'چھہتر', 'ستتر', 'اٹھہتر', 'اناسی',\n 'اسی', 'اکیاسی', 'بیاسی', 'تریاسی', 'چوراسی', 'پچاسی', 'چھیاسی', 'ستاسی', 'اٹھاسی', 'نواسی',\n 'نوے', 'اکانوے', 'بانوے', 'ترانوے', 'چورانوے', 'پچانوے', 'چھیانوے', 'ستانوے', 'اٹھانوے', 'ننانوے'\n]\n\n// Scale words: index 0 = units (empty), 1 = thousand, 2 = lakh, 3 = crore, etc.\nconst SCALE_WORDS = ['', 'ہزار', 'لاکھ', 'کروڑ', 'ارب', 'کھرب', 'نیل', 'پدم', 'شنکھ']\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts 0-999 to Urdu words.\n */\nfunction segmentToWords (n) {\n if (n === 0) return ''\n if (n < 100) return BELOW_HUNDRED[n]\n\n const hundreds = Math.trunc(n / 100)\n const remainder = n % 100\n\n if (remainder === 0) {\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED\n }\n return BELOW_HUNDRED[hundreds] + ' ' + HUNDRED + ' ' + BELOW_HUNDRED[remainder]\n}\n\n/**\n * Converts a non-negative integer to Urdu words.\n * Uses recursive approach for Indian 3-2-2 grouping pattern.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Urdu words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return segmentToWords(Number(n))\n }\n\n return buildLargeNumberWords(n, 0)\n}\n\n/**\n * Recursively builds words for numbers >= 1000.\n * Indian grouping: first 3 digits, then 2-digit groups.\n *\n * @param {bigint} n - Number to convert\n * @param {number} scale - Current scale index (0=units, 1=thousands, etc.)\n * @returns {string} Urdu words\n */\nfunction buildLargeNumberWords (n, scale) {\n if (n === 0n) return ''\n\n // Determine divisor: 1000 for first split, 100 for rest\n const divisor = scale === 0 ? 1000n : 100n\n const segment = Number(n % divisor)\n const rest = n / divisor\n\n // Build higher segments first (recursive)\n let result = ''\n if (rest > 0n) {\n result = buildLargeNumberWords(rest, scale + 1)\n }\n\n // Add current segment\n if (segment > 0) {\n if (result) result += ' '\n\n if (scale === 0) {\n // Units segment (0-999)\n result += segmentToWords(segment)\n } else {\n // Scale segments (0-99)\n result += BELOW_HUNDRED[segment] + ' ' + SCALE_WORDS[scale]\n }\n }\n\n return result\n}\n\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n let i = 0\n\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Urdu words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Urdu words\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Vietnamese language converter - Functional Implementation v2\n *\n * A performance-optimized number-to-words converter using precomputed lookup tables.\n * Self-contained module with its own input validation, ready for subpath exports.\n *\n * Key optimization: Precompute all segment values (0-999) at module load.\n * This eliminates all per-call string manipulation for segment conversion.\n *\n * Vietnamese-specific rules (handled in precomputation):\n * - Special pronunciation: \"lăm\" for 5 in tens position, \"mốt\" for final 1\n * - \"Lẻ\" (odd/extra) marker when tens place is zero after hundreds/scales\n * - Short scale system with Vietnamese words (nghìn, triệu, tỷ)\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\n\n// ============================================================================\n// Vocabulary (module-level constants)\n// ============================================================================\n\n// Base vocabulary for building lookup tables\nconst ONES = ['không', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín']\n\n// Scale words indexed by scale level (0 = units, 1 = thousands, etc.)\nconst SCALES = [\n '', 'nghìn', 'triệu', 'tỷ', 'nghìn tỷ', 'trăm nghìn tỷ',\n 'Quintillion', 'Sextillion', 'Septillion', 'Octillion',\n 'Nonillion', 'Decillion', 'Undecillion', 'Duodecillion',\n 'Tredecillion', 'Quattuordecillion', 'Sexdecillion',\n 'Septendecillion', 'Octodecillion', 'Novemdecillion', 'Vigintillion'\n]\n\nconst HUNDRED = 'trăm'\nconst ZERO = 'không'\nconst NEGATIVE = 'âm'\nconst DECIMAL_SEP = 'phẩy'\nconst LE = 'lẻ' // \"odd/extra\" marker for gaps\n\n// Special forms\nconst MOT_FINAL = 'mốt' // 1 in tens position (21, 31, etc.)\nconst LAM = 'lăm' // 5 in tens position (25, 35, etc.)\n\n// ============================================================================\n// Precomputed Lookup Tables (built once at module load)\n// ============================================================================\n\n/**\n * Builds word for 0-99 with special forms (mốt, lăm).\n * Only used during table construction.\n */\nfunction buildBelowHundred (n) {\n if (n === 0) return ONES[0]\n if (n < 10) return ONES[n]\n\n // Teens: 10-19\n if (n < 20) {\n const ones = n - 10\n if (ones === 0) return 'mười'\n if (ones === 5) return 'mười lăm'\n return 'mười ' + ONES[ones]\n }\n\n // 20-99\n const ones = n % 10\n const tens = Math.floor(n / 10)\n const tensWord = ONES[tens] + ' mươi'\n\n if (ones === 0) return tensWord\n if (ones === 1) return tensWord + ' ' + MOT_FINAL\n if (ones === 5) return tensWord + ' ' + LAM\n return tensWord + ' ' + ONES[ones]\n}\n\n/**\n * Builds segment word for 0-999.\n * Only used during table construction.\n */\nfunction buildSegment (n) {\n if (n === 0) return ''\n\n const hundreds = Math.floor(n / 100)\n const remainder = n % 100\n\n let result = ''\n\n if (hundreds > 0) {\n result = ONES[hundreds] + ' ' + HUNDRED\n }\n\n if (remainder > 0) {\n if (remainder < 10) {\n // Single digit after hundreds needs \"lẻ\"\n if (result) {\n result += ' ' + LE + ' '\n // Use \"năm\" not \"lăm\" after lẻ\n result += remainder === 5 ? 'năm' : ONES[remainder]\n } else {\n result = ONES[remainder]\n }\n } else {\n // 10-99 after hundreds\n if (result) result += ' '\n result += BELOW_100[remainder]\n }\n }\n\n return result\n}\n\n// Precompute all 100 below-hundred words (0-99)\n// BELOW_100[n] gives the Vietnamese word for n\nconst BELOW_100 = new Array(100)\nfor (let i = 0; i < 100; i++) {\n BELOW_100[i] = buildBelowHundred(i)\n}\n\n// Precompute all 1000 segment words (0-999)\n// SEGMENTS[n] gives the Vietnamese word for n within a segment\nconst SEGMENTS = new Array(1000)\nfor (let i = 0; i < 1000; i++) {\n SEGMENTS[i] = buildSegment(i)\n}\n\n// Precompute \"lẻ\" prefixed versions for small remainders after scale words\n// LE_SEGMENTS[n] gives \"lẻ X\" for n in range 1-99\nconst LE_SEGMENTS = new Array(100)\nLE_SEGMENTS[0] = ''\nfor (let i = 1; i < 10; i++) {\n // Use \"năm\" not \"lăm\" after lẻ\n LE_SEGMENTS[i] = LE + ' ' + (i === 5 ? 'năm' : ONES[i])\n}\nfor (let i = 10; i < 100; i++) {\n LE_SEGMENTS[i] = LE + ' ' + BELOW_100[i]\n}\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Converts a non-negative integer to Vietnamese words.\n *\n * @param {bigint} n - Non-negative integer to convert\n * @returns {string} Vietnamese words\n */\nfunction integerToWords (n) {\n if (n === 0n) return ZERO\n\n // Fast path: numbers < 100 (direct lookup)\n if (n < 100n) {\n return BELOW_100[Number(n)]\n }\n\n // Fast path: numbers < 1000 (direct lookup)\n if (n < 1000n) {\n return SEGMENTS[Number(n)]\n }\n\n // Fast path: numbers < 1,000,000 (thousands)\n if (n < 1_000_000n) {\n const thousands = Number(n / 1000n)\n const remainder = Number(n % 1000n)\n\n const thousandsWords = SEGMENTS[thousands] + ' ' + SCALES[1]\n\n if (remainder === 0) {\n return thousandsWords\n }\n\n // Check if remainder needs \"lẻ\" marker (< 100)\n if (remainder < 100) {\n return thousandsWords + ' ' + LE_SEGMENTS[remainder]\n }\n\n return thousandsWords + ' ' + SEGMENTS[remainder]\n }\n\n // For numbers >= 1,000,000, use scale decomposition\n return buildLargeNumberWords(n)\n}\n\n/**\n * Builds words for numbers >= 1,000,000.\n *\n * @param {bigint} n - Number >= 1,000,000\n * @returns {string} Vietnamese words\n */\nfunction buildLargeNumberWords (n) {\n const numStr = n.toString()\n const len = numStr.length\n\n // Build segments of 3 digits from right to left\n const segments = []\n const segmentSize = 3\n\n const remainderLen = len % segmentSize\n let pos = 0\n if (remainderLen > 0) {\n segments.push(Number(numStr.slice(0, remainderLen)))\n pos = remainderLen\n }\n while (pos < len) {\n segments.push(Number(numStr.slice(pos, pos + segmentSize)))\n pos += segmentSize\n }\n\n // Convert segments to words\n const parts = []\n let scaleIndex = segments.length - 1\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n if (segment !== 0) {\n const words = SEGMENTS[segment]\n if (words) {\n if (scaleIndex > 0) {\n parts.push(words + ' ' + SCALES[scaleIndex])\n } else {\n parts.push(words)\n }\n }\n }\n scaleIndex--\n }\n\n // Join with \"lẻ\" logic for small remainders\n const partsLen = parts.length\n if (partsLen === 0) return ZERO\n if (partsLen === 1) return parts[0]\n\n // Check if final segment needs \"lẻ\" marker (remainder <= 99 after scale word)\n const lastSegment = segments[segments.length - 1]\n if (lastSegment > 0 && lastSegment <= 99) {\n // Last segment is small (no hundreds), needs \"lẻ\" after scale word\n let result = parts[0]\n for (let i = 1; i < partsLen - 1; i++) {\n result += ' ' + parts[i]\n }\n return result + ' ' + LE_SEGMENTS[lastSegment]\n }\n\n // Join with spaces\n let result = parts[0]\n for (let i = 1; i < partsLen; i++) {\n result += ' ' + parts[i]\n }\n return result\n}\n\n/**\n * Converts decimal digits to Vietnamese words.\n *\n * @param {string} decimalPart - Decimal digits (without the point)\n * @returns {string} Vietnamese words for decimal part\n */\nfunction decimalPartToWords (decimalPart) {\n let result = ''\n\n // Handle leading zeros\n let i = 0\n while (i < decimalPart.length && decimalPart[i] === '0') {\n if (result) result += ' '\n result += ZERO\n i++\n }\n\n // Convert remainder as a single number\n const remainder = decimalPart.slice(i)\n if (remainder) {\n if (result) result += ' '\n result += integerToWords(BigInt(remainder))\n }\n\n return result\n}\n\n/**\n * Converts a numeric value to Vietnamese words.\n *\n * This is the main public API. It accepts any valid numeric input\n * (number, string, or bigint) and handles parsing internally.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @returns {string} The number in Vietnamese words\n * @throws {TypeError} If value is not a valid numeric type\n * @throws {Error} If value is not a valid number format\n *\n * @example\n * toWords(42) // 'bốn mươi hai'\n * toWords(101) // 'một trăm lẻ một'\n * toWords(1000000) // 'một triệu'\n */\nfunction toWords (value) {\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE + ' '\n }\n\n result += integerToWords(integerPart)\n\n if (decimalPart) {\n result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)\n }\n\n return result\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport { toWords }\n","/**\n * Simplified Chinese language converter - Functional Implementation\n *\n * Self-contained converter for Simplified Chinese.\n *\n * Key features:\n * - Myriad-based (万, 亿) grouping - 4 digits\n * - Formal (financial) vs common numerals\n * - Zero insertion for skipped positions\n * - No word separators (concatenated format)\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\n// Common (everyday) numerals\nconst ONES_COMMON = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\nconst TEN_COMMON = '十'\nconst HUNDRED_COMMON = '百'\nconst THOUSAND_COMMON = '千'\n\n// Formal (financial) numerals - harder to alter/forge\nconst ONES_FORMAL = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']\nconst TEN_FORMAL = '拾'\nconst HUNDRED_FORMAL = '佰'\nconst THOUSAND_FORMAL = '仟'\n\n// Scale words\nconst WAN_WORD = '万' // 10,000\nconst YI_WORD = '亿' // 100,000,000\n\nconst ZERO = '零'\nconst NEGATIVE = '负'\nconst DECIMAL_SEP = '点'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\n/**\n * Convert number below 万 (10,000) to words using direct string concatenation.\n */\nfunction convertBelowWan (value, ones, ten, hundred, thousand) {\n if (value === 0n) return ''\n\n let result = ''\n let needsZero = false\n\n // Thousands (千)\n const thousandsVal = value / 1000n\n const thousandsRemainder = value % 1000n\n if (thousandsVal > 0n) {\n result = ones[Number(thousandsVal)] + thousand\n needsZero = thousandsRemainder > 0n && thousandsRemainder < 100n\n }\n\n // Hundreds (百)\n const hundredsVal = thousandsRemainder / 100n\n const hundredsRemainder = thousandsRemainder % 100n\n if (hundredsVal > 0n) {\n if (needsZero) result += ZERO\n result += ones[Number(hundredsVal)] + hundred\n needsZero = hundredsRemainder > 0n && hundredsRemainder < 10n\n } else if (thousandsVal > 0n && hundredsRemainder > 0n) {\n needsZero = true\n }\n\n // Tens (十)\n const tensVal = hundredsRemainder / 10n\n const onesVal = hundredsRemainder % 10n\n if (tensVal > 0n) {\n if (needsZero) result += ZERO\n result += ones[Number(tensVal)] + ten\n needsZero = false\n } else if ((hundredsVal > 0n || thousandsVal > 0n) && onesVal > 0n) {\n needsZero = true\n }\n\n // Ones\n if (onesVal > 0n) {\n if (needsZero) result += ZERO\n result += ones[Number(onesVal)]\n }\n\n return result\n}\n\n/**\n * Convert number below 亿 (100 million) to words.\n */\nfunction convertBelowYi (value, ones, ten, hundred, thousand) {\n if (value === 0n) return ''\n\n if (value >= 10_000n) {\n const wanValue = value / 10_000n\n const wanRemainder = value % 10_000n\n\n let result = convertBelowWan(wanValue, ones, ten, hundred, thousand) + WAN_WORD\n\n if (wanRemainder > 0n) {\n const needsZero = (wanValue % 10n === 0n) || (wanRemainder < 1000n)\n if (needsZero) result += ZERO\n result += convertBelowWan(wanRemainder, ones, ten, hundred, thousand)\n }\n\n return result\n }\n\n return convertBelowWan(value, ones, ten, hundred, thousand)\n}\n\nfunction integerToWords (n, formal = true) {\n if (n === 0n) return ZERO\n\n const ones = formal ? ONES_FORMAL : ONES_COMMON\n const ten = formal ? TEN_FORMAL : TEN_COMMON\n const hundred = formal ? HUNDRED_FORMAL : HUNDRED_COMMON\n const thousand = formal ? THOUSAND_FORMAL : THOUSAND_COMMON\n\n // Handle numbers >= 亿 (100 million)\n if (n >= 100_000_000n) {\n const yiValue = n / 100_000_000n\n const yiRemainder = n % 100_000_000n\n\n let result = convertBelowYi(yiValue, ones, ten, hundred, thousand) + YI_WORD\n\n if (yiRemainder > 0n) {\n if (yiRemainder < 10_000_000n) result += ZERO\n result += convertBelowYi(yiRemainder, ones, ten, hundred, thousand)\n }\n\n return result\n }\n\n return convertBelowYi(n, ones, ten, hundred, thousand)\n}\n\n/**\n * Convert decimal digits to words using direct concatenation.\n */\nfunction decimalDigitsToWords (decimalString, ones) {\n let result = ''\n for (let i = 0; i < decimalString.length; i++) {\n result += ones[Number(decimalString[i])]\n }\n return result\n}\n\n/**\n * Converts a numeric value to Simplified Chinese words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.formal=true] - Use formal/financial numerals\n * @returns {string} The number in Simplified Chinese words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n const formal = options.formal !== false // Default to true\n\n let result = isNegative ? NEGATIVE : ''\n\n result += integerToWords(integerPart, formal)\n\n if (decimalPart) {\n const ones = formal ? ONES_FORMAL : ONES_COMMON\n result += DECIMAL_SEP + decimalDigitsToWords(decimalPart, ones)\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n","/**\n * Traditional Chinese language converter - Functional Implementation\n *\n * Self-contained converter for Traditional Chinese.\n *\n * Key features:\n * - Myriad-based (萬, 億) grouping - 4 digits\n * - Formal (financial) vs common numerals\n * - Zero insertion for skipped positions\n * - No word separators (concatenated format)\n *\n * Differences from Simplified:\n * - Different character forms (e.g., 負/负, 點/点, 億/亿, 萬/万)\n * - Some formal numerals differ (參/叁, 貳/贰, 陸/陆)\n */\n\nimport { parseNumericValue } from '../utils/parse-numeric.js'\nimport { validateOptions } from '../utils/validate-options.js'\n\n// ============================================================================\n// Vocabulary\n// ============================================================================\n\n// Common (everyday) numerals - Traditional forms\nconst ONES_COMMON = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\nconst TEN_COMMON = '十'\nconst HUNDRED_COMMON = '百'\nconst THOUSAND_COMMON = '千'\n\n// Formal (financial) numerals - Traditional forms\nconst ONES_FORMAL = ['零', '壹', '貳', '參', '肆', '伍', '陸', '柒', '捌', '玖']\nconst TEN_FORMAL = '拾'\nconst HUNDRED_FORMAL = '佰'\nconst THOUSAND_FORMAL = '仟'\n\n// Scale words - Traditional forms\nconst WAN_WORD = '萬' // 10,000\nconst YI_WORD = '億' // 100,000,000\n\nconst ZERO = '零'\nconst NEGATIVE = '負'\nconst DECIMAL_SEP = '點'\n\n// ============================================================================\n// Conversion Functions\n// ============================================================================\n\nfunction integerToWords (n, formal = true) {\n if (n === 0n) return ZERO\n\n const ones = formal ? ONES_FORMAL : ONES_COMMON\n const ten = formal ? TEN_FORMAL : TEN_COMMON\n const hundred = formal ? HUNDRED_FORMAL : HUNDRED_COMMON\n const thousand = formal ? THOUSAND_FORMAL : THOUSAND_COMMON\n\n // Convert number below 萬 (10,000)\n function convertBelowWan (value) {\n if (value === 0n) return ''\n\n const parts = []\n let needsZero = false\n\n // Thousands (千)\n const thousandsVal = value / 1000n\n const thousandsRemainder = value % 1000n\n if (thousandsVal > 0n) {\n parts.push(ones[Number(thousandsVal)] + thousand)\n needsZero = thousandsRemainder > 0n && thousandsRemainder < 100n\n }\n\n // Hundreds (百)\n const hundredsVal = thousandsRemainder / 100n\n const hundredsRemainder = thousandsRemainder % 100n\n if (hundredsVal > 0n) {\n if (needsZero) {\n parts.push(ZERO)\n needsZero = false\n }\n parts.push(ones[Number(hundredsVal)] + hundred)\n needsZero = hundredsRemainder > 0n && hundredsRemainder < 10n\n } else if (thousandsVal > 0n && hundredsRemainder > 0n) {\n needsZero = true\n }\n\n // Tens (十)\n const tensVal = hundredsRemainder / 10n\n const onesVal = hundredsRemainder % 10n\n if (tensVal > 0n) {\n if (needsZero) {\n parts.push(ZERO)\n needsZero = false\n }\n parts.push(ones[Number(tensVal)] + ten)\n } else if ((hundredsVal > 0n || thousandsVal > 0n) && onesVal > 0n) {\n needsZero = true\n }\n\n // Ones\n if (onesVal > 0n) {\n if (needsZero) {\n parts.push(ZERO)\n }\n parts.push(ones[Number(onesVal)])\n }\n\n return parts.join('')\n }\n\n // Convert number below 億 (100 million)\n function convertBelowYi (value) {\n if (value === 0n) return ''\n\n const parts = []\n\n if (value >= 10_000n) {\n const wanValue = value / 10_000n\n const wanRemainder = value % 10_000n\n\n parts.push(convertBelowWan(wanValue) + WAN_WORD)\n\n if (wanRemainder > 0n) {\n const wanEndsWithZero = wanValue % 10n === 0n\n const remainderMissesThousands = wanRemainder < 1000n\n const needsZero = wanEndsWithZero || remainderMissesThousands\n if (needsZero) {\n parts.push(ZERO)\n }\n parts.push(convertBelowWan(wanRemainder))\n }\n } else {\n parts.push(convertBelowWan(value))\n }\n\n return parts.join('')\n }\n\n // Main conversion\n const parts = []\n\n if (n >= 100_000_000n) {\n const yiValue = n / 100_000_000n\n const yiRemainder = n % 100_000_000n\n\n const yiWords = convertBelowYi(yiValue)\n parts.push(yiWords + YI_WORD)\n\n if (yiRemainder > 0n) {\n const needsZero = yiRemainder < 10_000_000n\n if (needsZero) {\n parts.push(ZERO)\n }\n parts.push(convertBelowYi(yiRemainder))\n }\n } else {\n parts.push(convertBelowYi(n))\n }\n\n return parts.join('')\n}\n\nfunction decimalDigitsToWords (decimalString, formal = true) {\n const ones = formal ? ONES_FORMAL : ONES_COMMON\n const words = []\n for (const char of decimalString) {\n words.push(ones[Number(char)])\n }\n return words\n}\n\n/**\n * Converts a numeric value to Traditional Chinese words.\n *\n * @param {number | string | bigint} value - The numeric value to convert\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.formal=true] - Use formal/financial numerals\n * @returns {string} The number in Traditional Chinese words\n */\nfunction toWords (value, options) {\n options = validateOptions(options)\n const { isNegative, integerPart, decimalPart } = parseNumericValue(value)\n const formal = options.formal !== false // Default to true\n\n let result = ''\n\n if (isNegative) {\n result = NEGATIVE\n }\n\n result += integerToWords(integerPart, formal)\n\n if (decimalPart) {\n result += DECIMAL_SEP + decimalDigitsToWords(decimalPart, formal).join('')\n }\n\n return result\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { toWords }\n"],"names":["parseNumericValue","value","type","isNegative","integerPart","Number","isFinite","Error","isSafeInteger","BigInt","parseNumericString","str","toString","includes","expandScientificNotation","numberToString","trimmed","trim","length","isNaN","normalizeString","TypeError","slice","dotIndex","indexOf","integerStr","decimalPart","mantissa","expStr","toLowerCase","split","exp","parseInt","digits","newDotPosition","repeat","ONES","TEENS","TENS","SCALE_WORDS","buildSegment","n","ones","tensDigit","Math","floor","hundredsDigit","parts","push","join","SEGMENTS","Array","i","ZERO","validateOptions","options","undefined","proto","Object","getPrototypeOf","prototype","isPlainObject","HUNDREDS","SCALE_APPENDED","SCALE_PLURAL","DUAL","DUAL_APPENDED","ONES_MASC","ONES_FEM","segmentToWords","groupNumber","groupLevel","fullNumber","tensValue","trunc","result","hundredsWord","numValue","pow","log10","onesDigit","tensIndex","integerToWords","gender","temp","group","groups","numberToProcess","groupDescription","groupText","unshift","numStr","len","segments","remainderLen","pos","scaleIndex","segment","scaleWord","buildLargeNumberWords","BELOW_HUNDRED","hundreds","remainder","remaining","groupByThreeThenTwos","segmentCount","words","segmentValue","PLURAL_FORMS","tens","buildSegmentWithHundreds","SEGMENTS_WITH_HUNDREDS","pluralize","forms","lastDigit","lastTwoDigits","thousands","segmentValues","ONES_VIGESIMAL","THOUSAND","SCALES","tensOnes","segmentWord","word","numWord","part","nextPart","endsWith","joinDanishParts","EIN","SCALES_PLURAL","HUNDRED","buildSegmentForThousand","SEGMENTS_THOUSAND","isScale","scaleLevel","segWords","prevPart","joinGermanParts","hasHundred","SEGMENTS_HAS_HUNDRED","remainderWord","firstNonZeroIdx","prevWasScale","TWENTIES_MASC","TWENTIES_FEM","HUNDREDS_MASC","HUNDREDS_FEM","feminine","SEGMENTS_MASC","SEGMENTS_FEM","getScaleWord","arrayIndex","baseWord","pluralWord","thousandsWord","thousandMultiplier","VOWELS","addLinker","hundredPrefix","buildSegmentWithLinker","lastSpaceIdx","lastIndexOf","prefix","lastWord","SEGMENTS_WITH_LINKER","SCALES_ARD","endsWithCents","endsWithVingts","t","o","SEGMENTS_ENDS_CENTS","SEGMENTS_ENDS_VINGTS","ardWord","withHyphen","replace","isSingleDigit","TEENS_MASC","THOUSANDS_MASC","TEENS_FEM","THOUSANDS_FEM","SCALE","buildScaleSegment","andWord","HUNDREDS_ARR","teenWord","buildUnitsSegment","SCALE_SEGMENTS_MASC","UNITS_SEGMENTS_MASC","SCALE_SEGMENTS_FEM","UNITS_SEGMENTS_FEM","THOUSANDS_SPECIAL","SCALE_SEGMENTS","UNITS_SEGMENTS","num","teens","SCALE_FORMS","masc","fem","onesMasc","onesFem","buildAllSegments","WORDS","Map","wordForScale","get","integerToWordsInner","zeroWord","has","units","tensToCardinal","hundredsToCardinal","postfix","thousandsToCardinal","scale","rest","bigNumberToCardinal","HUNDRED_WORD","THOUSAND_WORD","SCALE_PREFIXES","applyPhoneticRules","accentuateTre","buildSegmentWord","buildSegmentWordForScale","SEGMENTS_SCALE","THOUSANDS","getScaleWordSingular","prefixIndex","getScaleWordPlural","maxScale","testValue","divisor","segNum","segmentWords","lastPart","joinPartsWithConnector","joinKoreanParts","HUNDRED_SINGULAR","HUNDRED_PLURAL","buildSegmentFeminine","HUNDRED_GENITIVE","joinNorwegianParts","withAnd","onesWord","connector","SEGMENTS_WITH_AND","accentOne","includeOptionalAnd","noHundredPairing","applyAccent","high","low","lowWord","segmentLookup","isExactHundred","SEGMENTS_STARTS_WITH_HUNDREDS","SCALE_WORDS_SINGULAR","SCALE_WORDS_PLURAL","TWENTIES","SCALE_META","singular","plural","article","needsDe","spellUnder100","masculineTeens","u","spellUnder1000","h","r","hundredWord","buildScalePhrase","meta","lessThan100","tensOnesWord","SEGMENTS_LESS_THAN_100","joinSwedishParts","wordsUnder100","wordsUnder1000","extractSegments","val","unit","HUNDREDS_CONNECTED","convertBelowThousand","convertBelowMillion","hundredThousands","tenThousands","separator","SEGMENTS_NO_SPACE","sep","dropSpaces","segmentsArr","buildBelowHundred","tensWord","BELOW_100","LE_SEGMENTS","LE","thousandsWords","partsLen","lastSegment","ONES_COMMON","ONES_FORMAL","convertBelowWan","ten","hundred","thousand","needsZero","thousandsVal","thousandsRemainder","hundredsVal","hundredsRemainder","tensVal","onesVal","convertBelowYi","wanValue","wanRemainder","NEGATIVE","char","d","decimalPartToWords","negativeWord","getDecimalSeparator","digit","withHyphenSeparator","rawParts","filtered","isFeminine","usePrecomputed","SCALE_SEGS","UNITS_SEGS","man","opts","last3","groupCount","groupValue","groupWords","million","chunk","splitMillionGroups","formal","yiRemainder","decimalString","decimalDigitsToWords","yiWords"],"mappings":"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"}