n2words 3.1.0 → 5.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 +51 -40
- 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-BR.js +2 -0
- package/dist/pt-BR.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 +61 -88
- 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/{lib/languages/bn.js → src/bn-BD.js} +110 -6
- package/src/cs-CZ.d.ts +49 -0
- package/{lib/languages/cs.js → src/cs-CZ.js} +240 -14
- package/src/da-DK.d.ts +44 -0
- package/{lib/languages/da.js → src/da-DK.js} +131 -11
- 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/{lib/languages/en.js → src/en-NZ.js} +164 -31
- 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} +228 -18
- 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/{lib/languages/fi.js → src/fi-FI.js} +152 -11
- package/src/fil-PH.d.ts +37 -0
- package/{lib/languages/fil.js → src/fil-PH.js} +144 -8
- package/src/fr-BE.d.ts +49 -0
- package/{lib/languages → src}/fr-BE.js +175 -13
- package/src/fr-FR.d.ts +63 -0
- package/{lib/languages/fr.js → src/fr-FR.js} +182 -16
- package/src/gu-IN.d.ts +35 -0
- package/{lib/languages/gu.js → src/gu-IN.js} +115 -6
- package/src/ha-NG.d.ts +37 -0
- package/{lib/languages/ha.js → src/ha-NG.js} +107 -8
- package/src/hbo-IL.d.ts +39 -0
- package/{lib/languages/hbo.js → src/hbo-IL.js} +211 -19
- package/src/he-IL.d.ts +37 -0
- package/src/he-IL.js +537 -0
- package/src/hi-IN.d.ts +36 -0
- package/{lib/languages/hi.js → src/hi-IN.js} +116 -6
- 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} +99 -8
- package/src/it-IT.d.ts +59 -0
- package/{lib/languages/it.js → src/it-IT.js} +179 -15
- package/src/ja-JP.d.ts +49 -0
- package/{lib/languages/ja.js → src/ja-JP.js} +111 -12
- package/src/ka-GE.d.ts +44 -0
- package/{lib/languages/ka.js → src/ka-GE.js} +113 -11
- package/src/kn-IN.d.ts +35 -0
- package/{lib/languages/kn.js → src/kn-IN.js} +115 -6
- package/src/ko-KR.d.ts +45 -0
- package/{lib/languages/ko.js → src/ko-KR.js} +94 -12
- 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/{lib/languages/mr.js → src/mr-IN.js} +116 -6
- package/src/ms-MY.d.ts +37 -0
- package/{lib/languages/ms.js → src/ms-MY.js} +111 -8
- package/src/nb-NO.d.ts +44 -0
- package/{lib/languages/nb.js → src/nb-NO.js} +153 -11
- package/src/nl-NL.d.ts +54 -0
- package/{lib/languages/nl.js → src/nl-NL.js} +260 -18
- package/src/pa-IN.d.ts +36 -0
- package/{lib/languages/pa.js → src/pa-IN.js} +116 -6
- package/src/pl-PL.d.ts +55 -0
- package/src/pl-PL.js +585 -0
- package/src/pt-BR.d.ts +31 -0
- package/src/pt-BR.js +534 -0
- package/src/pt-PT.d.ts +45 -0
- package/{lib/languages/pt.js → src/pt-PT.js} +234 -12
- 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} +136 -11
- 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} +109 -6
- package/src/te-IN.d.ts +35 -0
- package/{lib/languages/te.js → src/te-IN.js} +115 -6
- 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/{lib/languages/tr.js → src/tr-TR.js} +168 -23
- package/src/uk-UA.d.ts +42 -0
- package/src/uk-UA.js +463 -0
- package/src/ur-PK.d.ts +36 -0
- package/{lib/languages/ur.js → src/ur-PK.js} +116 -6
- 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} +102 -11
- package/src/yo-NG.d.ts +37 -0
- package/{lib/languages/yo.js → src/yo-NG.js} +109 -9
- 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/ka.js +0 -3
- package/dist/languages/ka.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/yo.js +0 -3
- package/dist/languages/yo.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 -159
- package/lib/languages/am.d.ts +0 -7
- package/lib/languages/am.js +0 -159
- package/lib/languages/ar.d.ts +0 -17
- package/lib/languages/az.d.ts +0 -7
- package/lib/languages/az.js +0 -171
- package/lib/languages/bn.d.ts +0 -7
- 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 -320
- package/lib/languages/el.d.ts +0 -14
- package/lib/languages/el.js +0 -236
- package/lib/languages/en.d.ts +0 -17
- 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/fil.d.ts +0 -7
- package/lib/languages/fr-BE.d.ts +0 -11
- package/lib/languages/fr.d.ts +0 -21
- package/lib/languages/gu.d.ts +0 -7
- 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 -265
- package/lib/languages/hi.d.ts +0 -7
- package/lib/languages/hr.d.ts +0 -11
- package/lib/languages/hr.js +0 -224
- 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/ja.d.ts +0 -17
- package/lib/languages/ka.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 -301
- package/lib/languages/lv.d.ts +0 -18
- package/lib/languages/lv.js +0 -312
- package/lib/languages/mr.d.ts +0 -7
- 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/pl.d.ts +0 -22
- package/lib/languages/pl.js +0 -317
- package/lib/languages/pt.d.ts +0 -17
- package/lib/languages/ro.d.ts +0 -18
- package/lib/languages/ru.d.ts +0 -11
- package/lib/languages/ru.js +0 -245
- package/lib/languages/sr-Cyrl.d.ts +0 -11
- package/lib/languages/sr-Cyrl.js +0 -221
- package/lib/languages/sr-Latn.d.ts +0 -11
- package/lib/languages/sr-Latn.js +0 -221
- 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/uk.d.ts +0 -11
- package/lib/languages/uk.js +0 -224
- package/lib/languages/ur.d.ts +0 -7
- package/lib/languages/vi.d.ts +0 -17
- package/lib/languages/yo.d.ts +0 -7
- package/lib/languages/zh-Hans.d.ts +0 -11
- package/lib/languages/zh-Hant.d.ts +0 -11
- package/lib/n2words.d.ts +0 -55
- package/lib/n2words.js +0 -126
- 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
package/src/es-ES.js
ADDED
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spanish (Spain) language converter
|
|
3
|
+
*
|
|
4
|
+
* CLDR: es-ES | Spanish as used in Spain
|
|
5
|
+
*
|
|
6
|
+
* Uses the European long scale numbering system:
|
|
7
|
+
* - 10⁶ = millón
|
|
8
|
+
* - 10⁹ = mil millones (thousand millions)
|
|
9
|
+
* - 10¹² = billón
|
|
10
|
+
*
|
|
11
|
+
* Spanish-specific rules:
|
|
12
|
+
* - Gender agreement: uno/una, veintiuno/veintiuna, hundreds
|
|
13
|
+
* - Special twenties: veinte, veintiuno, veintidós, ... veintinueve
|
|
14
|
+
* - "y" conjunction: treinta y uno (only 30-99 with ones)
|
|
15
|
+
* - "cien" for exact 100, "ciento/cienta" otherwise
|
|
16
|
+
* - Irregular hundreds: quinientos, setecientos, novecientos
|
|
17
|
+
* - "un" before millón (not "uno"), omit before mil
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
21
|
+
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
22
|
+
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
23
|
+
import { validateOptions } from './utils/validate-options.js'
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Vocabulary (module-level constants)
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
const ONES_MASC = ['', 'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve']
|
|
30
|
+
const ONES_FEM = ['', 'una', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve']
|
|
31
|
+
|
|
32
|
+
const TEENS = ['diez', 'once', 'doce', 'trece', 'catorce', 'quince', 'dieciseis', 'diecisiete', 'dieciocho', 'diecinueve']
|
|
33
|
+
|
|
34
|
+
// 20-29 have special compound forms
|
|
35
|
+
const TWENTIES_MASC = ['veinte', 'veintiuno', 'veintidós', 'veintitrés', 'veinticuatro', 'veinticinco', 'veintiséis', 'veintisiete', 'veintiocho', 'veintinueve']
|
|
36
|
+
const TWENTIES_FEM = ['veinte', 'veintiuna', 'veintidós', 'veintitrés', 'veinticuatro', 'veinticinco', 'veintiséis', 'veintisiete', 'veintiocho', 'veintinueve']
|
|
37
|
+
|
|
38
|
+
const TENS = ['', '', '', 'treinta', 'cuarenta', 'cincuenta', 'sesenta', 'setenta', 'ochenta', 'noventa']
|
|
39
|
+
|
|
40
|
+
// Irregular hundreds
|
|
41
|
+
const HUNDREDS_MASC = ['', 'ciento', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos', 'seiscientos', 'setecientos', 'ochocientos', 'novecientos']
|
|
42
|
+
const HUNDREDS_FEM = ['', 'cienta', 'doscientas', 'trescientas', 'cuatrocientas', 'quinientas', 'seiscientas', 'setecientas', 'ochocientas', 'novecientas']
|
|
43
|
+
|
|
44
|
+
// Scale words (compound long scale)
|
|
45
|
+
const SCALES = ['millón', 'billón', 'trillón', 'cuatrillón']
|
|
46
|
+
const SCALES_PLURAL = ['millones', 'billones', 'trillones', 'cuatrillones']
|
|
47
|
+
|
|
48
|
+
const THOUSAND = 'mil'
|
|
49
|
+
const ZERO = 'cero'
|
|
50
|
+
const NEGATIVE = 'menos'
|
|
51
|
+
const DECIMAL_SEP = 'punto'
|
|
52
|
+
|
|
53
|
+
// Ordinal vocabulary (1-10 have unique forms, higher numbers use patterns)
|
|
54
|
+
// Spanish ordinals agree in gender: primero/primera, segundo/segunda
|
|
55
|
+
const ORDINAL_ONES_MASC = ['', 'primero', 'segundo', 'tercero', 'cuarto', 'quinto', 'sexto', 'séptimo', 'octavo', 'noveno']
|
|
56
|
+
const ORDINAL_ONES_FEM = ['', 'primera', 'segunda', 'tercera', 'cuarta', 'quinta', 'sexta', 'séptima', 'octava', 'novena']
|
|
57
|
+
const ORDINAL_TENS_MASC = ['', 'décimo', 'vigésimo', 'trigésimo', 'cuadragésimo', 'quincuagésimo', 'sexagésimo', 'septuagésimo', 'octogésimo', 'nonagésimo']
|
|
58
|
+
const ORDINAL_TENS_FEM = ['', 'décima', 'vigésima', 'trigésima', 'cuadragésima', 'quincuagésima', 'sexagésima', 'septuagésima', 'octogésima', 'nonagésima']
|
|
59
|
+
const ORDINAL_HUNDRED_MASC = 'centésimo'
|
|
60
|
+
const ORDINAL_HUNDRED_FEM = 'centésima'
|
|
61
|
+
const ORDINAL_THOUSAND_MASC = 'milésimo'
|
|
62
|
+
const ORDINAL_THOUSAND_FEM = 'milésima'
|
|
63
|
+
const ORDINAL_MILLION_MASC = 'millonésimo'
|
|
64
|
+
const ORDINAL_MILLION_FEM = 'millonésima'
|
|
65
|
+
|
|
66
|
+
// Currency vocabulary (Euro - Spain's official currency)
|
|
67
|
+
const EURO = 'euro'
|
|
68
|
+
const EUROS = 'euros'
|
|
69
|
+
const CENTIMO = 'céntimo'
|
|
70
|
+
const CENTIMOS = 'céntimos'
|
|
71
|
+
const CURRENCY_CONNECTOR = 'con'
|
|
72
|
+
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Segment Building
|
|
75
|
+
// ============================================================================
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Builds segment word for 0-999.
|
|
79
|
+
* @param {number} n - Segment value
|
|
80
|
+
* @param {boolean} feminine - Use feminine forms
|
|
81
|
+
* @returns {string} Spanish word
|
|
82
|
+
*/
|
|
83
|
+
function buildSegment (n, feminine) {
|
|
84
|
+
if (n === 0) return ''
|
|
85
|
+
|
|
86
|
+
// Special case: exact 100 is "cien" (no gender)
|
|
87
|
+
if (n === 100) return 'cien'
|
|
88
|
+
|
|
89
|
+
const ones = n % 10
|
|
90
|
+
const tens = Math.trunc(n / 10) % 10
|
|
91
|
+
const hundreds = Math.trunc(n / 100)
|
|
92
|
+
const tensOnes = n % 100
|
|
93
|
+
|
|
94
|
+
const parts = []
|
|
95
|
+
|
|
96
|
+
// Hundreds
|
|
97
|
+
if (hundreds > 0) {
|
|
98
|
+
const hundredsArr = feminine ? HUNDREDS_FEM : HUNDREDS_MASC
|
|
99
|
+
parts.push(hundredsArr[hundreds])
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Tens and ones
|
|
103
|
+
if (tensOnes === 0) {
|
|
104
|
+
// Just hundreds
|
|
105
|
+
} else if (tensOnes < 10) {
|
|
106
|
+
// Single digit
|
|
107
|
+
const onesArr = feminine ? ONES_FEM : ONES_MASC
|
|
108
|
+
parts.push(onesArr[tensOnes])
|
|
109
|
+
} else if (tensOnes < 20) {
|
|
110
|
+
// 10-19: teens
|
|
111
|
+
parts.push(TEENS[ones])
|
|
112
|
+
} else if (tensOnes < 30) {
|
|
113
|
+
// 20-29: special twenties
|
|
114
|
+
const twentiesArr = feminine ? TWENTIES_FEM : TWENTIES_MASC
|
|
115
|
+
parts.push(twentiesArr[ones])
|
|
116
|
+
} else {
|
|
117
|
+
// 30-99: tens y ones
|
|
118
|
+
if (ones === 0) {
|
|
119
|
+
parts.push(TENS[tens])
|
|
120
|
+
} else {
|
|
121
|
+
const onesArr = feminine ? ONES_FEM : ONES_MASC
|
|
122
|
+
parts.push(TENS[tens] + ' y ' + onesArr[ones])
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return parts.join(' ')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Helper Functions
|
|
131
|
+
// ============================================================================
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Gets scale word for Spanish compound long scale.
|
|
135
|
+
*
|
|
136
|
+
* @param {number} scaleIndex - Scale level (1 = thousand, 2 = million, etc.)
|
|
137
|
+
* @param {bigint} segment - Segment value for pluralization
|
|
138
|
+
* @returns {string} Scale word
|
|
139
|
+
*/
|
|
140
|
+
function getScaleWord (scaleIndex, segment) {
|
|
141
|
+
if (scaleIndex === 1) return THOUSAND
|
|
142
|
+
|
|
143
|
+
// Even indices (2, 4, 6, 8): millón, billón, trillón, cuatrillón
|
|
144
|
+
// Odd indices > 1 (3, 5, 7): mil millones, mil billones, mil trillones
|
|
145
|
+
if (scaleIndex % 2 === 0) {
|
|
146
|
+
const arrayIndex = (scaleIndex / 2) - 1
|
|
147
|
+
const baseWord = SCALES[arrayIndex]
|
|
148
|
+
if (!baseWord) return ''
|
|
149
|
+
return segment > 1n ? SCALES_PLURAL[arrayIndex] : baseWord
|
|
150
|
+
} else {
|
|
151
|
+
// Compound: "mil millones" pattern
|
|
152
|
+
const arrayIndex = ((scaleIndex - 1) / 2) - 1
|
|
153
|
+
const pluralWord = SCALES_PLURAL[arrayIndex]
|
|
154
|
+
if (!pluralWord) return THOUSAND
|
|
155
|
+
return THOUSAND + ' ' + pluralWord
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Conversion Functions
|
|
161
|
+
// ============================================================================
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Converts a non-negative integer to Spanish words.
|
|
165
|
+
*
|
|
166
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
167
|
+
* @param {boolean} feminine - Use feminine forms
|
|
168
|
+
* @returns {string} Spanish words
|
|
169
|
+
*/
|
|
170
|
+
function integerToWords (n, feminine) {
|
|
171
|
+
if (n === 0n) return ZERO
|
|
172
|
+
|
|
173
|
+
// Fast path: numbers < 1000
|
|
174
|
+
if (n < 1000n) {
|
|
175
|
+
return buildSegment(Number(n), feminine)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Fast path: numbers < 1,000,000 (thousands)
|
|
179
|
+
if (n < 1_000_000n) {
|
|
180
|
+
const thousands = Number(n / 1000n)
|
|
181
|
+
const remainder = Number(n % 1000n)
|
|
182
|
+
|
|
183
|
+
let result
|
|
184
|
+
if (thousands === 1) {
|
|
185
|
+
// "mil" not "uno mil"
|
|
186
|
+
result = THOUSAND
|
|
187
|
+
} else {
|
|
188
|
+
// Use masculine for thousands segment, but check for "uno" → omit before mil
|
|
189
|
+
const thousandsWord = buildSegment(thousands, false)
|
|
190
|
+
// "uno mil" → "mil" (handled in joinSegments equivalent)
|
|
191
|
+
if (thousandsWord === 'uno' || thousandsWord === 'una') {
|
|
192
|
+
result = THOUSAND
|
|
193
|
+
} else {
|
|
194
|
+
result = thousandsWord + ' ' + THOUSAND
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (remainder > 0) {
|
|
199
|
+
result += ' ' + buildSegment(remainder, feminine)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return result
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
206
|
+
return buildLargeNumberWords(n, feminine)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Builds words for numbers >= 1,000,000.
|
|
211
|
+
* Uses BigInt division for faster segment extraction.
|
|
212
|
+
*
|
|
213
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
214
|
+
* @param {boolean} feminine - Use feminine forms
|
|
215
|
+
* @returns {string} Spanish words
|
|
216
|
+
*/
|
|
217
|
+
function buildLargeNumberWords (n, feminine) {
|
|
218
|
+
// Extract segments using BigInt division (faster than string slicing)
|
|
219
|
+
// Segments stored least-significant first (index 0 = ones, 1 = thousands, etc.)
|
|
220
|
+
const segmentValues = []
|
|
221
|
+
let temp = n
|
|
222
|
+
while (temp > 0n) {
|
|
223
|
+
segmentValues.push(temp % 1000n)
|
|
224
|
+
temp = temp / 1000n
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Build result string directly
|
|
228
|
+
let result = ''
|
|
229
|
+
|
|
230
|
+
for (let i = segmentValues.length - 1; i >= 0; i--) {
|
|
231
|
+
const segment = segmentValues[i]
|
|
232
|
+
if (segment === 0n) continue
|
|
233
|
+
|
|
234
|
+
const scaleWord = i > 0 ? getScaleWord(i, segment) : ''
|
|
235
|
+
|
|
236
|
+
if (result) result += ' '
|
|
237
|
+
|
|
238
|
+
if (i === 0) {
|
|
239
|
+
// Units segment
|
|
240
|
+
result += buildSegment(Number(segment), feminine)
|
|
241
|
+
} else if (i === 1) {
|
|
242
|
+
// Thousands: omit "uno" before mil
|
|
243
|
+
if (segment === 1n) {
|
|
244
|
+
result += THOUSAND
|
|
245
|
+
} else {
|
|
246
|
+
result += buildSegment(Number(segment), false) + ' ' + scaleWord
|
|
247
|
+
}
|
|
248
|
+
} else if (i % 2 === 1) {
|
|
249
|
+
// Odd scale indices (3, 5, 7): "mil millones", "mil billones", etc.
|
|
250
|
+
// Omit "uno" before these compound scales
|
|
251
|
+
if (segment === 1n) {
|
|
252
|
+
result += scaleWord
|
|
253
|
+
} else {
|
|
254
|
+
result += buildSegment(Number(segment), false) + ' ' + scaleWord
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
// Even scale indices (2, 4, 6): millón, billón, trillón
|
|
258
|
+
if (segment === 1n) {
|
|
259
|
+
// "un millón" not "uno millón"
|
|
260
|
+
result += 'un ' + scaleWord
|
|
261
|
+
} else {
|
|
262
|
+
// Use masculine for scale segment
|
|
263
|
+
result += buildSegment(Number(segment), false) + ' ' + scaleWord
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return result
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Converts decimal digits to Spanish words.
|
|
273
|
+
*
|
|
274
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
275
|
+
* @param {boolean} feminine - Use feminine forms
|
|
276
|
+
* @returns {string} Spanish words for decimal part
|
|
277
|
+
*/
|
|
278
|
+
function decimalPartToWords (decimalPart, feminine) {
|
|
279
|
+
let result = ''
|
|
280
|
+
|
|
281
|
+
// Handle leading zeros
|
|
282
|
+
let i = 0
|
|
283
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
284
|
+
if (result) result += ' '
|
|
285
|
+
result += ZERO
|
|
286
|
+
i++
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Convert remainder as a single number
|
|
290
|
+
const remainder = decimalPart.slice(i)
|
|
291
|
+
if (remainder) {
|
|
292
|
+
if (result) result += ' '
|
|
293
|
+
result += integerToWords(BigInt(remainder), feminine)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return result
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Converts a numeric value to Spanish words.
|
|
301
|
+
*
|
|
302
|
+
* This is the main public API. It accepts any valid numeric input
|
|
303
|
+
* (number, string, or bigint) and handles parsing internally.
|
|
304
|
+
*
|
|
305
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
306
|
+
* @param {Object} [options] - Optional configuration
|
|
307
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
308
|
+
* @returns {string} The number in Spanish words
|
|
309
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
310
|
+
* @throws {Error} If value is not a valid number format
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* toCardinal(21) // 'veintiuno'
|
|
314
|
+
* toCardinal(21, {gender: 'feminine'}) // 'veintiuna'
|
|
315
|
+
* toCardinal(1000000) // 'un millón'
|
|
316
|
+
*/
|
|
317
|
+
function toCardinal (value, options) {
|
|
318
|
+
options = validateOptions(options)
|
|
319
|
+
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
320
|
+
|
|
321
|
+
// Apply option defaults
|
|
322
|
+
const { gender = 'masculine' } = options
|
|
323
|
+
const feminine = gender === 'feminine'
|
|
324
|
+
|
|
325
|
+
let result = ''
|
|
326
|
+
|
|
327
|
+
if (isNegative) {
|
|
328
|
+
result = NEGATIVE + ' '
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
result += integerToWords(integerPart, feminine)
|
|
332
|
+
|
|
333
|
+
if (decimalPart) {
|
|
334
|
+
result += ' ' + DECIMAL_SEP + ' ' + decimalPartToWords(decimalPart, feminine)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return result
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ============================================================================
|
|
341
|
+
// ORDINAL: toOrdinal(value, options?)
|
|
342
|
+
// ============================================================================
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Builds ordinal word for a 0-999 segment.
|
|
346
|
+
*
|
|
347
|
+
* Spanish ordinals use additive patterns:
|
|
348
|
+
* - 11th = "undécimo" (décimo + primero contracted)
|
|
349
|
+
* - 21st = "vigésimo primero"
|
|
350
|
+
* - 100th = "centésimo"
|
|
351
|
+
* - 101st = "centésimo primero"
|
|
352
|
+
*
|
|
353
|
+
* @param {number} n - Segment value 0-999
|
|
354
|
+
* @param {boolean} feminine - Use feminine forms
|
|
355
|
+
* @returns {string} Spanish ordinal word
|
|
356
|
+
*/
|
|
357
|
+
function buildOrdinalSegment (n, feminine) {
|
|
358
|
+
if (n === 0) return ''
|
|
359
|
+
|
|
360
|
+
const ones = n % 10
|
|
361
|
+
const tens = Math.trunc(n / 10) % 10
|
|
362
|
+
const hundreds = Math.trunc(n / 100)
|
|
363
|
+
|
|
364
|
+
const onesArr = feminine ? ORDINAL_ONES_FEM : ORDINAL_ONES_MASC
|
|
365
|
+
const tensArr = feminine ? ORDINAL_TENS_FEM : ORDINAL_TENS_MASC
|
|
366
|
+
const hundredWord = feminine ? ORDINAL_HUNDRED_FEM : ORDINAL_HUNDRED_MASC
|
|
367
|
+
|
|
368
|
+
const parts = []
|
|
369
|
+
|
|
370
|
+
// Hundreds
|
|
371
|
+
if (hundreds > 0) {
|
|
372
|
+
if (hundreds === 1) {
|
|
373
|
+
parts.push(hundredWord)
|
|
374
|
+
} else {
|
|
375
|
+
// 200th = ducentésimo, 300th = tricentésimo, etc.
|
|
376
|
+
// Use cardinal prefix + centésimo
|
|
377
|
+
const prefixes = ['', '', 'du', 'tri', 'cuadri', 'quin', 'sex', 'septi', 'octi', 'noni']
|
|
378
|
+
parts.push(prefixes[hundreds] + hundredWord)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Tens
|
|
383
|
+
if (tens > 0) {
|
|
384
|
+
parts.push(tensArr[tens])
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Ones
|
|
388
|
+
if (ones > 0) {
|
|
389
|
+
parts.push(onesArr[ones])
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return parts.join(' ')
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Converts a positive integer to Spanish ordinal words.
|
|
397
|
+
*
|
|
398
|
+
* @param {bigint} n - Positive integer to convert
|
|
399
|
+
* @param {boolean} feminine - Use feminine forms
|
|
400
|
+
* @returns {string} Spanish ordinal words
|
|
401
|
+
*/
|
|
402
|
+
function integerToOrdinal (n, feminine) {
|
|
403
|
+
const thousandWord = feminine ? ORDINAL_THOUSAND_FEM : ORDINAL_THOUSAND_MASC
|
|
404
|
+
const millionWord = feminine ? ORDINAL_MILLION_FEM : ORDINAL_MILLION_MASC
|
|
405
|
+
|
|
406
|
+
// Fast path: numbers < 1000
|
|
407
|
+
if (n < 1000n) {
|
|
408
|
+
return buildOrdinalSegment(Number(n), feminine)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Numbers 1000-999999
|
|
412
|
+
if (n < 1_000_000n) {
|
|
413
|
+
const thousands = Number(n / 1000n)
|
|
414
|
+
const remainder = Number(n % 1000n)
|
|
415
|
+
|
|
416
|
+
let result = ''
|
|
417
|
+
|
|
418
|
+
if (thousands === 1) {
|
|
419
|
+
result = thousandWord
|
|
420
|
+
} else {
|
|
421
|
+
// Use ordinal for thousands multiplier
|
|
422
|
+
result = buildOrdinalSegment(thousands, feminine) + ' ' + thousandWord
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (remainder > 0) {
|
|
426
|
+
result += ' ' + buildOrdinalSegment(remainder, feminine)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return result
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Numbers >= 1,000,000
|
|
433
|
+
const millions = Number(n / 1_000_000n)
|
|
434
|
+
const remainder = n % 1_000_000n
|
|
435
|
+
|
|
436
|
+
let result = ''
|
|
437
|
+
|
|
438
|
+
if (millions === 1) {
|
|
439
|
+
result = millionWord
|
|
440
|
+
} else {
|
|
441
|
+
result = buildOrdinalSegment(millions, feminine) + ' ' + millionWord
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (remainder > 0n) {
|
|
445
|
+
result += ' ' + integerToOrdinal(remainder, feminine)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return result
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Converts a numeric value to Spanish ordinal words.
|
|
453
|
+
*
|
|
454
|
+
* Spanish ordinals agree in gender with the noun they modify.
|
|
455
|
+
* Only positive integers are valid for ordinals.
|
|
456
|
+
*
|
|
457
|
+
* @param {number | string | bigint} value - The positive integer to convert
|
|
458
|
+
* @param {Object} [options] - Optional configuration
|
|
459
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
460
|
+
* @returns {string} The number in Spanish ordinal words
|
|
461
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
462
|
+
* @throws {Error} If value is not a positive integer
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* toOrdinal(1) // 'primero'
|
|
466
|
+
* toOrdinal(1, { gender: 'feminine' }) // 'primera'
|
|
467
|
+
* toOrdinal(21) // 'vigésimo primero'
|
|
468
|
+
* toOrdinal(100) // 'centésimo'
|
|
469
|
+
*/
|
|
470
|
+
function toOrdinal (value, options) {
|
|
471
|
+
options = validateOptions(options)
|
|
472
|
+
const integerPart = parseOrdinalValue(value)
|
|
473
|
+
|
|
474
|
+
const { gender = 'masculine' } = options
|
|
475
|
+
const feminine = gender === 'feminine'
|
|
476
|
+
|
|
477
|
+
return integerToOrdinal(integerPart, feminine)
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// ============================================================================
|
|
481
|
+
// CURRENCY: toCurrency(value, options?)
|
|
482
|
+
// ============================================================================
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Converts a numeric value to Spanish Euro currency words.
|
|
486
|
+
*
|
|
487
|
+
* Spanish currency uses masculine gender for euros (el euro)
|
|
488
|
+
* and masculine for céntimos (el céntimo).
|
|
489
|
+
*
|
|
490
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
491
|
+
* @param {Object} [options] - Optional configuration
|
|
492
|
+
* @param {boolean} [options.and=true] - Use "con" between euros and cents
|
|
493
|
+
* @returns {string} The amount in Spanish currency words
|
|
494
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
495
|
+
* @throws {Error} If value is not a valid number format
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* toCurrency(42.50) // 'cuarenta y dos euros con cincuenta céntimos'
|
|
499
|
+
* toCurrency(1) // 'un euro'
|
|
500
|
+
* toCurrency(0.99) // 'noventa y nueve céntimos'
|
|
501
|
+
* toCurrency(42.50, { and: false }) // 'cuarenta y dos euros cincuenta céntimos'
|
|
502
|
+
*/
|
|
503
|
+
function toCurrency (value, options) {
|
|
504
|
+
options = validateOptions(options)
|
|
505
|
+
const { isNegative, dollars: euros, cents: centimos } = parseCurrencyValue(value)
|
|
506
|
+
const { and: useAnd = true } = options
|
|
507
|
+
|
|
508
|
+
let result = ''
|
|
509
|
+
if (isNegative) result = NEGATIVE + ' '
|
|
510
|
+
|
|
511
|
+
// Euros part (show if non-zero, or if no centimos)
|
|
512
|
+
if (euros > 0n || centimos === 0n) {
|
|
513
|
+
// Use masculine for euros, but "un euro" not "uno euro"
|
|
514
|
+
if (euros === 1n) {
|
|
515
|
+
result += 'un ' + EURO
|
|
516
|
+
} else {
|
|
517
|
+
result += integerToWords(euros, false) + ' ' + EUROS
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Centimos part
|
|
522
|
+
if (centimos > 0n) {
|
|
523
|
+
if (euros > 0n) {
|
|
524
|
+
result += useAnd ? ' ' + CURRENCY_CONNECTOR + ' ' : ' '
|
|
525
|
+
}
|
|
526
|
+
// Use masculine for centimos, but "un céntimo" not "uno céntimo"
|
|
527
|
+
if (centimos === 1n) {
|
|
528
|
+
result += 'un ' + CENTIMO
|
|
529
|
+
} else {
|
|
530
|
+
result += integerToWords(centimos, false) + ' ' + CENTIMOS
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
return result
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// ============================================================================
|
|
538
|
+
// Public API
|
|
539
|
+
// ============================================================================
|
|
540
|
+
|
|
541
|
+
export { toCardinal, toOrdinal, toCurrency }
|
package/src/es-MX.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Spanish words (long scale).
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @param {Object} [options] - Optional configuration
|
|
6
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
7
|
+
* @returns {string} The number in Spanish words
|
|
8
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
9
|
+
* @throws {Error} If value is not a valid number format
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* toCardinal(21) // 'veintiuno'
|
|
13
|
+
* toCardinal(21, {gender: 'feminine'}) // 'veintiuna'
|
|
14
|
+
* toCardinal(1000000000) // 'mil millones'
|
|
15
|
+
*/
|
|
16
|
+
export function toCardinal(value: number | string | bigint, options?: {
|
|
17
|
+
gender?: "masculine" | "feminine" | undefined;
|
|
18
|
+
}): string;
|
|
19
|
+
/**
|
|
20
|
+
* Converts a numeric value to Spanish ordinal words.
|
|
21
|
+
*
|
|
22
|
+
* @param {number | string | bigint} value - The positive integer to convert
|
|
23
|
+
* @param {Object} [options] - Optional configuration
|
|
24
|
+
* @param {('masculine'|'feminine')} [options.gender='masculine'] - Grammatical gender
|
|
25
|
+
* @returns {string} The number in Spanish ordinal words
|
|
26
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
27
|
+
* @throws {Error} If value is not a positive integer
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* toOrdinal(1) // 'primero'
|
|
31
|
+
* toOrdinal(1, { gender: 'feminine' }) // 'primera'
|
|
32
|
+
* toOrdinal(21) // 'vigésimo primero'
|
|
33
|
+
*/
|
|
34
|
+
export function toOrdinal(value: number | string | bigint, options?: {
|
|
35
|
+
gender?: "masculine" | "feminine" | undefined;
|
|
36
|
+
}): string;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a numeric value to Mexican Peso currency words.
|
|
39
|
+
*
|
|
40
|
+
* Mexican currency uses masculine gender for pesos (el peso)
|
|
41
|
+
* and masculine for centavos (el centavo).
|
|
42
|
+
*
|
|
43
|
+
* @param {number | string | bigint} value - The currency amount to convert
|
|
44
|
+
* @param {Object} [options] - Optional configuration
|
|
45
|
+
* @param {boolean} [options.and=true] - Use "con" between pesos and centavos
|
|
46
|
+
* @returns {string} The amount in Mexican currency words
|
|
47
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
48
|
+
* @throws {Error} If value is not a valid number format
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* toCurrency(42.50) // 'cuarenta y dos pesos con cincuenta centavos'
|
|
52
|
+
* toCurrency(1) // 'un peso'
|
|
53
|
+
* toCurrency(0.99) // 'noventa y nueve centavos'
|
|
54
|
+
* toCurrency(42.50, { and: false }) // 'cuarenta y dos pesos cincuenta centavos'
|
|
55
|
+
*/
|
|
56
|
+
export function toCurrency(value: number | string | bigint, options?: {
|
|
57
|
+
and?: boolean | undefined;
|
|
58
|
+
}): string;
|