n2words 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/LICENSE +1 -1
- package/README.md +64 -184
- package/dist/am-ET.js +2 -0
- package/dist/am-ET.umd.js +2 -0
- package/dist/am-Latn-ET.js +2 -0
- package/dist/am-Latn-ET.umd.js +2 -0
- package/dist/ar-SA.js +2 -0
- package/dist/ar-SA.umd.js +2 -0
- package/dist/az-AZ.js +2 -0
- package/dist/az-AZ.umd.js +2 -0
- package/dist/bn-BD.js +2 -0
- package/dist/bn-BD.umd.js +2 -0
- package/dist/cs-CZ.js +2 -0
- package/dist/cs-CZ.umd.js +2 -0
- package/dist/da-DK.js +2 -0
- package/dist/da-DK.umd.js +2 -0
- package/dist/de-DE.js +2 -0
- package/dist/de-DE.umd.js +2 -0
- package/dist/el-GR.js +2 -0
- package/dist/el-GR.umd.js +2 -0
- package/dist/en-AU.js +2 -0
- package/dist/en-AU.umd.js +2 -0
- package/dist/en-BD.js +2 -0
- package/dist/en-BD.umd.js +2 -0
- package/dist/en-CA.js +2 -0
- package/dist/en-CA.umd.js +2 -0
- package/dist/en-GB.js +2 -0
- package/dist/en-GB.umd.js +2 -0
- package/dist/en-GH.js +2 -0
- package/dist/en-GH.umd.js +2 -0
- package/dist/en-IE.js +2 -0
- package/dist/en-IE.umd.js +2 -0
- package/dist/en-IN.js +2 -0
- package/dist/en-IN.umd.js +2 -0
- package/dist/en-KE.js +2 -0
- package/dist/en-KE.umd.js +2 -0
- package/dist/en-MY.js +2 -0
- package/dist/en-MY.umd.js +2 -0
- package/dist/en-NG.js +2 -0
- package/dist/en-NG.umd.js +2 -0
- package/dist/en-NZ.js +2 -0
- package/dist/en-NZ.umd.js +2 -0
- package/dist/en-PH.js +2 -0
- package/dist/en-PH.umd.js +2 -0
- package/dist/en-PK.js +2 -0
- package/dist/en-PK.umd.js +2 -0
- package/dist/en-SG.js +2 -0
- package/dist/en-SG.umd.js +2 -0
- package/dist/en-US.js +2 -0
- package/dist/en-US.umd.js +2 -0
- package/dist/en-ZA.js +2 -0
- package/dist/en-ZA.umd.js +2 -0
- package/dist/es-ES.js +2 -0
- package/dist/es-ES.umd.js +2 -0
- package/dist/es-MX.js +2 -0
- package/dist/es-MX.umd.js +2 -0
- package/dist/es-US.js +2 -0
- package/dist/es-US.umd.js +2 -0
- package/dist/fa-IR.js +2 -0
- package/dist/fa-IR.umd.js +2 -0
- package/dist/fi-FI.js +2 -0
- package/dist/fi-FI.umd.js +2 -0
- package/dist/fil-PH.js +2 -0
- package/dist/fil-PH.umd.js +2 -0
- package/dist/fr-BE.js +2 -0
- package/dist/fr-BE.umd.js +2 -0
- package/dist/fr-FR.js +2 -0
- package/dist/fr-FR.umd.js +2 -0
- package/dist/gu-IN.js +2 -0
- package/dist/gu-IN.umd.js +2 -0
- package/dist/ha-NG.js +2 -0
- package/dist/ha-NG.umd.js +2 -0
- package/dist/hbo-IL.js +2 -0
- package/dist/hbo-IL.umd.js +2 -0
- package/dist/he-IL.js +2 -0
- package/dist/he-IL.umd.js +2 -0
- package/dist/hi-IN.js +2 -0
- package/dist/hi-IN.umd.js +2 -0
- package/dist/hr-HR.js +2 -0
- package/dist/hr-HR.umd.js +2 -0
- package/dist/hu-HU.js +2 -0
- package/dist/hu-HU.umd.js +2 -0
- package/dist/id-ID.js +2 -0
- package/dist/id-ID.umd.js +2 -0
- package/dist/it-IT.js +2 -0
- package/dist/it-IT.umd.js +2 -0
- package/dist/ja-JP.js +2 -0
- package/dist/ja-JP.umd.js +2 -0
- package/dist/ka-GE.js +2 -0
- package/dist/ka-GE.umd.js +2 -0
- package/dist/kn-IN.js +2 -0
- package/dist/kn-IN.umd.js +2 -0
- package/dist/ko-KR.js +2 -0
- package/dist/ko-KR.umd.js +2 -0
- package/dist/lt-LT.js +2 -0
- package/dist/lt-LT.umd.js +2 -0
- package/dist/lv-LV.js +2 -0
- package/dist/lv-LV.umd.js +2 -0
- package/dist/mr-IN.js +2 -0
- package/dist/mr-IN.umd.js +2 -0
- package/dist/ms-MY.js +2 -0
- package/dist/ms-MY.umd.js +2 -0
- package/dist/nb-NO.js +2 -0
- package/dist/nb-NO.umd.js +2 -0
- package/dist/nl-NL.js +2 -0
- package/dist/nl-NL.umd.js +2 -0
- package/dist/pa-IN.js +2 -0
- package/dist/pa-IN.umd.js +2 -0
- package/dist/pl-PL.js +2 -0
- package/dist/pl-PL.umd.js +2 -0
- package/dist/pt-PT.js +2 -0
- package/dist/pt-PT.umd.js +2 -0
- package/dist/ro-RO.js +2 -0
- package/dist/ro-RO.umd.js +2 -0
- package/dist/ru-RU.js +2 -0
- package/dist/ru-RU.umd.js +2 -0
- package/dist/sr-Cyrl-RS.js +2 -0
- package/dist/sr-Cyrl-RS.umd.js +2 -0
- package/dist/sr-Latn-RS.js +2 -0
- package/dist/sr-Latn-RS.umd.js +2 -0
- package/dist/sv-SE.js +2 -0
- package/dist/sv-SE.umd.js +2 -0
- package/dist/sw-KE.js +2 -0
- package/dist/sw-KE.umd.js +2 -0
- package/dist/ta-IN.js +2 -0
- package/dist/ta-IN.umd.js +2 -0
- package/dist/te-IN.js +2 -0
- package/dist/te-IN.umd.js +2 -0
- package/dist/th-TH.js +2 -0
- package/dist/th-TH.umd.js +2 -0
- package/dist/tr-TR.js +2 -0
- package/dist/tr-TR.umd.js +2 -0
- package/dist/uk-UA.js +2 -0
- package/dist/uk-UA.umd.js +2 -0
- package/dist/ur-PK.js +2 -0
- package/dist/ur-PK.umd.js +2 -0
- package/dist/vi-VN.js +2 -0
- package/dist/vi-VN.umd.js +2 -0
- package/dist/yo-NG.js +2 -0
- package/dist/yo-NG.umd.js +2 -0
- package/dist/zh-Hans-CN.js +2 -0
- package/dist/zh-Hans-CN.umd.js +2 -0
- package/dist/zh-Hant-TW.js +2 -0
- package/dist/zh-Hant-TW.umd.js +2 -0
- package/package.json +47 -82
- package/src/am-ET.d.ts +40 -0
- package/src/am-ET.js +269 -0
- package/src/am-Latn-ET.d.ts +35 -0
- package/src/am-Latn-ET.js +264 -0
- package/src/ar-SA.d.ts +49 -0
- package/{lib/languages/ar.js → src/ar-SA.js} +177 -15
- package/src/az-AZ.d.ts +37 -0
- package/src/az-AZ.js +312 -0
- package/src/bn-BD.d.ts +36 -0
- package/src/bn-BD.js +270 -0
- package/src/cs-CZ.d.ts +49 -0
- package/{lib/languages/cs.js → src/cs-CZ.js} +249 -40
- package/src/da-DK.d.ts +44 -0
- package/{lib/languages/da.js → src/da-DK.js} +136 -23
- package/src/de-DE.d.ts +57 -0
- package/src/de-DE.js +603 -0
- package/src/el-GR.d.ts +40 -0
- package/src/el-GR.js +418 -0
- package/src/en-AU.d.ts +47 -0
- package/src/en-AU.js +423 -0
- package/src/en-BD.d.ts +49 -0
- package/src/en-BD.js +415 -0
- package/src/en-CA.d.ts +63 -0
- package/src/en-CA.js +518 -0
- package/src/en-GB.d.ts +56 -0
- package/src/en-GB.js +469 -0
- package/src/en-GH.d.ts +11 -0
- package/src/en-GH.js +345 -0
- package/src/en-IE.d.ts +56 -0
- package/src/en-IE.js +479 -0
- package/src/en-IN.d.ts +49 -0
- package/src/en-IN.js +415 -0
- package/src/en-KE.d.ts +11 -0
- package/src/en-KE.js +345 -0
- package/src/en-MY.d.ts +11 -0
- package/src/en-MY.js +347 -0
- package/src/en-NG.d.ts +56 -0
- package/src/en-NG.js +479 -0
- package/src/en-NZ.d.ts +11 -0
- package/src/en-NZ.js +375 -0
- package/src/en-PH.d.ts +11 -0
- package/src/en-PH.js +345 -0
- package/src/en-PK.d.ts +49 -0
- package/src/en-PK.js +415 -0
- package/src/en-SG.d.ts +11 -0
- package/src/en-SG.js +345 -0
- package/src/en-US.d.ts +63 -0
- package/src/en-US.js +516 -0
- package/src/en-ZA.d.ts +56 -0
- package/src/en-ZA.js +478 -0
- package/src/es-ES.d.ts +65 -0
- package/src/es-ES.js +541 -0
- package/src/es-MX.d.ts +58 -0
- package/{lib/languages/es.js → src/es-MX.js} +237 -47
- package/src/es-US.d.ts +58 -0
- package/src/es-US.js +446 -0
- package/src/fa-IR.d.ts +38 -0
- package/src/fa-IR.js +246 -0
- package/src/fi-FI.d.ts +46 -0
- package/src/fi-FI.js +379 -0
- package/src/fil-PH.d.ts +37 -0
- package/{lib/languages/fil.js → src/fil-PH.js} +149 -24
- package/src/fr-BE.d.ts +49 -0
- package/src/fr-BE.js +453 -0
- package/src/fr-FR.d.ts +63 -0
- package/{lib/languages/fr.js → src/fr-FR.js} +200 -47
- package/src/gu-IN.d.ts +35 -0
- package/src/gu-IN.js +259 -0
- package/src/ha-NG.d.ts +37 -0
- package/{lib/languages/ha.js → src/ha-NG.js} +110 -16
- package/src/hbo-IL.d.ts +39 -0
- package/{lib/languages/hbo.js → src/hbo-IL.js} +217 -43
- package/src/he-IL.d.ts +37 -0
- package/src/he-IL.js +537 -0
- package/src/hi-IN.d.ts +36 -0
- package/src/hi-IN.js +280 -0
- package/src/hr-HR.d.ts +42 -0
- package/src/hr-HR.js +463 -0
- package/src/hu-HU.d.ts +38 -0
- package/{lib/languages/hu.js → src/hu-HU.js} +164 -6
- package/src/id-ID.d.ts +38 -0
- package/{lib/languages/id.js → src/id-ID.js} +106 -20
- package/src/it-IT.d.ts +59 -0
- package/src/it-IT.js +506 -0
- package/src/ja-JP.d.ts +49 -0
- package/{lib/languages/ja.js → src/ja-JP.js} +119 -32
- package/src/ka-GE.d.ts +44 -0
- package/src/ka-GE.js +393 -0
- package/src/kn-IN.d.ts +35 -0
- package/{lib/languages/kn.js → src/kn-IN.js} +156 -34
- package/src/ko-KR.d.ts +45 -0
- package/{lib/languages/ko.js → src/ko-KR.js} +99 -24
- package/src/lt-LT.d.ts +49 -0
- package/src/lt-LT.js +543 -0
- package/src/lv-LV.d.ts +49 -0
- package/src/lv-LV.js +595 -0
- package/src/mr-IN.d.ts +36 -0
- package/src/mr-IN.js +260 -0
- package/src/ms-MY.d.ts +37 -0
- package/{lib/languages/ms.js → src/ms-MY.js} +118 -20
- package/src/nb-NO.d.ts +44 -0
- package/{lib/languages/nb.js → src/nb-NO.js} +165 -33
- package/src/nl-NL.d.ts +54 -0
- package/{lib/languages/nl.js → src/nl-NL.js} +271 -47
- package/src/pa-IN.d.ts +36 -0
- package/src/pa-IN.js +268 -0
- package/src/pl-PL.d.ts +55 -0
- package/src/pl-PL.js +585 -0
- package/src/pt-PT.d.ts +45 -0
- package/src/pt-PT.js +514 -0
- package/src/ro-RO.d.ts +44 -0
- package/{lib/languages/ro.js → src/ro-RO.js} +212 -18
- package/src/ru-RU.d.ts +50 -0
- package/src/ru-RU.js +535 -0
- package/src/sr-Cyrl-RS.d.ts +49 -0
- package/src/sr-Cyrl-RS.js +503 -0
- package/src/sr-Latn-RS.d.ts +49 -0
- package/src/sr-Latn-RS.js +503 -0
- package/src/sv-SE.d.ts +44 -0
- package/{lib/languages/sv.js → src/sv-SE.js} +149 -34
- package/src/sw-KE.d.ts +37 -0
- package/{lib/languages/sw.js → src/sw-KE.js} +117 -6
- package/src/ta-IN.d.ts +35 -0
- package/{lib/languages/ta.js → src/ta-IN.js} +163 -47
- package/src/te-IN.d.ts +35 -0
- package/{lib/languages/te.js → src/te-IN.js} +147 -46
- package/src/th-TH.d.ts +38 -0
- package/{lib/languages/th.js → src/th-TH.js} +99 -6
- package/src/tr-TR.d.ts +48 -0
- package/src/tr-TR.js +397 -0
- package/src/uk-UA.d.ts +42 -0
- package/src/uk-UA.js +463 -0
- package/src/ur-PK.d.ts +36 -0
- package/src/ur-PK.js +268 -0
- package/src/utils/expand-scientific.d.ts +32 -0
- package/src/utils/expand-scientific.js +65 -0
- package/src/utils/parse-cardinal.d.ts +14 -0
- package/{lib/utils/parse-numeric.js → src/utils/parse-cardinal.js} +14 -44
- package/src/utils/parse-currency.d.ts +14 -0
- package/src/utils/parse-currency.js +91 -0
- package/src/utils/parse-ordinal.d.ts +10 -0
- package/src/utils/parse-ordinal.js +103 -0
- package/src/vi-VN.d.ts +48 -0
- package/{lib/languages/vi.js → src/vi-VN.js} +124 -53
- package/src/yo-NG.d.ts +37 -0
- package/src/yo-NG.js +403 -0
- package/src/zh-Hans-CN.d.ts +48 -0
- package/{lib/languages/zh-Hans.js → src/zh-Hans-CN.js} +140 -8
- package/src/zh-Hant-TW.d.ts +50 -0
- package/{lib/languages/zh-Hant.js → src/zh-Hant-TW.js} +139 -8
- package/dist/languages/am-Latn.js +0 -3
- package/dist/languages/am-Latn.js.map +0 -1
- package/dist/languages/am.js +0 -3
- package/dist/languages/am.js.map +0 -1
- package/dist/languages/ar.js +0 -3
- package/dist/languages/ar.js.map +0 -1
- package/dist/languages/az.js +0 -3
- package/dist/languages/az.js.map +0 -1
- package/dist/languages/bn.js +0 -3
- package/dist/languages/bn.js.map +0 -1
- package/dist/languages/cs.js +0 -3
- package/dist/languages/cs.js.map +0 -1
- package/dist/languages/da.js +0 -3
- package/dist/languages/da.js.map +0 -1
- package/dist/languages/de.js +0 -3
- package/dist/languages/de.js.map +0 -1
- package/dist/languages/el.js +0 -3
- package/dist/languages/el.js.map +0 -1
- package/dist/languages/en.js +0 -3
- package/dist/languages/en.js.map +0 -1
- package/dist/languages/es.js +0 -3
- package/dist/languages/es.js.map +0 -1
- package/dist/languages/fa.js +0 -3
- package/dist/languages/fa.js.map +0 -1
- package/dist/languages/fi.js +0 -3
- package/dist/languages/fi.js.map +0 -1
- package/dist/languages/fil.js +0 -3
- package/dist/languages/fil.js.map +0 -1
- package/dist/languages/fr-BE.js +0 -3
- package/dist/languages/fr-BE.js.map +0 -1
- package/dist/languages/fr.js +0 -3
- package/dist/languages/fr.js.map +0 -1
- package/dist/languages/gu.js +0 -3
- package/dist/languages/gu.js.map +0 -1
- package/dist/languages/ha.js +0 -3
- package/dist/languages/ha.js.map +0 -1
- package/dist/languages/hbo.js +0 -3
- package/dist/languages/hbo.js.map +0 -1
- package/dist/languages/he.js +0 -3
- package/dist/languages/he.js.map +0 -1
- package/dist/languages/hi.js +0 -3
- package/dist/languages/hi.js.map +0 -1
- package/dist/languages/hr.js +0 -3
- package/dist/languages/hr.js.map +0 -1
- package/dist/languages/hu.js +0 -3
- package/dist/languages/hu.js.map +0 -1
- package/dist/languages/id.js +0 -3
- package/dist/languages/id.js.map +0 -1
- package/dist/languages/it.js +0 -3
- package/dist/languages/it.js.map +0 -1
- package/dist/languages/ja.js +0 -3
- package/dist/languages/ja.js.map +0 -1
- package/dist/languages/kn.js +0 -3
- package/dist/languages/kn.js.map +0 -1
- package/dist/languages/ko.js +0 -3
- package/dist/languages/ko.js.map +0 -1
- package/dist/languages/lt.js +0 -3
- package/dist/languages/lt.js.map +0 -1
- package/dist/languages/lv.js +0 -3
- package/dist/languages/lv.js.map +0 -1
- package/dist/languages/mr.js +0 -3
- package/dist/languages/mr.js.map +0 -1
- package/dist/languages/ms.js +0 -3
- package/dist/languages/ms.js.map +0 -1
- package/dist/languages/nb.js +0 -3
- package/dist/languages/nb.js.map +0 -1
- package/dist/languages/nl.js +0 -3
- package/dist/languages/nl.js.map +0 -1
- package/dist/languages/pa.js +0 -3
- package/dist/languages/pa.js.map +0 -1
- package/dist/languages/pl.js +0 -3
- package/dist/languages/pl.js.map +0 -1
- package/dist/languages/pt.js +0 -3
- package/dist/languages/pt.js.map +0 -1
- package/dist/languages/ro.js +0 -3
- package/dist/languages/ro.js.map +0 -1
- package/dist/languages/ru.js +0 -3
- package/dist/languages/ru.js.map +0 -1
- package/dist/languages/sr-Cyrl.js +0 -3
- package/dist/languages/sr-Cyrl.js.map +0 -1
- package/dist/languages/sr-Latn.js +0 -3
- package/dist/languages/sr-Latn.js.map +0 -1
- package/dist/languages/sv.js +0 -3
- package/dist/languages/sv.js.map +0 -1
- package/dist/languages/sw.js +0 -3
- package/dist/languages/sw.js.map +0 -1
- package/dist/languages/ta.js +0 -3
- package/dist/languages/ta.js.map +0 -1
- package/dist/languages/te.js +0 -3
- package/dist/languages/te.js.map +0 -1
- package/dist/languages/th.js +0 -3
- package/dist/languages/th.js.map +0 -1
- package/dist/languages/tr.js +0 -3
- package/dist/languages/tr.js.map +0 -1
- package/dist/languages/uk.js +0 -3
- package/dist/languages/uk.js.map +0 -1
- package/dist/languages/ur.js +0 -3
- package/dist/languages/ur.js.map +0 -1
- package/dist/languages/vi.js +0 -3
- package/dist/languages/vi.js.map +0 -1
- package/dist/languages/zh-Hans.js +0 -3
- package/dist/languages/zh-Hans.js.map +0 -1
- package/dist/languages/zh-Hant.js +0 -3
- package/dist/languages/zh-Hant.js.map +0 -1
- package/dist/n2words.js +0 -3
- package/dist/n2words.js.map +0 -1
- package/lib/languages/am-Latn.d.ts +0 -7
- package/lib/languages/am-Latn.js +0 -164
- package/lib/languages/am.d.ts +0 -7
- package/lib/languages/am.js +0 -164
- package/lib/languages/ar.d.ts +0 -17
- package/lib/languages/az.d.ts +0 -7
- package/lib/languages/az.js +0 -176
- package/lib/languages/bn.d.ts +0 -7
- package/lib/languages/bn.js +0 -145
- package/lib/languages/cs.d.ts +0 -18
- package/lib/languages/da.d.ts +0 -14
- package/lib/languages/de.d.ts +0 -17
- package/lib/languages/de.js +0 -332
- package/lib/languages/el.d.ts +0 -14
- package/lib/languages/el.js +0 -243
- package/lib/languages/en.d.ts +0 -17
- package/lib/languages/en.js +0 -256
- package/lib/languages/es.d.ts +0 -21
- package/lib/languages/fa.d.ts +0 -7
- package/lib/languages/fa.js +0 -134
- package/lib/languages/fi.d.ts +0 -14
- package/lib/languages/fi.js +0 -245
- package/lib/languages/fil.d.ts +0 -7
- package/lib/languages/fr-BE.d.ts +0 -11
- package/lib/languages/fr-BE.js +0 -300
- package/lib/languages/fr.d.ts +0 -21
- package/lib/languages/gu.d.ts +0 -7
- package/lib/languages/gu.js +0 -137
- package/lib/languages/ha.d.ts +0 -7
- package/lib/languages/hbo.d.ts +0 -13
- package/lib/languages/he.d.ts +0 -13
- package/lib/languages/he.js +0 -276
- package/lib/languages/hi.d.ts +0 -7
- package/lib/languages/hi.js +0 -145
- package/lib/languages/hr.d.ts +0 -11
- package/lib/languages/hr.js +0 -218
- package/lib/languages/hu.d.ts +0 -7
- package/lib/languages/id.d.ts +0 -7
- package/lib/languages/it.d.ts +0 -19
- package/lib/languages/it.js +0 -377
- package/lib/languages/ja.d.ts +0 -17
- package/lib/languages/kn.d.ts +0 -7
- package/lib/languages/ko.d.ts +0 -14
- package/lib/languages/lt.d.ts +0 -18
- package/lib/languages/lt.js +0 -310
- package/lib/languages/lv.d.ts +0 -18
- package/lib/languages/lv.js +0 -321
- package/lib/languages/mr.d.ts +0 -7
- package/lib/languages/mr.js +0 -137
- package/lib/languages/ms.d.ts +0 -7
- package/lib/languages/nb.d.ts +0 -14
- package/lib/languages/nl.d.ts +0 -26
- package/lib/languages/pa.d.ts +0 -7
- package/lib/languages/pa.js +0 -163
- package/lib/languages/pl.d.ts +0 -22
- package/lib/languages/pl.js +0 -330
- package/lib/languages/pt.d.ts +0 -17
- package/lib/languages/pt.js +0 -306
- package/lib/languages/ro.d.ts +0 -18
- package/lib/languages/ru.d.ts +0 -11
- package/lib/languages/ru.js +0 -240
- package/lib/languages/sr-Cyrl.d.ts +0 -11
- package/lib/languages/sr-Cyrl.js +0 -215
- package/lib/languages/sr-Latn.d.ts +0 -11
- package/lib/languages/sr-Latn.js +0 -215
- package/lib/languages/sv.d.ts +0 -14
- package/lib/languages/sw.d.ts +0 -7
- package/lib/languages/ta.d.ts +0 -7
- package/lib/languages/te.d.ts +0 -7
- package/lib/languages/th.d.ts +0 -7
- package/lib/languages/tr.d.ts +0 -18
- package/lib/languages/tr.js +0 -263
- package/lib/languages/uk.d.ts +0 -11
- package/lib/languages/uk.js +0 -218
- package/lib/languages/ur.d.ts +0 -7
- package/lib/languages/ur.js +0 -163
- package/lib/languages/vi.d.ts +0 -17
- package/lib/languages/zh-Hans.d.ts +0 -11
- package/lib/languages/zh-Hant.d.ts +0 -11
- package/lib/n2words.d.ts +0 -53
- package/lib/n2words.js +0 -122
- package/lib/utils/parse-numeric.d.ts +0 -17
- /package/{lib → src}/utils/is-plain-object.d.ts +0 -0
- /package/{lib → src}/utils/is-plain-object.js +0 -0
- /package/{lib → src}/utils/validate-options.d.ts +0 -0
- /package/{lib → src}/utils/validate-options.js +0 -0
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Japanese language converter
|
|
2
|
+
* Japanese (Japan) language converter
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Self-contained module with its own input validation, ready for subpath exports.
|
|
4
|
+
* CLDR: ja-JP | Japanese as used in Japan
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
* This eliminates all per-call string manipulation for segment conversion.
|
|
9
|
-
*
|
|
10
|
-
* Japanese-specific rules (handled in precomputation):
|
|
6
|
+
* Japanese-specific rules:
|
|
11
7
|
* - Myriad (万-based) grouping: 4 digits per segment instead of 3
|
|
12
8
|
* - 一 omission: Omit "一" before 十, 百, 千 but NOT before 万 and higher scales
|
|
13
9
|
* - Kanji numerals: 零一二三四五六七八九
|
|
14
10
|
* - No spaces between characters
|
|
15
11
|
*/
|
|
16
12
|
|
|
17
|
-
import {
|
|
13
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
14
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
15
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
18
16
|
|
|
19
17
|
// ============================================================================
|
|
20
18
|
// Vocabulary (module-level constants)
|
|
@@ -49,27 +47,43 @@ const ZERO = '零'
|
|
|
49
47
|
const NEGATIVE = 'マイナス'
|
|
50
48
|
const DECIMAL_SEP = '点'
|
|
51
49
|
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Ordinal Vocabulary
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
// Ordinal prefix
|
|
55
|
+
const ORDINAL_PREFIX = '第'
|
|
56
|
+
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Currency Vocabulary (Japanese Yen)
|
|
59
|
+
// ============================================================================
|
|
60
|
+
|
|
61
|
+
// Yen (main unit)
|
|
62
|
+
const YEN = '円'
|
|
63
|
+
|
|
64
|
+
// Sen (1/100 yen) - historically used, now rare
|
|
65
|
+
const SEN = '銭'
|
|
66
|
+
|
|
52
67
|
// Internal scale words (within 4-digit segments)
|
|
53
68
|
const TEN = '十'
|
|
54
69
|
const HUNDRED = '百'
|
|
55
70
|
const THOUSAND = '千'
|
|
56
71
|
|
|
57
72
|
// ============================================================================
|
|
58
|
-
//
|
|
73
|
+
// Segment Building
|
|
59
74
|
// ============================================================================
|
|
60
75
|
|
|
61
76
|
/**
|
|
62
77
|
* Builds segment word for 0-9999 with 一 omission rules.
|
|
63
78
|
* - Omit 一 before 十, 百, 千
|
|
64
|
-
* Only used during table construction.
|
|
65
79
|
*/
|
|
66
80
|
function buildSegment (n) {
|
|
67
81
|
if (n === 0) return ''
|
|
68
82
|
|
|
69
83
|
const ones = n % 10
|
|
70
|
-
const tens = Math.
|
|
71
|
-
const hundreds = Math.
|
|
72
|
-
const thousands = Math.
|
|
84
|
+
const tens = Math.trunc(n / 10) % 10
|
|
85
|
+
const hundreds = Math.trunc(n / 100) % 10
|
|
86
|
+
const thousands = Math.trunc(n / 1000)
|
|
73
87
|
|
|
74
88
|
let result = ''
|
|
75
89
|
|
|
@@ -108,13 +122,6 @@ function buildSegment (n) {
|
|
|
108
122
|
return result
|
|
109
123
|
}
|
|
110
124
|
|
|
111
|
-
// Precompute all 10000 segment words (0-9999)
|
|
112
|
-
// SEGMENTS[n] gives the Japanese word for n within a segment
|
|
113
|
-
const SEGMENTS = new Array(10000)
|
|
114
|
-
for (let i = 0; i < 10000; i++) {
|
|
115
|
-
SEGMENTS[i] = buildSegment(i)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
125
|
// ============================================================================
|
|
119
126
|
// Conversion Functions
|
|
120
127
|
// ============================================================================
|
|
@@ -128,9 +135,9 @@ for (let i = 0; i < 10000; i++) {
|
|
|
128
135
|
function integerToWords (n) {
|
|
129
136
|
if (n === 0n) return ZERO
|
|
130
137
|
|
|
131
|
-
// Fast path: numbers < 10000
|
|
138
|
+
// Fast path: numbers < 10000
|
|
132
139
|
if (n < 10000n) {
|
|
133
|
-
return
|
|
140
|
+
return buildSegment(Number(n))
|
|
134
141
|
}
|
|
135
142
|
|
|
136
143
|
// Fast path: numbers < 100,000,000 (万 range)
|
|
@@ -143,11 +150,11 @@ function integerToWords (n) {
|
|
|
143
150
|
if (man === 1) {
|
|
144
151
|
result = '一' + SCALES[0] // 一万
|
|
145
152
|
} else {
|
|
146
|
-
result =
|
|
153
|
+
result = buildSegment(man) + SCALES[0]
|
|
147
154
|
}
|
|
148
155
|
|
|
149
156
|
if (remainder > 0) {
|
|
150
|
-
result +=
|
|
157
|
+
result += buildSegment(remainder)
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
return result
|
|
@@ -186,11 +193,11 @@ function buildLargeNumberWords (n) {
|
|
|
186
193
|
if (segment === 1) {
|
|
187
194
|
result += '一' + SCALES[i - 1]
|
|
188
195
|
} else {
|
|
189
|
-
result +=
|
|
196
|
+
result += buildSegment(segment) + SCALES[i - 1]
|
|
190
197
|
}
|
|
191
198
|
} else {
|
|
192
199
|
// Units segment (no scale word)
|
|
193
|
-
result +=
|
|
200
|
+
result += buildSegment(segment)
|
|
194
201
|
}
|
|
195
202
|
}
|
|
196
203
|
|
|
@@ -230,12 +237,12 @@ function decimalPartToWords (decimalPart) {
|
|
|
230
237
|
* @throws {Error} If value is not a valid number format
|
|
231
238
|
*
|
|
232
239
|
* @example
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
240
|
+
* toCardinal(42) // '四十二'
|
|
241
|
+
* toCardinal(10000) // '一万'
|
|
242
|
+
* toCardinal(100000000) // '一億'
|
|
236
243
|
*/
|
|
237
|
-
function
|
|
238
|
-
const { isNegative, integerPart, decimalPart } =
|
|
244
|
+
function toCardinal (value) {
|
|
245
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
239
246
|
|
|
240
247
|
let result = ''
|
|
241
248
|
|
|
@@ -252,8 +259,88 @@ function toWords (value) {
|
|
|
252
259
|
return result
|
|
253
260
|
}
|
|
254
261
|
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// ORDINAL: toOrdinal(value)
|
|
264
|
+
// ============================================================================
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Converts a positive integer to Japanese ordinal words.
|
|
268
|
+
*
|
|
269
|
+
* Japanese ordinals: 第 prefix + cardinal number.
|
|
270
|
+
*
|
|
271
|
+
* @param {bigint} n - Positive integer to convert
|
|
272
|
+
* @returns {string} Japanese ordinal words
|
|
273
|
+
*/
|
|
274
|
+
function integerToOrdinal (n) {
|
|
275
|
+
return ORDINAL_PREFIX + integerToWords(n)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Converts a numeric value to Japanese ordinal words.
|
|
280
|
+
*
|
|
281
|
+
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
282
|
+
* @returns {string} The number as ordinal words
|
|
283
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
284
|
+
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* toOrdinal(1) // '第一'
|
|
288
|
+
* toOrdinal(10) // '第十'
|
|
289
|
+
* toOrdinal(100) // '第百'
|
|
290
|
+
*/
|
|
291
|
+
function toOrdinal (value) {
|
|
292
|
+
const integerPart = parseOrdinalValue(value)
|
|
293
|
+
return integerToOrdinal(integerPart)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// CURRENCY: toCurrency(value, options?)
|
|
298
|
+
// ============================================================================
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Converts a numeric value to Japanese currency words (Yen).
|
|
302
|
+
*
|
|
303
|
+
* Note: Sen (銭, 1/100 yen) is included for completeness but is rarely used
|
|
304
|
+
* in modern Japan. Most transactions are in whole yen.
|
|
305
|
+
*
|
|
306
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
307
|
+
* @returns {string} The amount in Japanese currency words
|
|
308
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
309
|
+
* @throws {Error} If value is not a valid number format
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* toCurrency(42) // '四十二円'
|
|
313
|
+
* toCurrency(1) // '一円'
|
|
314
|
+
* toCurrency(0.50) // '五十銭'
|
|
315
|
+
* toCurrency(42.50) // '四十二円五十銭'
|
|
316
|
+
*/
|
|
317
|
+
function toCurrency (value) {
|
|
318
|
+
const { isNegative, dollars: yen, cents: sen } = parseCurrencyValue(value)
|
|
319
|
+
|
|
320
|
+
// Build result
|
|
321
|
+
let result = ''
|
|
322
|
+
if (isNegative) result = NEGATIVE
|
|
323
|
+
|
|
324
|
+
// Yen part
|
|
325
|
+
if (yen > 0n) {
|
|
326
|
+
result += integerToWords(yen) + YEN
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Sen part (1/100 yen)
|
|
330
|
+
if (sen > 0n) {
|
|
331
|
+
result += integerToWords(sen) + SEN
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Handle zero case
|
|
335
|
+
if (yen === 0n && sen === 0n) {
|
|
336
|
+
result += ZERO + YEN
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return result
|
|
340
|
+
}
|
|
341
|
+
|
|
255
342
|
// ============================================================================
|
|
256
343
|
// Public API
|
|
257
344
|
// ============================================================================
|
|
258
345
|
|
|
259
|
-
export {
|
|
346
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/ka-GE.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Georgian words.
|
|
3
|
+
*
|
|
4
|
+
* This is the main public API. It accepts any valid numeric input
|
|
5
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
6
|
+
*
|
|
7
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
8
|
+
* @returns {string} The number in Georgian words
|
|
9
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
10
|
+
* @throws {Error} If value is not a valid number format
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* toCardinal(21) // 'ოცდაერთი'
|
|
14
|
+
* toCardinal(100) // 'ასი'
|
|
15
|
+
* toCardinal(1000) // 'ათასი'
|
|
16
|
+
*/
|
|
17
|
+
export function toCardinal(value: number | string | bigint): string;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a numeric value to Georgian ordinal words.
|
|
20
|
+
*
|
|
21
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
22
|
+
* @returns {string} The ordinal in Georgian words
|
|
23
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
24
|
+
* @throws {Error} If value is not a positive integer
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* toOrdinal(1) // 'პირველი'
|
|
28
|
+
* toOrdinal(10) // 'მეათე'
|
|
29
|
+
* toOrdinal(21) // 'მეოცდაერთე'
|
|
30
|
+
*/
|
|
31
|
+
export function toOrdinal(value: number | string | bigint): string;
|
|
32
|
+
/**
|
|
33
|
+
* Converts a numeric value to Georgian Lari currency words.
|
|
34
|
+
*
|
|
35
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
36
|
+
* @returns {string} The currency in Georgian words
|
|
37
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
38
|
+
* @throws {Error} If value is not a valid number format
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* toCurrency(1) // 'ერთი ლარი'
|
|
42
|
+
* toCurrency(2.50) // 'ორი ლარი ორმოცდაათი თეთრი'
|
|
43
|
+
*/
|
|
44
|
+
export function toCurrency(value: number | string | bigint): string;
|
package/src/ka-GE.js
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Georgian (Georgia) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: ka-GE | Georgian as used in Georgia
|
|
5
|
+
*
|
|
6
|
+
* Georgian-specific rules:
|
|
7
|
+
* - Vigesimal (base-20) system for 20-99
|
|
8
|
+
* - 40 = ორმოცი (2×20), 60 = სამოცი (3×20), 80 = ოთხმოცი (4×20)
|
|
9
|
+
* - 30/50/70/90 use "და" + "ათი": ოცდაათი (20+10), ორმოცდაათი (40+10)
|
|
10
|
+
* - Compound numbers use "და" (da = "and") connector
|
|
11
|
+
* - Hundreds: unit prefix + ას (ორასი = 200)
|
|
12
|
+
* - Short scale for large numbers (მილიონი, მილიარდი, ტრილიონი)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
16
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
17
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
18
|
+
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Vocabulary (module-level constants)
|
|
21
|
+
// ============================================================================
|
|
22
|
+
|
|
23
|
+
// Numbers 0-9 (primitives)
|
|
24
|
+
const ONES = ['ნული', 'ერთი', 'ორი', 'სამი', 'ოთხი', 'ხუთი', 'ექვსი', 'შვიდი', 'რვა', 'ცხრა']
|
|
25
|
+
|
|
26
|
+
// Numbers 10-19
|
|
27
|
+
const TEENS = ['ათი', 'თერთმეტი', 'თორმეტი', 'ცამეტი', 'თოთხმეტი', 'თხუთმეტი', 'თექვსმეტი', 'ჩვიდმეტი', 'თვრამეტი', 'ცხრამეტი']
|
|
28
|
+
|
|
29
|
+
// Vigesimal bases: 20, 40, 60, 80 (with და connector forms)
|
|
30
|
+
const VIGESIMAL = ['', 'ოცი', 'ორმოცი', 'სამოცი', 'ოთხმოცი']
|
|
31
|
+
const VIGESIMAL_DA = ['', 'ოცდა', 'ორმოცდა', 'სამოცდა', 'ოთხმოცდა']
|
|
32
|
+
|
|
33
|
+
// Prefixes for hundreds (unit forms without final vowel)
|
|
34
|
+
const HUNDRED_PREFIXES = ['', '', 'ორ', 'სამ', 'ოთხ', 'ხუთ', 'ექვს', 'შვიდ', 'რვა', 'ცხრა']
|
|
35
|
+
|
|
36
|
+
const HUNDRED = 'ასი'
|
|
37
|
+
const HUNDRED_STEM = 'ას' // Without final vowel
|
|
38
|
+
const THOUSAND = 'ათასი'
|
|
39
|
+
const THOUSAND_STEM = 'ათას' // Without final vowel
|
|
40
|
+
|
|
41
|
+
// Scale words (short scale) - indexed by segment position
|
|
42
|
+
const SCALES = ['', '', 'მილიონი', 'მილიარდი', 'ტრილიონი', 'კვადრილიონი', 'კვინტილიონი', 'სექსტილიონი']
|
|
43
|
+
|
|
44
|
+
const ZERO = 'ნული'
|
|
45
|
+
const NEGATIVE = 'მინუს'
|
|
46
|
+
const DECIMAL_SEP = 'მთელი'
|
|
47
|
+
|
|
48
|
+
// Ordinal suffix (Georgian adds -ე to form ordinals)
|
|
49
|
+
const ORDINAL_SUFFIX = 'ე'
|
|
50
|
+
|
|
51
|
+
// Ordinal forms for 1-9 (these are special)
|
|
52
|
+
const ORDINAL_ONES = ['', 'პირველი', 'მეორე', 'მესამე', 'მეოთხე', 'მეხუთე', 'მეექვსე', 'მეშვიდე', 'მერვე', 'მეცხრე']
|
|
53
|
+
|
|
54
|
+
// Currency (Georgian Lari)
|
|
55
|
+
const LARI = 'ლარი'
|
|
56
|
+
const TETRI = 'თეთრი'
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Segment Building
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Builds segment word for 0-99 using vigesimal system.
|
|
64
|
+
* @param {number} n - Number 0-99
|
|
65
|
+
* @returns {string} Georgian word
|
|
66
|
+
*/
|
|
67
|
+
function buildTens (n) {
|
|
68
|
+
if (n < 10) return ONES[n]
|
|
69
|
+
if (n < 20) return TEENS[n - 10]
|
|
70
|
+
|
|
71
|
+
const vigesimalGroup = Math.trunc(n / 20)
|
|
72
|
+
const remainder = n % 20
|
|
73
|
+
|
|
74
|
+
if (remainder === 0) {
|
|
75
|
+
return VIGESIMAL[vigesimalGroup]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Use და connector: ოცდა + remainder
|
|
79
|
+
const base = VIGESIMAL_DA[vigesimalGroup]
|
|
80
|
+
if (remainder < 10) {
|
|
81
|
+
return base + ONES[remainder]
|
|
82
|
+
}
|
|
83
|
+
return base + TEENS[remainder - 10]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Builds segment word for 0-999.
|
|
88
|
+
* Returns object with full form and stem form (without final vowel).
|
|
89
|
+
* @param {number} n - Number 0-999
|
|
90
|
+
* @returns {{full: string, stem: string}} Georgian words
|
|
91
|
+
*/
|
|
92
|
+
function buildSegment (n) {
|
|
93
|
+
if (n === 0) return { full: '', stem: '' }
|
|
94
|
+
if (n < 100) {
|
|
95
|
+
const word = buildTens(n)
|
|
96
|
+
// Remove final vowel for stem
|
|
97
|
+
const lastChar = word.slice(-1)
|
|
98
|
+
const stem = (lastChar === 'ი' || lastChar === 'ა') ? word.slice(0, -1) : word
|
|
99
|
+
return { full: word, stem }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const hundreds = Math.trunc(n / 100)
|
|
103
|
+
const remainder = n % 100
|
|
104
|
+
|
|
105
|
+
// Build hundreds: ასი (100), ორასი (200), etc.
|
|
106
|
+
let hundredWord
|
|
107
|
+
if (hundreds === 1) {
|
|
108
|
+
hundredWord = remainder > 0 ? HUNDRED_STEM : HUNDRED
|
|
109
|
+
} else {
|
|
110
|
+
hundredWord = HUNDRED_PREFIXES[hundreds] + (remainder > 0 ? HUNDRED_STEM : HUNDRED)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (remainder > 0) {
|
|
114
|
+
const remainderWord = buildTens(remainder)
|
|
115
|
+
const full = hundredWord + ' ' + remainderWord
|
|
116
|
+
// Stem removes final vowel from remainder
|
|
117
|
+
const lastChar = remainderWord.slice(-1)
|
|
118
|
+
const remainderStem = (lastChar === 'ი' || lastChar === 'ა') ? remainderWord.slice(0, -1) : remainderWord
|
|
119
|
+
return { full, stem: hundredWord + ' ' + remainderStem }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Hundreds only - stem removes final ი
|
|
123
|
+
return { full: hundredWord, stem: hundredWord.slice(0, -1) }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// Conversion Functions
|
|
128
|
+
// ============================================================================
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Converts a non-negative integer to Georgian words.
|
|
132
|
+
*
|
|
133
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
134
|
+
* @returns {string} Georgian words
|
|
135
|
+
*/
|
|
136
|
+
function integerToWords (n) {
|
|
137
|
+
if (n === 0n) return ZERO
|
|
138
|
+
|
|
139
|
+
// Fast path: numbers < 1000
|
|
140
|
+
if (n < 1000n) {
|
|
141
|
+
const { full } = buildSegment(Number(n))
|
|
142
|
+
return full
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Fast path: numbers < 1,000,000 (thousands)
|
|
146
|
+
if (n < 1_000_000n) {
|
|
147
|
+
const thousands = Number(n / 1000n)
|
|
148
|
+
const remainder = Number(n % 1000n)
|
|
149
|
+
|
|
150
|
+
let result
|
|
151
|
+
if (thousands === 1) {
|
|
152
|
+
// "ათასი" not "ერთი ათასი"
|
|
153
|
+
result = remainder > 0 ? THOUSAND_STEM : THOUSAND
|
|
154
|
+
} else {
|
|
155
|
+
// Use stem form before ათასი
|
|
156
|
+
const { stem: thousandsPart } = buildSegment(thousands)
|
|
157
|
+
result = thousandsPart + ' ' + (remainder > 0 ? THOUSAND_STEM : THOUSAND)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (remainder > 0) {
|
|
161
|
+
const { full: remainderWord } = buildSegment(remainder)
|
|
162
|
+
result += ' ' + remainderWord
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return result
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
169
|
+
return buildLargeNumberWords(n)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Builds words for numbers >= 1,000,000.
|
|
174
|
+
*
|
|
175
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
176
|
+
* @returns {string} Georgian words
|
|
177
|
+
*/
|
|
178
|
+
function buildLargeNumberWords (n) {
|
|
179
|
+
const numStr = n.toString()
|
|
180
|
+
const len = numStr.length
|
|
181
|
+
|
|
182
|
+
// Build segments of 3 digits from left to right
|
|
183
|
+
const segments = []
|
|
184
|
+
const segmentSize = 3
|
|
185
|
+
|
|
186
|
+
const remainderLen = len % segmentSize
|
|
187
|
+
let pos = 0
|
|
188
|
+
if (remainderLen > 0) {
|
|
189
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
190
|
+
pos = remainderLen
|
|
191
|
+
}
|
|
192
|
+
while (pos < len) {
|
|
193
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
194
|
+
pos += segmentSize
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Convert segments to words
|
|
198
|
+
const parts = []
|
|
199
|
+
let scaleIndex = segments.length - 1
|
|
200
|
+
|
|
201
|
+
for (let i = 0; i < segments.length; i++) {
|
|
202
|
+
const segment = segments[i]
|
|
203
|
+
|
|
204
|
+
if (segment !== 0) {
|
|
205
|
+
if (scaleIndex === 0) {
|
|
206
|
+
// Units (no scale)
|
|
207
|
+
const { full } = buildSegment(segment)
|
|
208
|
+
parts.push(full)
|
|
209
|
+
} else if (scaleIndex === 1) {
|
|
210
|
+
// Thousands - check if there's a remainder
|
|
211
|
+
const hasRemainder = segments.slice(i + 1).some(s => s !== 0)
|
|
212
|
+
const thousandWord = hasRemainder ? THOUSAND_STEM : THOUSAND
|
|
213
|
+
|
|
214
|
+
if (segment === 1) {
|
|
215
|
+
parts.push(thousandWord)
|
|
216
|
+
} else {
|
|
217
|
+
const { stem } = buildSegment(segment)
|
|
218
|
+
parts.push(stem + ' ' + thousandWord)
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
// Million and above
|
|
222
|
+
const scaleWord = SCALES[scaleIndex] || SCALES[SCALES.length - 1]
|
|
223
|
+
if (segment === 1) {
|
|
224
|
+
parts.push('ერთი ' + scaleWord)
|
|
225
|
+
} else {
|
|
226
|
+
const { full } = buildSegment(segment)
|
|
227
|
+
parts.push(full + ' ' + scaleWord)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
scaleIndex--
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return parts.join(' ')
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Converts decimal digits to Georgian words.
|
|
240
|
+
*
|
|
241
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
242
|
+
* @returns {string} Georgian words for decimal part
|
|
243
|
+
*/
|
|
244
|
+
function decimalPartToWords (decimalPart) {
|
|
245
|
+
let result = ''
|
|
246
|
+
|
|
247
|
+
// Handle leading zeros
|
|
248
|
+
let i = 0
|
|
249
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
250
|
+
if (result) result += ' '
|
|
251
|
+
result += ZERO
|
|
252
|
+
i++
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Convert remainder as a single number
|
|
256
|
+
const remainder = decimalPart.slice(i)
|
|
257
|
+
if (remainder) {
|
|
258
|
+
if (result) result += ' '
|
|
259
|
+
result += integerToWords(BigInt(remainder))
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return result
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Converts a numeric value to Georgian words.
|
|
267
|
+
*
|
|
268
|
+
* This is the main public API. It accepts any valid numeric input
|
|
269
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
270
|
+
*
|
|
271
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
272
|
+
* @returns {string} The number in Georgian words
|
|
273
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
274
|
+
* @throws {Error} If value is not a valid number format
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* toCardinal(21) // 'ოცდაერთი'
|
|
278
|
+
* toCardinal(100) // 'ასი'
|
|
279
|
+
* toCardinal(1000) // 'ათასი'
|
|
280
|
+
*/
|
|
281
|
+
function toCardinal (value) {
|
|
282
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
283
|
+
|
|
284
|
+
let result = ''
|
|
285
|
+
|
|
286
|
+
if (isNegative) {
|
|
287
|
+
result = NEGATIVE + ' '
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
result += integerToWords(integerPart)
|
|
291
|
+
|
|
292
|
+
if (decimalPart) {
|
|
293
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return result
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// ============================================================================
|
|
300
|
+
// Ordinal Functions
|
|
301
|
+
// ============================================================================
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Converts a non-negative integer to Georgian ordinal words.
|
|
305
|
+
* Georgian ordinals are formed by:
|
|
306
|
+
* - 1-9: special forms (პირველი, მეორე, მესამე, etc.)
|
|
307
|
+
* - 10+: მე- prefix + cardinal + -ე suffix
|
|
308
|
+
*
|
|
309
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
310
|
+
* @returns {string} Georgian ordinal words
|
|
311
|
+
*/
|
|
312
|
+
function integerToOrdinal (n) {
|
|
313
|
+
if (n === 0n) return ''
|
|
314
|
+
if (n <= 9n) return ORDINAL_ONES[Number(n)]
|
|
315
|
+
|
|
316
|
+
// For 10+, use მე- + cardinal stem + -ე
|
|
317
|
+
const cardinal = integerToWords(n)
|
|
318
|
+
|
|
319
|
+
// Remove final vowel and add -ე suffix
|
|
320
|
+
const lastChar = cardinal.slice(-1)
|
|
321
|
+
let stem
|
|
322
|
+
if (lastChar === 'ი' || lastChar === 'ა') {
|
|
323
|
+
stem = cardinal.slice(0, -1)
|
|
324
|
+
} else {
|
|
325
|
+
stem = cardinal
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return 'მე' + stem + ORDINAL_SUFFIX
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Converts a numeric value to Georgian ordinal words.
|
|
333
|
+
*
|
|
334
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
335
|
+
* @returns {string} The ordinal in Georgian words
|
|
336
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
337
|
+
* @throws {Error} If value is not a positive integer
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* toOrdinal(1) // 'პირველი'
|
|
341
|
+
* toOrdinal(10) // 'მეათე'
|
|
342
|
+
* toOrdinal(21) // 'მეოცდაერთე'
|
|
343
|
+
*/
|
|
344
|
+
function toOrdinal (value) {
|
|
345
|
+
const n = parseOrdinalValue(value)
|
|
346
|
+
return integerToOrdinal(n)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// ============================================================================
|
|
350
|
+
// Currency Functions
|
|
351
|
+
// ============================================================================
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Converts a numeric value to Georgian Lari currency words.
|
|
355
|
+
*
|
|
356
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
357
|
+
* @returns {string} The currency in Georgian words
|
|
358
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
359
|
+
* @throws {Error} If value is not a valid number format
|
|
360
|
+
*
|
|
361
|
+
* @example
|
|
362
|
+
* toCurrency(1) // 'ერთი ლარი'
|
|
363
|
+
* toCurrency(2.50) // 'ორი ლარი ორმოცდაათი თეთრი'
|
|
364
|
+
*/
|
|
365
|
+
function toCurrency (value) {
|
|
366
|
+
const { isNegative, dollars, cents } = parseCurrencyValue(value)
|
|
367
|
+
|
|
368
|
+
const parts = []
|
|
369
|
+
|
|
370
|
+
if (isNegative) {
|
|
371
|
+
parts.push(NEGATIVE)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Lari
|
|
375
|
+
if (dollars > 0n || cents === 0n) {
|
|
376
|
+
const lariWord = integerToWords(dollars)
|
|
377
|
+
parts.push(lariWord + ' ' + LARI)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Tetri
|
|
381
|
+
if (cents > 0n) {
|
|
382
|
+
const tetriWord = integerToWords(cents)
|
|
383
|
+
parts.push(tetriWord + ' ' + TETRI)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return parts.join(' ')
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// ============================================================================
|
|
390
|
+
// Public API
|
|
391
|
+
// ============================================================================
|
|
392
|
+
|
|
393
|
+
export { toCardinal, toOrdinal, toCurrency }
|