n2words 1.24.0 → 2.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/README.md +285 -156
- package/dist/ArabicConverter.js +3 -0
- package/dist/ArabicConverter.js.map +1 -0
- package/dist/AzerbaijaniConverter.js +3 -0
- package/dist/AzerbaijaniConverter.js.map +1 -0
- package/dist/BanglaConverter.js +3 -0
- package/dist/BanglaConverter.js.map +1 -0
- package/dist/BiblicalHebrewConverter.js +3 -0
- package/dist/BiblicalHebrewConverter.js.map +1 -0
- package/dist/CroatianConverter.js +3 -0
- package/dist/CroatianConverter.js.map +1 -0
- package/dist/CzechConverter.js +3 -0
- package/dist/CzechConverter.js.map +1 -0
- package/dist/DanishConverter.js +3 -0
- package/dist/DanishConverter.js.map +1 -0
- package/dist/DutchConverter.js +3 -0
- package/dist/DutchConverter.js.map +1 -0
- package/dist/EnglishConverter.js +3 -0
- package/dist/EnglishConverter.js.map +1 -0
- package/dist/FilipinoConverter.js +3 -0
- package/dist/FilipinoConverter.js.map +1 -0
- package/dist/FrenchBelgiumConverter.js +3 -0
- package/dist/FrenchBelgiumConverter.js.map +1 -0
- package/dist/FrenchConverter.js +3 -0
- package/dist/FrenchConverter.js.map +1 -0
- package/dist/GermanConverter.js +3 -0
- package/dist/GermanConverter.js.map +1 -0
- package/dist/GreekConverter.js +3 -0
- package/dist/GreekConverter.js.map +1 -0
- package/dist/GujaratiConverter.js +3 -0
- package/dist/GujaratiConverter.js.map +1 -0
- package/dist/HebrewConverter.js +3 -0
- package/dist/HebrewConverter.js.map +1 -0
- package/dist/HindiConverter.js +3 -0
- package/dist/HindiConverter.js.map +1 -0
- package/dist/HungarianConverter.js +3 -0
- package/dist/HungarianConverter.js.map +1 -0
- package/dist/IndonesianConverter.js +3 -0
- package/dist/IndonesianConverter.js.map +1 -0
- package/dist/ItalianConverter.js +3 -0
- package/dist/ItalianConverter.js.map +1 -0
- package/dist/JapaneseConverter.js +3 -0
- package/dist/JapaneseConverter.js.map +1 -0
- package/dist/KannadaConverter.js +3 -0
- package/dist/KannadaConverter.js.map +1 -0
- package/dist/KoreanConverter.js +3 -0
- package/dist/KoreanConverter.js.map +1 -0
- package/dist/LatvianConverter.js +3 -0
- package/dist/LatvianConverter.js.map +1 -0
- package/dist/LithuanianConverter.js +3 -0
- package/dist/LithuanianConverter.js.map +1 -0
- package/dist/MalayConverter.js +3 -0
- package/dist/MalayConverter.js.map +1 -0
- package/dist/MarathiConverter.js +3 -0
- package/dist/MarathiConverter.js.map +1 -0
- package/dist/NorwegianBokmalConverter.js +3 -0
- package/dist/NorwegianBokmalConverter.js.map +1 -0
- package/dist/PersianConverter.js +3 -0
- package/dist/PersianConverter.js.map +1 -0
- package/dist/PolishConverter.js +3 -0
- package/dist/PolishConverter.js.map +1 -0
- package/dist/PortugueseConverter.js +3 -0
- package/dist/PortugueseConverter.js.map +1 -0
- package/dist/PunjabiConverter.js +3 -0
- package/dist/PunjabiConverter.js.map +1 -0
- package/dist/RomanianConverter.js +3 -0
- package/dist/RomanianConverter.js.map +1 -0
- package/dist/RussianConverter.js +3 -0
- package/dist/RussianConverter.js.map +1 -0
- package/dist/SerbianCyrillicConverter.js +3 -0
- package/dist/SerbianCyrillicConverter.js.map +1 -0
- package/dist/SerbianLatinConverter.js +3 -0
- package/dist/SerbianLatinConverter.js.map +1 -0
- package/dist/SimplifiedChineseConverter.js +3 -0
- package/dist/SimplifiedChineseConverter.js.map +1 -0
- package/dist/SpanishConverter.js +3 -0
- package/dist/SpanishConverter.js.map +1 -0
- package/dist/SwahiliConverter.js +3 -0
- package/dist/SwahiliConverter.js.map +1 -0
- package/dist/SwedishConverter.js +3 -0
- package/dist/SwedishConverter.js.map +1 -0
- package/dist/TamilConverter.js +3 -0
- package/dist/TamilConverter.js.map +1 -0
- package/dist/TeluguConverter.js +3 -0
- package/dist/TeluguConverter.js.map +1 -0
- package/dist/ThaiConverter.js +3 -0
- package/dist/ThaiConverter.js.map +1 -0
- package/dist/TraditionalChineseConverter.js +3 -0
- package/dist/TraditionalChineseConverter.js.map +1 -0
- package/dist/TurkishConverter.js +3 -0
- package/dist/TurkishConverter.js.map +1 -0
- package/dist/UkrainianConverter.js +3 -0
- package/dist/UkrainianConverter.js.map +1 -0
- package/dist/UrduConverter.js +3 -0
- package/dist/UrduConverter.js.map +1 -0
- package/dist/VietnameseConverter.js +3 -0
- package/dist/VietnameseConverter.js.map +1 -0
- package/dist/n2words.js +3 -2
- package/dist/n2words.js.map +1 -1
- package/lib/classes/abstract-language.d.ts +178 -0
- package/lib/classes/abstract-language.js +192 -185
- package/lib/classes/greedy-scale-language.d.ts +109 -0
- package/lib/classes/greedy-scale-language.js +96 -90
- package/lib/classes/slavic-language.d.ts +148 -0
- package/lib/classes/slavic-language.js +136 -106
- package/lib/classes/south-asian-language.d.ts +70 -0
- package/lib/classes/south-asian-language.js +58 -65
- package/lib/classes/turkic-language.d.ts +26 -0
- package/lib/classes/turkic-language.js +22 -26
- package/lib/languages/ar.d.ts +30 -0
- package/lib/languages/ar.js +49 -133
- package/lib/languages/az.d.ts +12 -0
- package/lib/languages/az.js +7 -23
- package/lib/languages/bn.d.ts +11 -0
- package/lib/languages/bn.js +12 -7
- package/lib/languages/cs.d.ts +88 -0
- package/lib/languages/cs.js +44 -113
- package/lib/languages/da.d.ts +15 -0
- package/lib/languages/da.js +40 -87
- package/lib/languages/de.d.ts +14 -0
- package/lib/languages/de.js +34 -68
- package/lib/languages/el.d.ts +14 -0
- package/lib/languages/el.js +22 -48
- package/lib/languages/en.d.ts +16 -0
- package/lib/languages/en.js +22 -59
- package/lib/languages/es.d.ts +15 -0
- package/lib/languages/es.js +49 -81
- package/lib/languages/fa.d.ts +47 -0
- package/lib/languages/fa.js +90 -73
- package/lib/languages/fil.d.ts +16 -0
- package/lib/languages/fil.js +35 -76
- package/lib/languages/fr-BE.d.ts +11 -0
- package/lib/languages/fr-BE.js +15 -51
- package/lib/languages/fr.d.ts +15 -0
- package/lib/languages/fr.js +33 -72
- package/lib/languages/gu.d.ts +11 -0
- package/lib/languages/gu.js +10 -34
- package/lib/languages/hbo.d.ts +113 -0
- package/lib/languages/hbo.js +251 -0
- package/lib/languages/he.d.ts +80 -0
- package/lib/languages/he.js +41 -164
- package/lib/languages/hi.d.ts +11 -0
- package/lib/languages/hi.js +12 -7
- package/lib/languages/hr.d.ts +80 -0
- package/lib/languages/hr.js +51 -95
- package/lib/languages/hu.d.ts +22 -0
- package/lib/languages/hu.js +35 -53
- package/lib/languages/id.d.ts +37 -0
- package/lib/languages/id.js +29 -44
- package/lib/languages/it.d.ts +37 -0
- package/lib/languages/it.js +36 -52
- package/lib/languages/ja.d.ts +17 -0
- package/lib/languages/ja.js +22 -75
- package/lib/languages/kn.d.ts +11 -0
- package/lib/languages/kn.js +10 -39
- package/lib/languages/ko.d.ts +14 -0
- package/lib/languages/ko.js +17 -45
- package/lib/languages/lt.d.ts +70 -0
- package/lib/languages/lt.js +28 -63
- package/lib/languages/lv.d.ts +70 -0
- package/lib/languages/lv.js +35 -58
- package/lib/languages/mr.d.ts +11 -0
- package/lib/languages/mr.js +10 -34
- package/lib/languages/ms.d.ts +31 -0
- package/lib/languages/ms.js +24 -20
- package/lib/languages/nb.d.ts +12 -0
- package/lib/languages/nb.js +36 -56
- package/lib/languages/nl.d.ts +16 -0
- package/lib/languages/nl.js +58 -109
- package/lib/languages/pa.d.ts +11 -0
- package/lib/languages/{pa-Guru.js → pa.js} +12 -7
- package/lib/languages/pl.d.ts +80 -0
- package/lib/languages/pl.js +26 -105
- package/lib/languages/pt.d.ts +29 -0
- package/lib/languages/pt.js +29 -64
- package/lib/languages/ro.d.ts +158 -0
- package/lib/languages/ro.js +60 -167
- package/lib/languages/ru.d.ts +85 -0
- package/lib/languages/ru.js +17 -37
- package/lib/languages/sr-Cyrl.d.ts +80 -0
- package/lib/languages/sr-Cyrl.js +113 -0
- package/lib/languages/sr-Latn.d.ts +80 -0
- package/lib/languages/sr-Latn.js +54 -98
- package/lib/languages/sv.d.ts +14 -0
- package/lib/languages/sv.js +26 -63
- package/lib/languages/sw.d.ts +39 -0
- package/lib/languages/sw.js +26 -21
- package/lib/languages/ta.d.ts +20 -0
- package/lib/languages/ta.js +26 -26
- package/lib/languages/te.d.ts +22 -0
- package/lib/languages/te.js +28 -38
- package/lib/languages/th.d.ts +17 -0
- package/lib/languages/th.js +25 -31
- package/lib/languages/tr.d.ts +12 -0
- package/lib/languages/tr.js +11 -38
- package/lib/languages/uk.d.ts +85 -0
- package/lib/languages/uk.js +18 -44
- package/lib/languages/ur.d.ts +11 -0
- package/lib/languages/ur.js +12 -7
- package/lib/languages/vi.d.ts +72 -0
- package/lib/languages/vi.js +25 -71
- package/lib/languages/zh-Hans.d.ts +21 -0
- package/lib/languages/zh-Hans.js +33 -87
- package/lib/languages/zh-Hant.d.ts +21 -0
- package/lib/languages/zh-Hant.js +111 -0
- package/lib/n2words.d.ts +209 -0
- package/lib/n2words.js +474 -191
- package/package.json +106 -67
- package/dist/languages/ar.js +0 -2
- package/dist/languages/ar.js.map +0 -1
- package/dist/languages/az.js +0 -2
- package/dist/languages/az.js.map +0 -1
- package/dist/languages/bn.js +0 -2
- package/dist/languages/bn.js.map +0 -1
- package/dist/languages/cs.js +0 -2
- package/dist/languages/cs.js.map +0 -1
- package/dist/languages/da.js +0 -2
- package/dist/languages/da.js.map +0 -1
- package/dist/languages/de.js +0 -2
- package/dist/languages/de.js.map +0 -1
- package/dist/languages/el.js +0 -2
- package/dist/languages/el.js.map +0 -1
- package/dist/languages/en.js +0 -2
- package/dist/languages/en.js.map +0 -1
- package/dist/languages/es.js +0 -2
- package/dist/languages/es.js.map +0 -1
- package/dist/languages/fa.js +0 -2
- package/dist/languages/fa.js.map +0 -1
- package/dist/languages/fil.js +0 -2
- package/dist/languages/fil.js.map +0 -1
- package/dist/languages/fr-BE.js +0 -2
- package/dist/languages/fr-BE.js.map +0 -1
- package/dist/languages/fr.js +0 -2
- package/dist/languages/fr.js.map +0 -1
- package/dist/languages/gu.js +0 -2
- package/dist/languages/gu.js.map +0 -1
- package/dist/languages/he.js +0 -2
- package/dist/languages/he.js.map +0 -1
- package/dist/languages/hi.js +0 -2
- package/dist/languages/hi.js.map +0 -1
- package/dist/languages/hr.js +0 -2
- package/dist/languages/hr.js.map +0 -1
- package/dist/languages/hu.js +0 -2
- package/dist/languages/hu.js.map +0 -1
- package/dist/languages/id.js +0 -2
- package/dist/languages/id.js.map +0 -1
- package/dist/languages/it.js +0 -2
- package/dist/languages/it.js.map +0 -1
- package/dist/languages/ja.js +0 -2
- package/dist/languages/ja.js.map +0 -1
- package/dist/languages/kn.js +0 -2
- package/dist/languages/kn.js.map +0 -1
- package/dist/languages/ko.js +0 -2
- package/dist/languages/ko.js.map +0 -1
- package/dist/languages/lt.js +0 -2
- package/dist/languages/lt.js.map +0 -1
- package/dist/languages/lv.js +0 -2
- package/dist/languages/lv.js.map +0 -1
- package/dist/languages/mr.js +0 -2
- package/dist/languages/mr.js.map +0 -1
- package/dist/languages/ms.js +0 -2
- package/dist/languages/ms.js.map +0 -1
- package/dist/languages/nb.js +0 -2
- package/dist/languages/nb.js.map +0 -1
- package/dist/languages/nl.js +0 -2
- package/dist/languages/nl.js.map +0 -1
- package/dist/languages/pa-Guru.js +0 -2
- package/dist/languages/pa-Guru.js.map +0 -1
- package/dist/languages/pl.js +0 -2
- package/dist/languages/pl.js.map +0 -1
- package/dist/languages/pt.js +0 -2
- package/dist/languages/pt.js.map +0 -1
- package/dist/languages/ro.js +0 -2
- package/dist/languages/ro.js.map +0 -1
- package/dist/languages/ru.js +0 -2
- package/dist/languages/ru.js.map +0 -1
- package/dist/languages/sr-Latn.js +0 -2
- package/dist/languages/sr-Latn.js.map +0 -1
- package/dist/languages/sv.js +0 -2
- package/dist/languages/sv.js.map +0 -1
- package/dist/languages/sw.js +0 -2
- package/dist/languages/sw.js.map +0 -1
- package/dist/languages/ta.js +0 -2
- package/dist/languages/ta.js.map +0 -1
- package/dist/languages/te.js +0 -2
- package/dist/languages/te.js.map +0 -1
- package/dist/languages/th.js +0 -2
- package/dist/languages/th.js.map +0 -1
- package/dist/languages/tr.js +0 -2
- package/dist/languages/tr.js.map +0 -1
- package/dist/languages/uk.js +0 -2
- package/dist/languages/uk.js.map +0 -1
- package/dist/languages/ur.js +0 -2
- package/dist/languages/ur.js.map +0 -1
- package/dist/languages/vi.js +0 -2
- package/dist/languages/vi.js.map +0 -1
- package/dist/languages/zh-Hans.js +0 -2
- package/dist/languages/zh-Hans.js.map +0 -1
- package/typings/classes/abstract-language.d.ts +0 -144
- package/typings/classes/greedy-scale-language.d.ts +0 -148
- package/typings/classes/slavic-language.d.ts +0 -145
- package/typings/classes/south-asian-language.d.ts +0 -101
- package/typings/classes/turkic-language.d.ts +0 -42
- package/typings/languages/ar.d.ts +0 -93
- package/typings/languages/az.d.ts +0 -25
- package/typings/languages/bn.d.ts +0 -1
- package/typings/languages/cs.d.ts +0 -120
- package/typings/languages/da.d.ts +0 -53
- package/typings/languages/de.d.ts +0 -26
- package/typings/languages/el.d.ts +0 -11
- package/typings/languages/en.d.ts +0 -30
- package/typings/languages/es.d.ts +0 -43
- package/typings/languages/fa.d.ts +0 -81
- package/typings/languages/fil.d.ts +0 -12
- package/typings/languages/fr-BE.d.ts +0 -41
- package/typings/languages/fr.d.ts +0 -43
- package/typings/languages/gu.d.ts +0 -12
- package/typings/languages/he.d.ts +0 -197
- package/typings/languages/hi.d.ts +0 -1
- package/typings/languages/hr.d.ts +0 -110
- package/typings/languages/hu.d.ts +0 -37
- package/typings/languages/id.d.ts +0 -69
- package/typings/languages/it.d.ts +0 -51
- package/typings/languages/ja.d.ts +0 -58
- package/typings/languages/kn.d.ts +0 -11
- package/typings/languages/ko.d.ts +0 -25
- package/typings/languages/lt.d.ts +0 -110
- package/typings/languages/lv.d.ts +0 -99
- package/typings/languages/mr.d.ts +0 -12
- package/typings/languages/ms.d.ts +0 -37
- package/typings/languages/nb.d.ts +0 -27
- package/typings/languages/nl.d.ts +0 -65
- package/typings/languages/pa-Guru.d.ts +0 -1
- package/typings/languages/pl.d.ts +0 -116
- package/typings/languages/pt.d.ts +0 -39
- package/typings/languages/ro.d.ts +0 -229
- package/typings/languages/ru.d.ts +0 -108
- package/typings/languages/sr-Latn.d.ts +0 -98
- package/typings/languages/sv.d.ts +0 -30
- package/typings/languages/sw.d.ts +0 -1
- package/typings/languages/ta.d.ts +0 -1
- package/typings/languages/te.d.ts +0 -1
- package/typings/languages/th.d.ts +0 -1
- package/typings/languages/tr.d.ts +0 -46
- package/typings/languages/uk.d.ts +0 -117
- package/typings/languages/ur.d.ts +0 -1
- package/typings/languages/vi.d.ts +0 -116
- package/typings/languages/zh-Hans.d.ts +0 -57
- package/typings/n2words.d.ts +0 -177
package/lib/n2words.js
CHANGED
|
@@ -1,258 +1,541 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* n2words - Convert numbers to words in multiple languages
|
|
3
|
+
*
|
|
4
|
+
* This file is the main entry point for the n2words library.
|
|
5
|
+
* It exports converter functions for all supported languages.
|
|
6
|
+
*
|
|
7
|
+
* ## For Contributors
|
|
8
|
+
*
|
|
9
|
+
* When adding a new language, this file must be updated in THREE sections:
|
|
10
|
+
* 1. Language Imports - Add import statement (alphabetically sorted)
|
|
11
|
+
* 2. Language Converters - Create converter with makeConverter() (alphabetically sorted)
|
|
12
|
+
* 3. Exports - Add to export list (alphabetically sorted)
|
|
13
|
+
*
|
|
14
|
+
* Use the scaffolding tool to automate this process:
|
|
15
|
+
* npm run lang:add <language-code>
|
|
16
|
+
*
|
|
17
|
+
* ## Public API Structure
|
|
18
|
+
*
|
|
19
|
+
* Each language exports a converter function:
|
|
20
|
+
* - Name: `{LanguageName}Converter` (e.g., EnglishConverter, SpanishConverter)
|
|
21
|
+
* - Signature: `(value: NumericValue, options?: Options) => string`
|
|
22
|
+
* - Input: number, bigint, or string (numeric strings only)
|
|
23
|
+
* - Output: Words representing the number in the target language
|
|
24
|
+
*
|
|
25
|
+
* Languages without options use signature: `(value: NumericValue) => string`
|
|
26
|
+
* Languages with options define a typedef (e.g., ArabicOptions) and use: `(value: NumericValue, options?: ArabicOptions) => string`
|
|
27
|
+
*
|
|
2
28
|
* @module n2words
|
|
3
29
|
*/
|
|
4
30
|
|
|
5
|
-
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Language Imports
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
import { Arabic } from './languages/ar.js'
|
|
36
|
+
import { Azerbaijani } from './languages/az.js'
|
|
37
|
+
import { Bangla } from './languages/bn.js'
|
|
38
|
+
import { Czech } from './languages/cs.js'
|
|
39
|
+
import { Danish } from './languages/da.js'
|
|
40
|
+
import { German } from './languages/de.js'
|
|
41
|
+
import { Greek } from './languages/el.js'
|
|
42
|
+
import { English } from './languages/en.js'
|
|
43
|
+
import { Spanish } from './languages/es.js'
|
|
44
|
+
import { Persian } from './languages/fa.js'
|
|
45
|
+
import { Filipino } from './languages/fil.js'
|
|
46
|
+
import { French } from './languages/fr.js'
|
|
47
|
+
import { FrenchBelgium } from './languages/fr-BE.js'
|
|
48
|
+
import { Gujarati } from './languages/gu.js'
|
|
49
|
+
import { Hebrew } from './languages/he.js'
|
|
50
|
+
import { BiblicalHebrew } from './languages/hbo.js'
|
|
51
|
+
import { Hindi } from './languages/hi.js'
|
|
52
|
+
import { Croatian } from './languages/hr.js'
|
|
53
|
+
import { Hungarian } from './languages/hu.js'
|
|
54
|
+
import { Indonesian } from './languages/id.js'
|
|
55
|
+
import { Italian } from './languages/it.js'
|
|
56
|
+
import { Japanese } from './languages/ja.js'
|
|
57
|
+
import { Kannada } from './languages/kn.js'
|
|
58
|
+
import { Korean } from './languages/ko.js'
|
|
59
|
+
import { Lithuanian } from './languages/lt.js'
|
|
60
|
+
import { Latvian } from './languages/lv.js'
|
|
61
|
+
import { Marathi } from './languages/mr.js'
|
|
62
|
+
import { Malay } from './languages/ms.js'
|
|
63
|
+
import { Dutch } from './languages/nl.js'
|
|
64
|
+
import { NorwegianBokmal } from './languages/nb.js'
|
|
65
|
+
import { Punjabi } from './languages/pa.js'
|
|
66
|
+
import { Polish } from './languages/pl.js'
|
|
67
|
+
import { Portuguese } from './languages/pt.js'
|
|
68
|
+
import { Romanian } from './languages/ro.js'
|
|
69
|
+
import { Russian } from './languages/ru.js'
|
|
70
|
+
import { SerbianCyrillic } from './languages/sr-Cyrl.js'
|
|
71
|
+
import { SerbianLatin } from './languages/sr-Latn.js'
|
|
72
|
+
import { Swedish } from './languages/sv.js'
|
|
73
|
+
import { Swahili } from './languages/sw.js'
|
|
74
|
+
import { Tamil } from './languages/ta.js'
|
|
75
|
+
import { Telugu } from './languages/te.js'
|
|
76
|
+
import { Thai } from './languages/th.js'
|
|
77
|
+
import { Turkish } from './languages/tr.js'
|
|
78
|
+
import { Ukrainian } from './languages/uk.js'
|
|
79
|
+
import { Urdu } from './languages/ur.js'
|
|
80
|
+
import { Vietnamese } from './languages/vi.js'
|
|
81
|
+
import { SimplifiedChinese } from './languages/zh-Hans.js'
|
|
82
|
+
import { TraditionalChinese } from './languages/zh-Hant.js'
|
|
83
|
+
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Type Definitions
|
|
86
|
+
// ============================================================================
|
|
87
|
+
//
|
|
88
|
+
// This section defines TypeScript-compatible JSDoc types for:
|
|
89
|
+
// - NumericValue: The input types accepted by all converters
|
|
90
|
+
// - {Language}Options: Optional configuration for languages that support it
|
|
91
|
+
//
|
|
92
|
+
// Keep options typedefs alphabetically sorted for maintainability.
|
|
93
|
+
// ============================================================================
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Numeric value that can be converted to words.
|
|
97
|
+
* Accepts number, bigint, or numeric string representations.
|
|
98
|
+
* @typedef {number | bigint | string} NumericValue
|
|
99
|
+
*/
|
|
6
100
|
|
|
7
101
|
/**
|
|
8
102
|
* @typedef {Object} ArabicOptions
|
|
9
|
-
* @property {string} [negativeWord
|
|
10
|
-
* @property {
|
|
103
|
+
* @property {string} [negativeWord] Word for negative numbers
|
|
104
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
11
105
|
*/
|
|
12
106
|
|
|
13
107
|
/**
|
|
14
|
-
* @typedef {Object}
|
|
15
|
-
* @property {
|
|
108
|
+
* @typedef {Object} BiblicalHebrewOptions
|
|
109
|
+
* @property {string} [andWord='ו'] Conjunction character (typically 'ו' for and)
|
|
110
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
16
111
|
*/
|
|
17
112
|
|
|
18
113
|
/**
|
|
19
|
-
* @typedef {Object}
|
|
20
|
-
* @property {
|
|
21
|
-
* @property {boolean} [biblical=false] - Use biblical scale words instead of modern ones.
|
|
22
|
-
* @property {boolean} [feminine=false] - Use feminine forms for numbers.
|
|
114
|
+
* @typedef {Object} CroatianOptions
|
|
115
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
23
116
|
*/
|
|
24
117
|
|
|
25
118
|
/**
|
|
26
|
-
* @typedef {Object}
|
|
27
|
-
* @property {('
|
|
119
|
+
* @typedef {Object} CzechOptions
|
|
120
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @typedef {Object} DanishOptions
|
|
125
|
+
* @property {boolean} [ordFlag=false] Enable ordinal number conversion
|
|
28
126
|
*/
|
|
29
127
|
|
|
30
128
|
/**
|
|
31
129
|
* @typedef {Object} DutchOptions
|
|
32
|
-
* @property {boolean} [includeOptionalAnd=false]
|
|
33
|
-
* @property {boolean} [
|
|
34
|
-
* @property {boolean} [accentOne=true]
|
|
130
|
+
* @property {boolean} [includeOptionalAnd=false] Include optional "en" separator
|
|
131
|
+
* @property {boolean} [noHundredPairing=false] Disable hundred-pairing (e.g., "twelve hundred" becomes "one thousand two hundred")
|
|
132
|
+
* @property {boolean} [accentOne=true] Use accented "één" for one
|
|
35
133
|
*/
|
|
36
134
|
|
|
37
135
|
/**
|
|
38
136
|
* @typedef {Object} FrenchOptions
|
|
39
|
-
* @property {boolean} [withHyphenSeparator=false]
|
|
137
|
+
* @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds
|
|
40
138
|
*/
|
|
41
139
|
|
|
42
140
|
/**
|
|
43
|
-
* @typedef {Object}
|
|
44
|
-
* @property {boolean} [
|
|
141
|
+
* @typedef {Object} FrenchBelgiumOptions
|
|
142
|
+
* @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @typedef {Object} HebrewOptions
|
|
147
|
+
* @property {string} [andWord='ו'] Conjunction character (typically 'ו' for and)
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @typedef {Object} LatvianOptions
|
|
152
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @typedef {Object} LithuanianOptions
|
|
157
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @typedef {Object} PolishOptions
|
|
162
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
45
163
|
*/
|
|
46
164
|
|
|
47
165
|
/**
|
|
48
166
|
* @typedef {Object} RomanianOptions
|
|
49
|
-
* @property {
|
|
167
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
50
168
|
*/
|
|
51
169
|
|
|
52
170
|
/**
|
|
53
|
-
* @typedef {Object}
|
|
54
|
-
* @property {
|
|
171
|
+
* @typedef {Object} RussianOptions
|
|
172
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
55
173
|
*/
|
|
56
174
|
|
|
57
175
|
/**
|
|
58
|
-
* @typedef {Object}
|
|
59
|
-
* @property {
|
|
176
|
+
* @typedef {Object} SerbianCyrillicOptions
|
|
177
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
60
178
|
*/
|
|
61
179
|
|
|
62
180
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* @typedef {Object} N2WordsOptions
|
|
66
|
-
* @property {LanguageCode} [lang='en'] - Target language code with full autocomplete support.
|
|
67
|
-
* Supports many languages with regional variants (e.g., 'fr-BE').
|
|
68
|
-
* Falls back progressively from most-specific to least-specific (e.g., 'fr-BE' -> 'fr').
|
|
69
|
-
* Throws an error if no match is found after fallback attempts.
|
|
70
|
-
* @property {string} [negativeWord] - (Arabic only) Word for negative numbers.
|
|
71
|
-
* @property {boolean} [feminine] - (Arabic, Hebrew, Romanian, Slavic languages) Use feminine forms.
|
|
72
|
-
* @property {boolean} [formal] - (Chinese only) Use formal/financial numerals.
|
|
73
|
-
* @property {string} [and] - (Hebrew only) Conjunction character.
|
|
74
|
-
* @property {boolean} [biblical] - (Hebrew only) Use biblical scale words.
|
|
75
|
-
* @property {('o'|'a'|string)} [genderStem] - (Spanish only) Gender ending.
|
|
76
|
-
* @property {boolean} [includeOptionalAnd] - (Dutch only) Include optional "en".
|
|
77
|
-
* @property {boolean} [noHundredPairs] - (Dutch only) Disable comma before hundreds.
|
|
78
|
-
* @property {boolean} [accentOne] - (Dutch only) Use accented "één".
|
|
79
|
-
* @property {boolean} [withHyphenSeparator] - (French, Belgian French) Use hyphens.
|
|
80
|
-
* @property {boolean} [dropSpaces] - (Turkish, Azerbaijani) Remove spaces.
|
|
81
|
-
* @property {boolean} [ordFlag] - (Danish only) Enable ordinal conversion.
|
|
82
|
-
*
|
|
83
|
-
* Language-specific options are automatically validated and forwarded to converters.
|
|
84
|
-
* See individual language implementations for detailed option descriptions.
|
|
181
|
+
* @typedef {Object} SerbianLatinOptions
|
|
182
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
85
183
|
*/
|
|
86
184
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
import da from './languages/da.js'
|
|
92
|
-
import en from './languages/en.js'
|
|
93
|
-
import es from './languages/es.js'
|
|
94
|
-
import fa from './languages/fa.js'
|
|
95
|
-
import sw from './languages/sw.js'
|
|
96
|
-
import fr from './languages/fr.js'
|
|
97
|
-
import frBE from './languages/fr-BE.js'
|
|
98
|
-
import he from './languages/he.js'
|
|
99
|
-
import hr from './languages/hr.js'
|
|
100
|
-
import hu from './languages/hu.js'
|
|
101
|
-
import id from './languages/id.js'
|
|
102
|
-
import ms from './languages/ms.js'
|
|
103
|
-
import it from './languages/it.js'
|
|
104
|
-
import ja from './languages/ja.js'
|
|
105
|
-
import hi from './languages/hi.js'
|
|
106
|
-
import bn from './languages/bn.js'
|
|
107
|
-
import ko from './languages/ko.js'
|
|
108
|
-
import th from './languages/th.js'
|
|
109
|
-
import ta from './languages/ta.js'
|
|
110
|
-
import te from './languages/te.js'
|
|
111
|
-
import sv from './languages/sv.js'
|
|
112
|
-
import lt from './languages/lt.js'
|
|
113
|
-
import lv from './languages/lv.js'
|
|
114
|
-
import nl from './languages/nl.js'
|
|
115
|
-
import nb from './languages/nb.js'
|
|
116
|
-
import pl from './languages/pl.js'
|
|
117
|
-
import pt from './languages/pt.js'
|
|
118
|
-
import ro from './languages/ro.js'
|
|
119
|
-
import ru from './languages/ru.js'
|
|
120
|
-
import srLatn from './languages/sr-Latn.js'
|
|
121
|
-
import tr from './languages/tr.js'
|
|
122
|
-
import uk from './languages/uk.js'
|
|
123
|
-
import vi from './languages/vi.js'
|
|
124
|
-
import zhHans from './languages/zh-Hans.js'
|
|
125
|
-
import ur from './languages/ur.js'
|
|
126
|
-
import paGuru from './languages/pa-Guru.js'
|
|
127
|
-
import fil from './languages/fil.js'
|
|
128
|
-
import mr from './languages/mr.js'
|
|
129
|
-
import gu from './languages/gu.js'
|
|
130
|
-
import kn from './languages/kn.js'
|
|
131
|
-
import el from './languages/el.js'
|
|
185
|
+
/**
|
|
186
|
+
* @typedef {Object} SimplifiedChineseOptions
|
|
187
|
+
* @property {boolean} [formal=true] Use formal/financial numerals (壹贰叁) vs. common numerals (一二三)
|
|
188
|
+
*/
|
|
132
189
|
|
|
133
190
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* in both Node.js and browser environments (enables bundler dead-code elimination).
|
|
137
|
-
* Keys are language codes (e.g., 'en', 'fr', 'fr-BE'); values are converter functions.
|
|
138
|
-
* @type {Object<string, Function>}
|
|
191
|
+
* @typedef {Object} SpanishOptions
|
|
192
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
139
193
|
*/
|
|
140
|
-
const dict = {
|
|
141
|
-
ar,
|
|
142
|
-
az,
|
|
143
|
-
cs,
|
|
144
|
-
de,
|
|
145
|
-
da,
|
|
146
|
-
en,
|
|
147
|
-
es,
|
|
148
|
-
fa,
|
|
149
|
-
sw,
|
|
150
|
-
fr,
|
|
151
|
-
'fr-BE': frBE,
|
|
152
|
-
he,
|
|
153
|
-
hr,
|
|
154
|
-
hu,
|
|
155
|
-
id,
|
|
156
|
-
ms,
|
|
157
|
-
it,
|
|
158
|
-
ja,
|
|
159
|
-
hi,
|
|
160
|
-
bn,
|
|
161
|
-
ko,
|
|
162
|
-
th,
|
|
163
|
-
ta,
|
|
164
|
-
te,
|
|
165
|
-
sv,
|
|
166
|
-
lt,
|
|
167
|
-
lv,
|
|
168
|
-
nl,
|
|
169
|
-
nb,
|
|
170
|
-
pl,
|
|
171
|
-
pt,
|
|
172
|
-
ro,
|
|
173
|
-
ru,
|
|
174
|
-
'sr-Latn': srLatn,
|
|
175
|
-
tr,
|
|
176
|
-
uk,
|
|
177
|
-
vi,
|
|
178
|
-
'zh-Hans': zhHans,
|
|
179
|
-
ur,
|
|
180
|
-
'pa-Guru': paGuru,
|
|
181
|
-
fil,
|
|
182
|
-
mr,
|
|
183
|
-
gu,
|
|
184
|
-
kn,
|
|
185
|
-
el
|
|
186
|
-
}
|
|
187
194
|
|
|
188
195
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
*
|
|
196
|
+
* @typedef {Object} TraditionalChineseOptions
|
|
197
|
+
* @property {boolean} [formal=true] Use formal/financial numerals (壹貳參) vs. common numerals (一二三)
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @typedef {Object} TurkishOptions
|
|
202
|
+
* @property {boolean} [dropSpaces=false] Remove spaces between words if true
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @typedef {Object} UkrainianOptions
|
|
207
|
+
* @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
// ============================================================================
|
|
211
|
+
// Converter Factory
|
|
212
|
+
// ============================================================================
|
|
213
|
+
//
|
|
214
|
+
// makeConverter() is a factory function that creates converter functions from
|
|
215
|
+
// language classes. It provides a consistent functional API for all languages:
|
|
216
|
+
//
|
|
217
|
+
// const result = EnglishConverter(42) // "forty-two"
|
|
218
|
+
// const result = ArabicConverter(1, {gender: 'feminine'}) // "واحدة"
|
|
219
|
+
//
|
|
220
|
+
// This design:
|
|
221
|
+
// - Hides class instantiation details from public API
|
|
222
|
+
// - Ensures each conversion uses a fresh instance
|
|
223
|
+
// - Maintains immutability (no shared state between conversions)
|
|
224
|
+
// ============================================================================
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Creates a converter function for a language class.
|
|
195
228
|
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* - `string` (numeric string, possibly with decimal point),
|
|
199
|
-
* - `bigint` for very large integers.
|
|
200
|
-
* Decimal numbers as strings preserve precision that `number` type cannot.
|
|
201
|
-
* @param {N2WordsOptions} [options={}] Optional configuration object.
|
|
229
|
+
* This factory handles all input validation and normalization at the public API
|
|
230
|
+
* boundary, then delegates to the language class with pre-processed data.
|
|
202
231
|
*
|
|
203
|
-
* @
|
|
204
|
-
*
|
|
232
|
+
* @template {Object} [TOptions={}]
|
|
233
|
+
* @param {new (options?: TOptions) => { toWords: (isNegative: boolean, integerPart: bigint, decimalPart?: string) => string }} LanguageClass - Language class constructor
|
|
234
|
+
* @returns {(value: NumericValue, options?: TOptions) => string} Converter function
|
|
235
|
+
*/
|
|
236
|
+
function makeConverter (LanguageClass) {
|
|
237
|
+
/**
|
|
238
|
+
* @param {NumericValue} value
|
|
239
|
+
* @param {TOptions} [options]
|
|
240
|
+
* @returns {string}
|
|
241
|
+
*/
|
|
242
|
+
return function convertToWords (value, options) {
|
|
243
|
+
if (options !== undefined && !isPlainObject(options)) {
|
|
244
|
+
throw new TypeError('options must be a plain object if provided')
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
|
|
248
|
+
return new LanguageClass(options).toWords(isNegative, integerPart, decimalPart)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ============================================================================
|
|
253
|
+
// Input Parsing Utilities
|
|
254
|
+
// ============================================================================
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @typedef {Object} ParsedNumericValue
|
|
258
|
+
* @property {boolean} isNegative - Whether the value is negative
|
|
259
|
+
* @property {bigint} integerPart - The absolute integer part
|
|
260
|
+
* @property {string} [decimalPart] - The decimal digits (without the point)
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Parses and validates a numeric value into its components.
|
|
265
|
+
* Handles number, string, and bigint inputs uniformly.
|
|
205
266
|
*
|
|
206
|
-
* @
|
|
207
|
-
* @
|
|
267
|
+
* @param {NumericValue} value The value to parse
|
|
268
|
+
* @returns {ParsedNumericValue} The parsed components
|
|
269
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
270
|
+
* @throws {Error} If value is not a valid number format
|
|
271
|
+
*/
|
|
272
|
+
function parseNumericValue (value) {
|
|
273
|
+
const type = typeof value
|
|
274
|
+
|
|
275
|
+
// BigInt: simplest case - no decimals, no scientific notation
|
|
276
|
+
if (type === 'bigint') {
|
|
277
|
+
return value < 0n
|
|
278
|
+
? { isNegative: true, integerPart: -value }
|
|
279
|
+
: { isNegative: false, integerPart: value }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Reject invalid types early
|
|
283
|
+
if (type !== 'number' && type !== 'string') {
|
|
284
|
+
throw new TypeError(
|
|
285
|
+
`Invalid value type: expected number, string, or bigint, received ${type}`
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Convert to normalized string
|
|
290
|
+
const str = type === 'number'
|
|
291
|
+
? numberToString(value)
|
|
292
|
+
: stringToNormalizedForm(value)
|
|
293
|
+
|
|
294
|
+
return parseNumericString(str)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Converts a JavaScript number to a decimal string.
|
|
299
|
+
* Handles special cases: Infinity, NaN, and scientific notation.
|
|
208
300
|
*
|
|
209
|
-
* @
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
|
|
213
|
-
|
|
301
|
+
* @param {number} value The number to convert
|
|
302
|
+
* @returns {string} Decimal string representation
|
|
303
|
+
* @throws {Error} If value is not finite
|
|
304
|
+
*/
|
|
305
|
+
function numberToString (value) {
|
|
306
|
+
if (!Number.isFinite(value)) {
|
|
307
|
+
throw new Error('Number must be finite (NaN and Infinity are not supported)')
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const str = value.toString()
|
|
311
|
+
|
|
312
|
+
// Expand scientific notation (used for values >= 1e21 or < 1e-6)
|
|
313
|
+
if (str.includes('e') || str.includes('E')) {
|
|
314
|
+
return expandScientificNotation(str)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return str
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Validates and normalizes a string numeric input.
|
|
214
322
|
*
|
|
215
|
-
* @
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* convertToWords(1, { lang: 'cs', feminine: true }) // Czech feminine form
|
|
323
|
+
* @param {string} value The string to validate
|
|
324
|
+
* @returns {string} Trimmed and validated string
|
|
325
|
+
* @throws {Error} If string is empty or not a valid number format
|
|
219
326
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
327
|
+
function stringToNormalizedForm (value) {
|
|
328
|
+
const trimmed = value.trim()
|
|
329
|
+
|
|
330
|
+
if (trimmed.length === 0) {
|
|
331
|
+
throw new Error(`Invalid number format: "${value}"`)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Validate by attempting conversion (handles edge cases like "1e21", "-.5", etc.)
|
|
335
|
+
if (Number.isNaN(Number(trimmed))) {
|
|
336
|
+
throw new Error(`Invalid number format: "${value}"`)
|
|
223
337
|
}
|
|
224
338
|
|
|
225
|
-
|
|
226
|
-
|
|
339
|
+
// Expand scientific notation if present
|
|
340
|
+
if (trimmed.includes('e') || trimmed.includes('E')) {
|
|
341
|
+
return expandScientificNotation(trimmed)
|
|
227
342
|
}
|
|
228
343
|
|
|
229
|
-
|
|
344
|
+
return trimmed
|
|
345
|
+
}
|
|
230
346
|
|
|
231
|
-
|
|
232
|
-
|
|
347
|
+
/**
|
|
348
|
+
* Parses a normalized numeric string into its components.
|
|
349
|
+
*
|
|
350
|
+
* @param {string} str A normalized decimal string (no scientific notation)
|
|
351
|
+
* @returns {ParsedNumericValue} The parsed components
|
|
352
|
+
*/
|
|
353
|
+
function parseNumericString (str) {
|
|
354
|
+
// Extract sign
|
|
355
|
+
const isNegative = str[0] === '-'
|
|
356
|
+
if (isNegative) {
|
|
357
|
+
str = str.slice(1)
|
|
233
358
|
}
|
|
234
359
|
|
|
235
|
-
|
|
236
|
-
|
|
360
|
+
// Split into integer and decimal parts
|
|
361
|
+
const dotIndex = str.indexOf('.')
|
|
362
|
+
if (dotIndex === -1) {
|
|
363
|
+
return { isNegative, integerPart: BigInt(str) }
|
|
237
364
|
}
|
|
238
365
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
366
|
+
const integerStr = str.slice(0, dotIndex) || '0'
|
|
367
|
+
const decimalPart = str.slice(dotIndex + 1)
|
|
368
|
+
|
|
369
|
+
return { isNegative, integerPart: BigInt(integerStr), decimalPart }
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Expands scientific notation to decimal form.
|
|
374
|
+
* JavaScript uses scientific notation for values >= 1e21 or < 1e-6.
|
|
375
|
+
*
|
|
376
|
+
* @param {string} str String possibly in scientific notation (e.g., "1e+21")
|
|
377
|
+
* @returns {string} Decimal form (e.g., "1000000000000000000000")
|
|
378
|
+
*/
|
|
379
|
+
function expandScientificNotation (str) {
|
|
380
|
+
const [mantissa, expStr] = str.toLowerCase().split('e')
|
|
381
|
+
const exp = parseInt(expStr, 10)
|
|
382
|
+
|
|
383
|
+
// Extract digits and determine original decimal position
|
|
384
|
+
const dotIndex = mantissa.indexOf('.')
|
|
385
|
+
const digits = dotIndex === -1
|
|
386
|
+
? mantissa
|
|
387
|
+
: mantissa.slice(0, dotIndex) + mantissa.slice(dotIndex + 1)
|
|
388
|
+
const integerLength = dotIndex === -1 ? mantissa.length : dotIndex
|
|
389
|
+
|
|
390
|
+
// Calculate new decimal position after applying exponent
|
|
391
|
+
const newDotPosition = integerLength + exp
|
|
392
|
+
|
|
393
|
+
if (newDotPosition >= digits.length) {
|
|
394
|
+
// Pure integer: pad with trailing zeros
|
|
395
|
+
return digits + '0'.repeat(newDotPosition - digits.length)
|
|
242
396
|
}
|
|
243
397
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
let lastDashIndex = languageCode.lastIndexOf('-')
|
|
248
|
-
while (lastDashIndex > 0) {
|
|
249
|
-
const candidateLanguageCode = languageCode.slice(0, lastDashIndex)
|
|
250
|
-
languageConverter = dict[candidateLanguageCode]
|
|
251
|
-
if (languageConverter !== undefined) {
|
|
252
|
-
return languageConverter(value, options)
|
|
253
|
-
}
|
|
254
|
-
lastDashIndex = candidateLanguageCode.lastIndexOf('-')
|
|
398
|
+
if (newDotPosition <= 0) {
|
|
399
|
+
// Pure decimal: pad with leading zeros after decimal point
|
|
400
|
+
return '0.' + '0'.repeat(-newDotPosition) + digits
|
|
255
401
|
}
|
|
256
402
|
|
|
257
|
-
|
|
403
|
+
// Mixed: insert decimal point at new position
|
|
404
|
+
return digits.slice(0, newDotPosition) + '.' + digits.slice(newDotPosition)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Checks if a value is a plain object (not null, array, or other object types).
|
|
409
|
+
*
|
|
410
|
+
* @param {*} value Value to check
|
|
411
|
+
* @returns {boolean} True if value is a plain object
|
|
412
|
+
*/
|
|
413
|
+
function isPlainObject (value) {
|
|
414
|
+
if (value === null || typeof value !== 'object') return false
|
|
415
|
+
const proto = Object.getPrototypeOf(value)
|
|
416
|
+
return proto === Object.prototype || proto === null
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// ============================================================================
|
|
420
|
+
// Language Converters
|
|
421
|
+
// ============================================================================
|
|
422
|
+
//
|
|
423
|
+
// Each converter is created using makeConverter() with explicit type annotations.
|
|
424
|
+
//
|
|
425
|
+
// Pattern for languages WITHOUT options:
|
|
426
|
+
// const LanguageConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Language))
|
|
427
|
+
//
|
|
428
|
+
// Pattern for languages WITH options:
|
|
429
|
+
// const LanguageConverter = /** @type {(value: NumericValue, options?: LanguageOptions) => string} */ (makeConverter(Language))
|
|
430
|
+
//
|
|
431
|
+
// IMPORTANT: Keep converters alphabetically sorted by converter name.
|
|
432
|
+
// ============================================================================
|
|
433
|
+
|
|
434
|
+
const ArabicConverter = /** @type {(value: NumericValue, options?: ArabicOptions) => string} */ (makeConverter(Arabic))
|
|
435
|
+
const AzerbaijaniConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Azerbaijani))
|
|
436
|
+
const BanglaConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Bangla))
|
|
437
|
+
const BiblicalHebrewConverter = /** @type {(value: NumericValue, options?: BiblicalHebrewOptions) => string} */ (makeConverter(BiblicalHebrew))
|
|
438
|
+
const CroatianConverter = /** @type {(value: NumericValue, options?: CroatianOptions) => string} */ (makeConverter(Croatian))
|
|
439
|
+
const CzechConverter = /** @type {(value: NumericValue, options?: CzechOptions) => string} */ (makeConverter(Czech))
|
|
440
|
+
const DanishConverter = /** @type {(value: NumericValue, options?: DanishOptions) => string} */ (makeConverter(Danish))
|
|
441
|
+
const DutchConverter = /** @type {(value: NumericValue, options?: DutchOptions) => string} */ (makeConverter(Dutch))
|
|
442
|
+
const EnglishConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(English))
|
|
443
|
+
const FilipinoConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Filipino))
|
|
444
|
+
const FrenchConverter = /** @type {(value: NumericValue, options?: FrenchOptions) => string} */ (makeConverter(French))
|
|
445
|
+
const FrenchBelgiumConverter = /** @type {(value: NumericValue, options?: FrenchBelgiumOptions) => string} */ (makeConverter(FrenchBelgium))
|
|
446
|
+
const GermanConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(German))
|
|
447
|
+
const GreekConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Greek))
|
|
448
|
+
const GujaratiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Gujarati))
|
|
449
|
+
const HebrewConverter = /** @type {(value: NumericValue, options?: HebrewOptions) => string} */ (makeConverter(Hebrew))
|
|
450
|
+
const HindiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Hindi))
|
|
451
|
+
const HungarianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Hungarian))
|
|
452
|
+
const IndonesianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Indonesian))
|
|
453
|
+
const ItalianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Italian))
|
|
454
|
+
const JapaneseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Japanese))
|
|
455
|
+
const KannadaConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Kannada))
|
|
456
|
+
const KoreanConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Korean))
|
|
457
|
+
const LatvianConverter = /** @type {(value: NumericValue, options?: LatvianOptions) => string} */ (makeConverter(Latvian))
|
|
458
|
+
const LithuanianConverter = /** @type {(value: NumericValue, options?: LithuanianOptions) => string} */ (makeConverter(Lithuanian))
|
|
459
|
+
const MalayConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Malay))
|
|
460
|
+
const MarathiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Marathi))
|
|
461
|
+
const NorwegianBokmalConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(NorwegianBokmal))
|
|
462
|
+
const PersianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Persian))
|
|
463
|
+
const PolishConverter = /** @type {(value: NumericValue, options?: PolishOptions) => string} */ (makeConverter(Polish))
|
|
464
|
+
const PortugueseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Portuguese))
|
|
465
|
+
const PunjabiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Punjabi))
|
|
466
|
+
const RomanianConverter = /** @type {(value: NumericValue, options?: RomanianOptions) => string} */ (makeConverter(Romanian))
|
|
467
|
+
const RussianConverter = /** @type {(value: NumericValue, options?: RussianOptions) => string} */ (makeConverter(Russian))
|
|
468
|
+
const SerbianCyrillicConverter = /** @type {(value: NumericValue, options?: SerbianCyrillicOptions) => string} */ (makeConverter(SerbianCyrillic))
|
|
469
|
+
const SerbianLatinConverter = /** @type {(value: NumericValue, options?: SerbianLatinOptions) => string} */ (makeConverter(SerbianLatin))
|
|
470
|
+
const SimplifiedChineseConverter = /** @type {(value: NumericValue, options?: SimplifiedChineseOptions) => string} */ (makeConverter(SimplifiedChinese))
|
|
471
|
+
const SpanishConverter = /** @type {(value: NumericValue, options?: SpanishOptions) => string} */ (makeConverter(Spanish))
|
|
472
|
+
const SwahiliConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Swahili))
|
|
473
|
+
const SwedishConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Swedish))
|
|
474
|
+
const TamilConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Tamil))
|
|
475
|
+
const TeluguConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Telugu))
|
|
476
|
+
const ThaiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Thai))
|
|
477
|
+
const TraditionalChineseConverter = /** @type {(value: NumericValue, options?: TraditionalChineseOptions) => string} */ (makeConverter(TraditionalChinese))
|
|
478
|
+
const TurkishConverter = /** @type {(value: NumericValue, options?: TurkishOptions) => string} */ (makeConverter(Turkish))
|
|
479
|
+
const UkrainianConverter = /** @type {(value: NumericValue, options?: UkrainianOptions) => string} */ (makeConverter(Ukrainian))
|
|
480
|
+
const UrduConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Urdu))
|
|
481
|
+
const VietnameseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Vietnamese))
|
|
482
|
+
|
|
483
|
+
// ============================================================================
|
|
484
|
+
// Exports
|
|
485
|
+
// ============================================================================
|
|
486
|
+
//
|
|
487
|
+
// All converter functions are exported for public use.
|
|
488
|
+
//
|
|
489
|
+
// IMPORTANT: Keep exports alphabetically sorted for maintainability.
|
|
490
|
+
// ============================================================================
|
|
491
|
+
|
|
492
|
+
export {
|
|
493
|
+
ArabicConverter,
|
|
494
|
+
AzerbaijaniConverter,
|
|
495
|
+
BanglaConverter,
|
|
496
|
+
BiblicalHebrewConverter,
|
|
497
|
+
CroatianConverter,
|
|
498
|
+
CzechConverter,
|
|
499
|
+
DanishConverter,
|
|
500
|
+
DutchConverter,
|
|
501
|
+
EnglishConverter,
|
|
502
|
+
FilipinoConverter,
|
|
503
|
+
FrenchConverter,
|
|
504
|
+
FrenchBelgiumConverter,
|
|
505
|
+
GermanConverter,
|
|
506
|
+
GreekConverter,
|
|
507
|
+
GujaratiConverter,
|
|
508
|
+
HebrewConverter,
|
|
509
|
+
HindiConverter,
|
|
510
|
+
HungarianConverter,
|
|
511
|
+
IndonesianConverter,
|
|
512
|
+
ItalianConverter,
|
|
513
|
+
JapaneseConverter,
|
|
514
|
+
KannadaConverter,
|
|
515
|
+
KoreanConverter,
|
|
516
|
+
LatvianConverter,
|
|
517
|
+
LithuanianConverter,
|
|
518
|
+
MalayConverter,
|
|
519
|
+
MarathiConverter,
|
|
520
|
+
NorwegianBokmalConverter,
|
|
521
|
+
PersianConverter,
|
|
522
|
+
PolishConverter,
|
|
523
|
+
PortugueseConverter,
|
|
524
|
+
PunjabiConverter,
|
|
525
|
+
RomanianConverter,
|
|
526
|
+
RussianConverter,
|
|
527
|
+
SerbianCyrillicConverter,
|
|
528
|
+
SerbianLatinConverter,
|
|
529
|
+
SimplifiedChineseConverter,
|
|
530
|
+
SpanishConverter,
|
|
531
|
+
SwahiliConverter,
|
|
532
|
+
SwedishConverter,
|
|
533
|
+
TamilConverter,
|
|
534
|
+
TeluguConverter,
|
|
535
|
+
ThaiConverter,
|
|
536
|
+
TraditionalChineseConverter,
|
|
537
|
+
TurkishConverter,
|
|
538
|
+
UkrainianConverter,
|
|
539
|
+
UrduConverter,
|
|
540
|
+
VietnameseConverter
|
|
258
541
|
}
|