n2words 1.24.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/README.md +183 -156
- package/dist/languages/am-Latn.js +3 -0
- package/dist/languages/am-Latn.js.map +1 -0
- package/dist/languages/am.js +3 -0
- package/dist/languages/am.js.map +1 -0
- package/dist/languages/ar.js +3 -2
- package/dist/languages/ar.js.map +1 -1
- package/dist/languages/az.js +3 -2
- package/dist/languages/az.js.map +1 -1
- package/dist/languages/bn.js +3 -2
- package/dist/languages/bn.js.map +1 -1
- package/dist/languages/cs.js +3 -2
- package/dist/languages/cs.js.map +1 -1
- package/dist/languages/da.js +3 -2
- package/dist/languages/da.js.map +1 -1
- package/dist/languages/de.js +3 -2
- package/dist/languages/de.js.map +1 -1
- package/dist/languages/el.js +3 -2
- package/dist/languages/el.js.map +1 -1
- package/dist/languages/en.js +3 -2
- package/dist/languages/en.js.map +1 -1
- package/dist/languages/es.js +3 -2
- package/dist/languages/es.js.map +1 -1
- package/dist/languages/fa.js +3 -2
- package/dist/languages/fa.js.map +1 -1
- package/dist/languages/fi.js +3 -0
- package/dist/languages/fi.js.map +1 -0
- package/dist/languages/fil.js +3 -2
- package/dist/languages/fil.js.map +1 -1
- package/dist/languages/fr-BE.js +3 -2
- package/dist/languages/fr-BE.js.map +1 -1
- package/dist/languages/fr.js +3 -2
- package/dist/languages/fr.js.map +1 -1
- package/dist/languages/gu.js +3 -2
- package/dist/languages/gu.js.map +1 -1
- package/dist/languages/ha.js +3 -0
- package/dist/languages/ha.js.map +1 -0
- package/dist/languages/hbo.js +3 -0
- package/dist/languages/hbo.js.map +1 -0
- package/dist/languages/he.js +3 -2
- package/dist/languages/he.js.map +1 -1
- package/dist/languages/hi.js +3 -2
- package/dist/languages/hi.js.map +1 -1
- package/dist/languages/hr.js +3 -2
- package/dist/languages/hr.js.map +1 -1
- package/dist/languages/hu.js +3 -2
- package/dist/languages/hu.js.map +1 -1
- package/dist/languages/id.js +3 -2
- package/dist/languages/id.js.map +1 -1
- package/dist/languages/it.js +3 -2
- package/dist/languages/it.js.map +1 -1
- package/dist/languages/ja.js +3 -2
- package/dist/languages/ja.js.map +1 -1
- package/dist/languages/kn.js +3 -2
- package/dist/languages/kn.js.map +1 -1
- package/dist/languages/ko.js +3 -2
- package/dist/languages/ko.js.map +1 -1
- package/dist/languages/lt.js +3 -2
- package/dist/languages/lt.js.map +1 -1
- package/dist/languages/lv.js +3 -2
- package/dist/languages/lv.js.map +1 -1
- package/dist/languages/mr.js +3 -2
- package/dist/languages/mr.js.map +1 -1
- package/dist/languages/ms.js +3 -2
- package/dist/languages/ms.js.map +1 -1
- package/dist/languages/nb.js +3 -2
- package/dist/languages/nb.js.map +1 -1
- package/dist/languages/nl.js +3 -2
- package/dist/languages/nl.js.map +1 -1
- package/dist/languages/pa.js +3 -0
- package/dist/languages/pa.js.map +1 -0
- package/dist/languages/pl.js +3 -2
- package/dist/languages/pl.js.map +1 -1
- package/dist/languages/pt.js +3 -2
- package/dist/languages/pt.js.map +1 -1
- package/dist/languages/ro.js +3 -2
- package/dist/languages/ro.js.map +1 -1
- package/dist/languages/ru.js +3 -2
- package/dist/languages/ru.js.map +1 -1
- package/dist/languages/sr-Cyrl.js +3 -0
- package/dist/languages/sr-Cyrl.js.map +1 -0
- package/dist/languages/sr-Latn.js +3 -2
- package/dist/languages/sr-Latn.js.map +1 -1
- package/dist/languages/sv.js +3 -2
- package/dist/languages/sv.js.map +1 -1
- package/dist/languages/sw.js +3 -2
- package/dist/languages/sw.js.map +1 -1
- package/dist/languages/ta.js +3 -2
- package/dist/languages/ta.js.map +1 -1
- package/dist/languages/te.js +3 -2
- package/dist/languages/te.js.map +1 -1
- package/dist/languages/th.js +3 -2
- package/dist/languages/th.js.map +1 -1
- package/dist/languages/tr.js +3 -2
- package/dist/languages/tr.js.map +1 -1
- package/dist/languages/uk.js +3 -2
- package/dist/languages/uk.js.map +1 -1
- package/dist/languages/ur.js +3 -2
- package/dist/languages/ur.js.map +1 -1
- package/dist/languages/vi.js +3 -2
- package/dist/languages/vi.js.map +1 -1
- package/dist/languages/zh-Hans.js +3 -2
- package/dist/languages/zh-Hans.js.map +1 -1
- package/dist/languages/zh-Hant.js +3 -0
- package/dist/languages/zh-Hant.js.map +1 -0
- package/dist/n2words.js +3 -2
- package/dist/n2words.js.map +1 -1
- package/lib/languages/am-Latn.d.ts +7 -0
- package/lib/languages/am-Latn.js +164 -0
- package/lib/languages/am.d.ts +7 -0
- package/lib/languages/am.js +164 -0
- package/lib/languages/ar.d.ts +17 -0
- package/lib/languages/ar.js +171 -209
- package/lib/languages/az.d.ts +7 -0
- package/lib/languages/az.js +167 -49
- package/lib/languages/bn.d.ts +7 -0
- package/lib/languages/bn.js +142 -123
- package/lib/languages/cs.d.ts +18 -0
- package/lib/languages/cs.js +303 -176
- package/lib/languages/da.d.ts +14 -0
- package/lib/languages/da.js +267 -139
- package/lib/languages/de.d.ts +17 -0
- package/lib/languages/de.js +310 -113
- package/lib/languages/el.d.ts +14 -0
- package/lib/languages/el.js +225 -98
- package/lib/languages/en.d.ts +17 -0
- package/lib/languages/en.js +235 -102
- package/lib/languages/es.d.ts +21 -0
- package/lib/languages/es.js +307 -125
- package/lib/languages/fa.d.ts +7 -0
- package/lib/languages/fa.js +115 -108
- package/lib/languages/fi.d.ts +14 -0
- package/lib/languages/fi.js +245 -0
- package/lib/languages/fil.d.ts +7 -0
- package/lib/languages/fil.js +199 -139
- package/lib/languages/fr-BE.d.ts +11 -0
- package/lib/languages/fr-BE.js +287 -48
- package/lib/languages/fr.d.ts +21 -0
- package/lib/languages/fr.js +343 -119
- package/lib/languages/gu.d.ts +7 -0
- package/lib/languages/gu.js +125 -144
- package/lib/languages/ha.d.ts +7 -0
- package/lib/languages/ha.js +230 -0
- package/lib/languages/hbo.d.ts +13 -0
- package/lib/languages/hbo.js +300 -0
- package/lib/languages/he.d.ts +13 -0
- package/lib/languages/he.js +230 -283
- package/lib/languages/hi.d.ts +7 -0
- package/lib/languages/hi.js +142 -123
- package/lib/languages/hr.d.ts +11 -0
- package/lib/languages/hr.js +190 -129
- package/lib/languages/hu.d.ts +7 -0
- package/lib/languages/hu.js +194 -133
- package/lib/languages/id.d.ts +7 -0
- package/lib/languages/id.js +167 -140
- package/lib/languages/it.d.ts +19 -0
- package/lib/languages/it.js +337 -108
- package/lib/languages/ja.d.ts +17 -0
- package/lib/languages/ja.js +224 -155
- package/lib/languages/kn.d.ts +7 -0
- package/lib/languages/kn.js +128 -62
- package/lib/languages/ko.d.ts +14 -0
- package/lib/languages/ko.js +250 -70
- package/lib/languages/lt.d.ts +18 -0
- package/lib/languages/lt.js +287 -148
- package/lib/languages/lv.d.ts +18 -0
- package/lib/languages/lv.js +291 -123
- package/lib/languages/mr.d.ts +7 -0
- package/lib/languages/mr.js +125 -144
- package/lib/languages/ms.d.ts +7 -0
- package/lib/languages/ms.js +171 -112
- package/lib/languages/nb.d.ts +14 -0
- package/lib/languages/nb.js +275 -100
- package/lib/languages/nl.d.ts +26 -0
- package/lib/languages/nl.js +307 -174
- package/lib/languages/pa.d.ts +7 -0
- package/lib/languages/pa.js +163 -0
- package/lib/languages/pl.d.ts +22 -0
- package/lib/languages/pl.js +299 -158
- package/lib/languages/pt.d.ts +17 -0
- package/lib/languages/pt.js +279 -120
- package/lib/languages/ro.d.ts +18 -0
- package/lib/languages/ro.js +214 -337
- package/lib/languages/ru.d.ts +11 -0
- package/lib/languages/ru.js +219 -95
- package/lib/languages/sr-Cyrl.d.ts +11 -0
- package/lib/languages/sr-Cyrl.js +215 -0
- package/lib/languages/sr-Latn.d.ts +11 -0
- package/lib/languages/sr-Latn.js +190 -132
- package/lib/languages/sv.d.ts +14 -0
- package/lib/languages/sv.js +280 -103
- package/lib/languages/sw.d.ts +7 -0
- package/lib/languages/sw.js +135 -103
- package/lib/languages/ta.d.ts +7 -0
- package/lib/languages/ta.js +133 -205
- package/lib/languages/te.d.ts +7 -0
- package/lib/languages/te.js +148 -213
- package/lib/languages/th.d.ts +7 -0
- package/lib/languages/th.js +139 -101
- package/lib/languages/tr.d.ts +18 -0
- package/lib/languages/tr.js +246 -66
- package/lib/languages/uk.d.ts +11 -0
- package/lib/languages/uk.js +197 -101
- package/lib/languages/ur.d.ts +7 -0
- package/lib/languages/ur.js +160 -123
- package/lib/languages/vi.d.ts +17 -0
- package/lib/languages/vi.js +287 -164
- package/lib/languages/zh-Hans.d.ts +11 -0
- package/lib/languages/zh-Hans.js +159 -142
- package/lib/languages/zh-Hant.d.ts +11 -0
- package/lib/languages/zh-Hant.js +202 -0
- package/lib/n2words.d.ts +53 -0
- package/lib/n2words.js +91 -227
- package/lib/utils/is-plain-object.d.ts +13 -0
- package/lib/utils/is-plain-object.js +17 -0
- package/lib/utils/parse-numeric.d.ts +17 -0
- package/lib/utils/parse-numeric.js +108 -0
- package/lib/utils/validate-options.d.ts +8 -0
- package/lib/utils/validate-options.js +16 -0
- package/package.json +118 -67
- package/dist/languages/pa-Guru.js +0 -2
- package/dist/languages/pa-Guru.js.map +0 -1
- package/lib/classes/abstract-language.js +0 -261
- package/lib/classes/greedy-scale-language.js +0 -195
- package/lib/classes/slavic-language.js +0 -251
- package/lib/classes/south-asian-language.js +0 -161
- package/lib/classes/turkic-language.js +0 -63
- package/lib/languages/pa-Guru.js +0 -126
- 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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Turkish words.
|
|
3
|
+
*
|
|
4
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
5
|
+
* @param {Object} [options] - Conversion options
|
|
6
|
+
* @param {boolean} [options.dropSpaces=false] - Remove spaces for compound form
|
|
7
|
+
* @returns {string} The number in Turkish 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
|
+
* toWords(21) // 'yirmi bir'
|
|
13
|
+
* toWords(21, { dropSpaces: true }) // 'yirmibir'
|
|
14
|
+
* toWords(1000) // 'bin'
|
|
15
|
+
*/
|
|
16
|
+
export function toWords(value: number | string | bigint, options?: {
|
|
17
|
+
dropSpaces?: boolean | undefined;
|
|
18
|
+
}): string;
|
package/lib/languages/tr.js
CHANGED
|
@@ -1,83 +1,263 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Turkish language converter - Functional Implementation
|
|
3
|
+
*
|
|
4
|
+
* A performance-optimized number-to-words converter using precomputed lookup tables.
|
|
5
|
+
*
|
|
6
|
+
* Key features:
|
|
7
|
+
* - Omits 'bir' (one) before hundreds and thousands
|
|
8
|
+
* - Optional dropSpaces for compound form
|
|
9
|
+
* - Short scale naming
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { parseNumericValue } from '../utils/parse-numeric.js'
|
|
13
|
+
import { validateOptions } from '../utils/validate-options.js'
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Vocabulary (module-level constants)
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
const ONES = ['', 'bir', 'iki', 'üç', 'dört', 'beş', 'altı', 'yedi', 'sekiz', 'dokuz']
|
|
20
|
+
|
|
21
|
+
const TEENS = ['on', 'on bir', 'on iki', 'on üç', 'on dört', 'on beş', 'on altı', 'on yedi', 'on sekiz', 'on dokuz']
|
|
22
|
+
const TENS = ['', '', 'yirmi', 'otuz', 'kırk', 'elli', 'altmış', 'yetmiş', 'seksen', 'doksan']
|
|
23
|
+
|
|
24
|
+
const HUNDRED = 'yüz'
|
|
25
|
+
const THOUSAND = 'bin'
|
|
26
|
+
|
|
27
|
+
const ZERO = 'sıfır'
|
|
28
|
+
const NEGATIVE = 'eksi'
|
|
29
|
+
const DECIMAL_SEP = 'virgül'
|
|
30
|
+
|
|
31
|
+
// Short scale
|
|
32
|
+
const SCALES = ['milyon', 'milyar', 'trilyon', 'katrilyon', 'kentilyon']
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Precomputed Lookup Tables (built once at module load)
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Builds segment word for 0-999.
|
|
40
|
+
* Omits "bir" before "yüz" (hundred).
|
|
41
|
+
*/
|
|
42
|
+
function buildSegment (n, separator = ' ') {
|
|
43
|
+
if (n === 0) return ''
|
|
44
|
+
|
|
45
|
+
const ones = n % 10
|
|
46
|
+
const tens = Math.floor(n / 10) % 10
|
|
47
|
+
const hundreds = Math.floor(n / 100)
|
|
48
|
+
|
|
49
|
+
const parts = []
|
|
50
|
+
|
|
51
|
+
// Hundreds - omit "bir" before yüz
|
|
52
|
+
if (hundreds > 0) {
|
|
53
|
+
if (hundreds === 1) {
|
|
54
|
+
parts.push(HUNDRED)
|
|
55
|
+
} else {
|
|
56
|
+
parts.push(ONES[hundreds] + separator + HUNDRED)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Tens and ones
|
|
61
|
+
const tensOnes = n % 100
|
|
62
|
+
|
|
63
|
+
if (tensOnes === 0) {
|
|
64
|
+
// Just hundreds
|
|
65
|
+
} else if (tensOnes < 10) {
|
|
66
|
+
parts.push(ONES[ones])
|
|
67
|
+
} else if (tensOnes < 20) {
|
|
68
|
+
parts.push(TEENS[ones].replace(' ', separator))
|
|
69
|
+
} else if (ones === 0) {
|
|
70
|
+
parts.push(TENS[tens])
|
|
71
|
+
} else {
|
|
72
|
+
parts.push(TENS[tens] + separator + ONES[ones])
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return parts.join(separator)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Precompute all 1000 segment words (0-999) with space separator
|
|
79
|
+
const SEGMENTS = new Array(1000)
|
|
80
|
+
const SEGMENTS_NO_SPACE = new Array(1000)
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < 1000; i++) {
|
|
83
|
+
SEGMENTS[i] = buildSegment(i, ' ')
|
|
84
|
+
SEGMENTS_NO_SPACE[i] = buildSegment(i, '')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Conversion Functions
|
|
89
|
+
// ============================================================================
|
|
2
90
|
|
|
3
91
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
92
|
+
* Converts a non-negative integer to Turkish words.
|
|
93
|
+
*
|
|
94
|
+
* @param {bigint} n - Non-negative integer to convert
|
|
95
|
+
* @param {Object} options - Conversion options
|
|
96
|
+
* @returns {string} Turkish words
|
|
6
97
|
*/
|
|
98
|
+
function integerToWords (n, options = {}) {
|
|
99
|
+
if (n === 0n) return ZERO
|
|
100
|
+
|
|
101
|
+
const sep = options.dropSpaces ? '' : ' '
|
|
102
|
+
const segments = options.dropSpaces ? SEGMENTS_NO_SPACE : SEGMENTS
|
|
103
|
+
|
|
104
|
+
// Fast path: numbers < 1000 (direct lookup)
|
|
105
|
+
if (n < 1000n) {
|
|
106
|
+
return segments[Number(n)]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fast path: numbers < 1,000,000 (thousands)
|
|
110
|
+
if (n < 1_000_000n) {
|
|
111
|
+
const thousands = Number(n / 1000n)
|
|
112
|
+
const remainder = Number(n % 1000n)
|
|
113
|
+
|
|
114
|
+
// Omit "bir" before bin (thousand)
|
|
115
|
+
let result
|
|
116
|
+
if (thousands === 1) {
|
|
117
|
+
result = THOUSAND
|
|
118
|
+
} else {
|
|
119
|
+
result = segments[thousands] + sep + THOUSAND
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (remainder > 0) {
|
|
123
|
+
result += sep + segments[remainder]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return result
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// For numbers >= 1,000,000, use scale decomposition
|
|
130
|
+
return buildLargeNumberWords(n, options)
|
|
131
|
+
}
|
|
7
132
|
|
|
8
133
|
/**
|
|
9
|
-
*
|
|
134
|
+
* Builds words for numbers >= 1,000,000.
|
|
10
135
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - Optional word spacing (dropSpaces option)
|
|
15
|
-
* - Supports 'ş', 'ç', 'ğ', 'ı', 'ü', 'ö' characters
|
|
136
|
+
* @param {bigint} n - Number >= 1,000,000
|
|
137
|
+
* @param {Object} options - Conversion options
|
|
138
|
+
* @returns {string} Turkish words
|
|
16
139
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
140
|
+
function buildLargeNumberWords (n, options) {
|
|
141
|
+
const sep = options.dropSpaces ? '' : ' '
|
|
142
|
+
const segmentsArr = options.dropSpaces ? SEGMENTS_NO_SPACE : SEGMENTS
|
|
143
|
+
|
|
144
|
+
const numStr = n.toString()
|
|
145
|
+
const len = numStr.length
|
|
146
|
+
|
|
147
|
+
// Build segments of 3 digits from right to left
|
|
148
|
+
const segments = []
|
|
149
|
+
const segmentSize = 3
|
|
150
|
+
|
|
151
|
+
const remainderLen = len % segmentSize
|
|
152
|
+
let pos = 0
|
|
153
|
+
if (remainderLen > 0) {
|
|
154
|
+
segments.push(Number(numStr.slice(0, remainderLen)))
|
|
155
|
+
pos = remainderLen
|
|
156
|
+
}
|
|
157
|
+
while (pos < len) {
|
|
158
|
+
segments.push(Number(numStr.slice(pos, pos + segmentSize)))
|
|
159
|
+
pos += segmentSize
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Convert segments to words
|
|
163
|
+
const parts = []
|
|
164
|
+
let scaleIndex = segments.length - 1
|
|
165
|
+
|
|
166
|
+
for (let i = 0; i < segments.length; i++) {
|
|
167
|
+
const segment = segments[i]
|
|
168
|
+
|
|
169
|
+
if (segment !== 0) {
|
|
170
|
+
const segmentWord = segmentsArr[segment]
|
|
171
|
+
|
|
172
|
+
if (scaleIndex === 0) {
|
|
173
|
+
// Units segment
|
|
174
|
+
parts.push(segmentWord)
|
|
175
|
+
} else if (scaleIndex === 1) {
|
|
176
|
+
// Thousands - omit "bir" before bin
|
|
177
|
+
if (segment === 1) {
|
|
178
|
+
parts.push(THOUSAND)
|
|
179
|
+
} else {
|
|
180
|
+
parts.push(segmentWord + sep + THOUSAND)
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
// Millions+ - "bir" is kept before scale words
|
|
184
|
+
const scaleWord = SCALES[scaleIndex - 2]
|
|
185
|
+
parts.push(segmentWord + sep + scaleWord)
|
|
186
|
+
}
|
|
63
187
|
}
|
|
188
|
+
|
|
189
|
+
scaleIndex--
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return parts.join(sep)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Converts decimal digits to Turkish words.
|
|
197
|
+
*
|
|
198
|
+
* @param {string} decimalPart - Decimal digits (without the point)
|
|
199
|
+
* @param {Object} options - Conversion options
|
|
200
|
+
* @returns {string} Turkish words for decimal part
|
|
201
|
+
*/
|
|
202
|
+
function decimalPartToWords (decimalPart, options) {
|
|
203
|
+
const sep = options.dropSpaces ? '' : ' '
|
|
204
|
+
let result = ''
|
|
205
|
+
|
|
206
|
+
// Handle leading zeros
|
|
207
|
+
let i = 0
|
|
208
|
+
while (i < decimalPart.length && decimalPart[i] === '0') {
|
|
209
|
+
if (result) result += sep
|
|
210
|
+
result += ZERO
|
|
211
|
+
i++
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Convert remainder as a single number
|
|
215
|
+
const remainder = decimalPart.slice(i)
|
|
216
|
+
if (remainder) {
|
|
217
|
+
if (result) result += sep
|
|
218
|
+
result += integerToWords(BigInt(remainder), options)
|
|
64
219
|
}
|
|
220
|
+
|
|
221
|
+
return result
|
|
65
222
|
}
|
|
66
223
|
|
|
67
224
|
/**
|
|
68
|
-
* Converts a
|
|
225
|
+
* Converts a numeric value to Turkish words.
|
|
69
226
|
*
|
|
70
|
-
* @param {number|string|bigint} value The
|
|
71
|
-
* @param {Object} [options] Conversion options
|
|
72
|
-
* @param {boolean} [options.dropSpaces=false] Remove spaces
|
|
73
|
-
* @returns {string} The number
|
|
74
|
-
* @throws {TypeError} If value is
|
|
75
|
-
* @throws {Error} If value is
|
|
227
|
+
* @param {number | string | bigint} value - The numeric value to convert
|
|
228
|
+
* @param {Object} [options] - Conversion options
|
|
229
|
+
* @param {boolean} [options.dropSpaces=false] - Remove spaces for compound form
|
|
230
|
+
* @returns {string} The number in Turkish words
|
|
231
|
+
* @throws {TypeError} If value is not a valid numeric type
|
|
232
|
+
* @throws {Error} If value is not a valid number format
|
|
76
233
|
*
|
|
77
234
|
* @example
|
|
78
|
-
*
|
|
79
|
-
*
|
|
235
|
+
* toWords(21) // 'yirmi bir'
|
|
236
|
+
* toWords(21, { dropSpaces: true }) // 'yirmibir'
|
|
237
|
+
* toWords(1000) // 'bin'
|
|
80
238
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
239
|
+
function toWords (value, options) {
|
|
240
|
+
options = validateOptions(options)
|
|
241
|
+
const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
|
|
242
|
+
|
|
243
|
+
const sep = options.dropSpaces ? '' : ' '
|
|
244
|
+
let result = ''
|
|
245
|
+
|
|
246
|
+
if (isNegative) {
|
|
247
|
+
result = NEGATIVE + sep
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
result += integerToWords(integerPart, options)
|
|
251
|
+
|
|
252
|
+
if (decimalPart) {
|
|
253
|
+
result += sep + DECIMAL_SEP + sep + decimalPartToWords(decimalPart, options)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return result
|
|
83
257
|
}
|
|
258
|
+
|
|
259
|
+
// ============================================================================
|
|
260
|
+
// Public API
|
|
261
|
+
// ============================================================================
|
|
262
|
+
|
|
263
|
+
export { toWords }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a numeric value to Ukrainian words.
|
|
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 Ukrainian words
|
|
8
|
+
*/
|
|
9
|
+
export function toWords(value: number | string | bigint, options?: {
|
|
10
|
+
gender?: "masculine" | "feminine" | undefined;
|
|
11
|
+
}): string;
|