n2words 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +86 -188
  3. package/dist/languages/am-Latn.js +3 -0
  4. package/dist/languages/am-Latn.js.map +1 -0
  5. package/dist/languages/am.js +3 -0
  6. package/dist/languages/am.js.map +1 -0
  7. package/dist/languages/ar.js +3 -0
  8. package/dist/languages/ar.js.map +1 -0
  9. package/dist/languages/az.js +3 -0
  10. package/dist/languages/az.js.map +1 -0
  11. package/dist/languages/bn.js +3 -0
  12. package/dist/languages/bn.js.map +1 -0
  13. package/dist/languages/cs.js +3 -0
  14. package/dist/languages/cs.js.map +1 -0
  15. package/dist/languages/da.js +3 -0
  16. package/dist/languages/da.js.map +1 -0
  17. package/dist/languages/de.js +3 -0
  18. package/dist/languages/de.js.map +1 -0
  19. package/dist/languages/el.js +3 -0
  20. package/dist/languages/el.js.map +1 -0
  21. package/dist/languages/en.js +3 -0
  22. package/dist/languages/en.js.map +1 -0
  23. package/dist/languages/es.js +3 -0
  24. package/dist/languages/es.js.map +1 -0
  25. package/dist/languages/fa.js +3 -0
  26. package/dist/languages/fa.js.map +1 -0
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -0
  30. package/dist/languages/fil.js.map +1 -0
  31. package/dist/languages/fr-BE.js +3 -0
  32. package/dist/languages/fr-BE.js.map +1 -0
  33. package/dist/languages/fr.js +3 -0
  34. package/dist/languages/fr.js.map +1 -0
  35. package/dist/languages/gu.js +3 -0
  36. package/dist/languages/gu.js.map +1 -0
  37. package/dist/languages/ha.js +3 -0
  38. package/dist/languages/ha.js.map +1 -0
  39. package/dist/languages/hbo.js +3 -0
  40. package/dist/languages/hbo.js.map +1 -0
  41. package/dist/languages/he.js +3 -0
  42. package/dist/languages/he.js.map +1 -0
  43. package/dist/languages/hi.js +3 -0
  44. package/dist/languages/hi.js.map +1 -0
  45. package/dist/languages/hr.js +3 -0
  46. package/dist/languages/hr.js.map +1 -0
  47. package/dist/languages/hu.js +3 -0
  48. package/dist/languages/hu.js.map +1 -0
  49. package/dist/languages/id.js +3 -0
  50. package/dist/languages/id.js.map +1 -0
  51. package/dist/languages/it.js +3 -0
  52. package/dist/languages/it.js.map +1 -0
  53. package/dist/languages/ja.js +3 -0
  54. package/dist/languages/ja.js.map +1 -0
  55. package/dist/languages/kn.js +3 -0
  56. package/dist/languages/kn.js.map +1 -0
  57. package/dist/languages/ko.js +3 -0
  58. package/dist/languages/ko.js.map +1 -0
  59. package/dist/languages/lt.js +3 -0
  60. package/dist/languages/lt.js.map +1 -0
  61. package/dist/languages/lv.js +3 -0
  62. package/dist/languages/lv.js.map +1 -0
  63. package/dist/languages/mr.js +3 -0
  64. package/dist/languages/mr.js.map +1 -0
  65. package/dist/languages/ms.js +3 -0
  66. package/dist/languages/ms.js.map +1 -0
  67. package/dist/languages/nb.js +3 -0
  68. package/dist/languages/nb.js.map +1 -0
  69. package/dist/languages/nl.js +3 -0
  70. package/dist/languages/nl.js.map +1 -0
  71. package/dist/languages/pa.js +3 -0
  72. package/dist/languages/pa.js.map +1 -0
  73. package/dist/languages/pl.js +3 -0
  74. package/dist/languages/pl.js.map +1 -0
  75. package/dist/languages/pt.js +3 -0
  76. package/dist/languages/pt.js.map +1 -0
  77. package/dist/languages/ro.js +3 -0
  78. package/dist/languages/ro.js.map +1 -0
  79. package/dist/languages/ru.js +3 -0
  80. package/dist/languages/ru.js.map +1 -0
  81. package/dist/languages/sr-Cyrl.js +3 -0
  82. package/dist/languages/sr-Cyrl.js.map +1 -0
  83. package/dist/languages/sr-Latn.js +3 -0
  84. package/dist/languages/sr-Latn.js.map +1 -0
  85. package/dist/languages/sv.js +3 -0
  86. package/dist/languages/sv.js.map +1 -0
  87. package/dist/languages/sw.js +3 -0
  88. package/dist/languages/sw.js.map +1 -0
  89. package/dist/languages/ta.js +3 -0
  90. package/dist/languages/ta.js.map +1 -0
  91. package/dist/languages/te.js +3 -0
  92. package/dist/languages/te.js.map +1 -0
  93. package/dist/languages/th.js +3 -0
  94. package/dist/languages/th.js.map +1 -0
  95. package/dist/languages/tr.js +3 -0
  96. package/dist/languages/tr.js.map +1 -0
  97. package/dist/languages/uk.js +3 -0
  98. package/dist/languages/uk.js.map +1 -0
  99. package/dist/languages/ur.js +3 -0
  100. package/dist/languages/ur.js.map +1 -0
  101. package/dist/languages/vi.js +3 -0
  102. package/dist/languages/vi.js.map +1 -0
  103. package/dist/languages/zh-Hans.js +3 -0
  104. package/dist/languages/zh-Hans.js.map +1 -0
  105. package/dist/languages/zh-Hant.js +3 -0
  106. package/dist/languages/zh-Hant.js.map +1 -0
  107. package/dist/n2words.js +2 -2
  108. package/dist/n2words.js.map +1 -1
  109. package/lib/languages/am-Latn.d.ts +7 -0
  110. package/lib/languages/am-Latn.js +164 -0
  111. package/lib/languages/am.d.ts +7 -0
  112. package/lib/languages/am.js +164 -0
  113. package/lib/languages/ar.d.ts +14 -27
  114. package/lib/languages/ar.js +175 -129
  115. package/lib/languages/az.d.ts +4 -9
  116. package/lib/languages/az.js +171 -37
  117. package/lib/languages/bn.d.ts +4 -8
  118. package/lib/languages/bn.js +138 -124
  119. package/lib/languages/cs.d.ts +15 -85
  120. package/lib/languages/cs.js +310 -114
  121. package/lib/languages/da.d.ts +11 -12
  122. package/lib/languages/da.js +276 -101
  123. package/lib/languages/de.d.ts +14 -11
  124. package/lib/languages/de.js +317 -86
  125. package/lib/languages/el.d.ts +11 -11
  126. package/lib/languages/el.js +231 -78
  127. package/lib/languages/en.d.ts +14 -13
  128. package/lib/languages/en.js +242 -72
  129. package/lib/languages/es.d.ts +18 -12
  130. package/lib/languages/es.js +317 -103
  131. package/lib/languages/fa.d.ts +4 -44
  132. package/lib/languages/fa.js +112 -122
  133. package/lib/languages/fi.d.ts +14 -0
  134. package/lib/languages/fi.js +245 -0
  135. package/lib/languages/fil.d.ts +4 -13
  136. package/lib/languages/fil.js +207 -106
  137. package/lib/languages/fr-BE.d.ts +8 -8
  138. package/lib/languages/fr-BE.js +294 -19
  139. package/lib/languages/fr.d.ts +18 -12
  140. package/lib/languages/fr.js +352 -89
  141. package/lib/languages/gu.d.ts +4 -8
  142. package/lib/languages/gu.js +130 -125
  143. package/lib/languages/ha.d.ts +7 -0
  144. package/lib/languages/ha.js +230 -0
  145. package/lib/languages/hbo.d.ts +10 -110
  146. package/lib/languages/hbo.js +263 -214
  147. package/lib/languages/he.d.ts +10 -77
  148. package/lib/languages/he.js +242 -172
  149. package/lib/languages/hi.d.ts +4 -8
  150. package/lib/languages/hi.js +138 -124
  151. package/lib/languages/hr.d.ts +8 -77
  152. package/lib/languages/hr.js +194 -89
  153. package/lib/languages/hu.d.ts +4 -19
  154. package/lib/languages/hu.js +198 -119
  155. package/lib/languages/id.d.ts +4 -34
  156. package/lib/languages/id.js +171 -129
  157. package/lib/languages/it.d.ts +16 -34
  158. package/lib/languages/it.js +339 -94
  159. package/lib/languages/ja.d.ts +14 -14
  160. package/lib/languages/ja.js +233 -111
  161. package/lib/languages/kn.d.ts +4 -8
  162. package/lib/languages/kn.js +130 -35
  163. package/lib/languages/ko.d.ts +11 -11
  164. package/lib/languages/ko.js +257 -49
  165. package/lib/languages/lt.d.ts +15 -67
  166. package/lib/languages/lt.js +296 -122
  167. package/lib/languages/lv.d.ts +15 -67
  168. package/lib/languages/lv.js +297 -106
  169. package/lib/languages/mr.d.ts +4 -8
  170. package/lib/languages/mr.js +130 -125
  171. package/lib/languages/ms.d.ts +4 -28
  172. package/lib/languages/ms.js +171 -116
  173. package/lib/languages/nb.d.ts +11 -9
  174. package/lib/languages/nb.js +282 -87
  175. package/lib/languages/nl.d.ts +23 -13
  176. package/lib/languages/nl.js +317 -133
  177. package/lib/languages/pa.d.ts +4 -8
  178. package/lib/languages/pa.js +156 -124
  179. package/lib/languages/pl.d.ts +19 -77
  180. package/lib/languages/pl.js +307 -87
  181. package/lib/languages/pt.d.ts +14 -26
  182. package/lib/languages/pt.js +286 -92
  183. package/lib/languages/ro.d.ts +15 -155
  184. package/lib/languages/ro.js +219 -235
  185. package/lib/languages/ru.d.ts +8 -82
  186. package/lib/languages/ru.js +222 -78
  187. package/lib/languages/sr-Cyrl.d.ts +8 -77
  188. package/lib/languages/sr-Cyrl.js +191 -89
  189. package/lib/languages/sr-Latn.d.ts +8 -77
  190. package/lib/languages/sr-Latn.js +191 -89
  191. package/lib/languages/sv.d.ts +11 -11
  192. package/lib/languages/sv.js +288 -74
  193. package/lib/languages/sw.d.ts +4 -36
  194. package/lib/languages/sw.js +133 -106
  195. package/lib/languages/ta.d.ts +4 -17
  196. package/lib/languages/ta.js +129 -201
  197. package/lib/languages/te.d.ts +4 -19
  198. package/lib/languages/te.js +141 -196
  199. package/lib/languages/th.d.ts +4 -14
  200. package/lib/languages/th.js +135 -91
  201. package/lib/languages/tr.d.ts +15 -9
  202. package/lib/languages/tr.js +256 -49
  203. package/lib/languages/uk.d.ts +8 -82
  204. package/lib/languages/uk.js +200 -78
  205. package/lib/languages/ur.d.ts +4 -8
  206. package/lib/languages/ur.js +156 -124
  207. package/lib/languages/vi.d.ts +14 -69
  208. package/lib/languages/vi.js +294 -125
  209. package/lib/languages/zh-Hans.d.ts +8 -18
  210. package/lib/languages/zh-Hans.js +163 -92
  211. package/lib/languages/zh-Hant.d.ts +8 -18
  212. package/lib/languages/zh-Hant.js +181 -90
  213. package/lib/n2words.d.ts +53 -209
  214. package/lib/n2words.js +111 -530
  215. package/lib/utils/is-plain-object.d.ts +13 -0
  216. package/lib/utils/is-plain-object.js +17 -0
  217. package/lib/utils/parse-numeric.d.ts +17 -0
  218. package/lib/utils/parse-numeric.js +108 -0
  219. package/lib/utils/validate-options.d.ts +8 -0
  220. package/lib/utils/validate-options.js +16 -0
  221. package/package.json +26 -14
  222. package/dist/ArabicConverter.js +0 -3
  223. package/dist/ArabicConverter.js.map +0 -1
  224. package/dist/AzerbaijaniConverter.js +0 -3
  225. package/dist/AzerbaijaniConverter.js.map +0 -1
  226. package/dist/BanglaConverter.js +0 -3
  227. package/dist/BanglaConverter.js.map +0 -1
  228. package/dist/BiblicalHebrewConverter.js +0 -3
  229. package/dist/BiblicalHebrewConverter.js.map +0 -1
  230. package/dist/CroatianConverter.js +0 -3
  231. package/dist/CroatianConverter.js.map +0 -1
  232. package/dist/CzechConverter.js +0 -3
  233. package/dist/CzechConverter.js.map +0 -1
  234. package/dist/DanishConverter.js +0 -3
  235. package/dist/DanishConverter.js.map +0 -1
  236. package/dist/DutchConverter.js +0 -3
  237. package/dist/DutchConverter.js.map +0 -1
  238. package/dist/EnglishConverter.js +0 -3
  239. package/dist/EnglishConverter.js.map +0 -1
  240. package/dist/FilipinoConverter.js +0 -3
  241. package/dist/FilipinoConverter.js.map +0 -1
  242. package/dist/FrenchBelgiumConverter.js +0 -3
  243. package/dist/FrenchBelgiumConverter.js.map +0 -1
  244. package/dist/FrenchConverter.js +0 -3
  245. package/dist/FrenchConverter.js.map +0 -1
  246. package/dist/GermanConverter.js +0 -3
  247. package/dist/GermanConverter.js.map +0 -1
  248. package/dist/GreekConverter.js +0 -3
  249. package/dist/GreekConverter.js.map +0 -1
  250. package/dist/GujaratiConverter.js +0 -3
  251. package/dist/GujaratiConverter.js.map +0 -1
  252. package/dist/HebrewConverter.js +0 -3
  253. package/dist/HebrewConverter.js.map +0 -1
  254. package/dist/HindiConverter.js +0 -3
  255. package/dist/HindiConverter.js.map +0 -1
  256. package/dist/HungarianConverter.js +0 -3
  257. package/dist/HungarianConverter.js.map +0 -1
  258. package/dist/IndonesianConverter.js +0 -3
  259. package/dist/IndonesianConverter.js.map +0 -1
  260. package/dist/ItalianConverter.js +0 -3
  261. package/dist/ItalianConverter.js.map +0 -1
  262. package/dist/JapaneseConverter.js +0 -3
  263. package/dist/JapaneseConverter.js.map +0 -1
  264. package/dist/KannadaConverter.js +0 -3
  265. package/dist/KannadaConverter.js.map +0 -1
  266. package/dist/KoreanConverter.js +0 -3
  267. package/dist/KoreanConverter.js.map +0 -1
  268. package/dist/LatvianConverter.js +0 -3
  269. package/dist/LatvianConverter.js.map +0 -1
  270. package/dist/LithuanianConverter.js +0 -3
  271. package/dist/LithuanianConverter.js.map +0 -1
  272. package/dist/MalayConverter.js +0 -3
  273. package/dist/MalayConverter.js.map +0 -1
  274. package/dist/MarathiConverter.js +0 -3
  275. package/dist/MarathiConverter.js.map +0 -1
  276. package/dist/NorwegianBokmalConverter.js +0 -3
  277. package/dist/NorwegianBokmalConverter.js.map +0 -1
  278. package/dist/PersianConverter.js +0 -3
  279. package/dist/PersianConverter.js.map +0 -1
  280. package/dist/PolishConverter.js +0 -3
  281. package/dist/PolishConverter.js.map +0 -1
  282. package/dist/PortugueseConverter.js +0 -3
  283. package/dist/PortugueseConverter.js.map +0 -1
  284. package/dist/PunjabiConverter.js +0 -3
  285. package/dist/PunjabiConverter.js.map +0 -1
  286. package/dist/RomanianConverter.js +0 -3
  287. package/dist/RomanianConverter.js.map +0 -1
  288. package/dist/RussianConverter.js +0 -3
  289. package/dist/RussianConverter.js.map +0 -1
  290. package/dist/SerbianCyrillicConverter.js +0 -3
  291. package/dist/SerbianCyrillicConverter.js.map +0 -1
  292. package/dist/SerbianLatinConverter.js +0 -3
  293. package/dist/SerbianLatinConverter.js.map +0 -1
  294. package/dist/SimplifiedChineseConverter.js +0 -3
  295. package/dist/SimplifiedChineseConverter.js.map +0 -1
  296. package/dist/SpanishConverter.js +0 -3
  297. package/dist/SpanishConverter.js.map +0 -1
  298. package/dist/SwahiliConverter.js +0 -3
  299. package/dist/SwahiliConverter.js.map +0 -1
  300. package/dist/SwedishConverter.js +0 -3
  301. package/dist/SwedishConverter.js.map +0 -1
  302. package/dist/TamilConverter.js +0 -3
  303. package/dist/TamilConverter.js.map +0 -1
  304. package/dist/TeluguConverter.js +0 -3
  305. package/dist/TeluguConverter.js.map +0 -1
  306. package/dist/ThaiConverter.js +0 -3
  307. package/dist/ThaiConverter.js.map +0 -1
  308. package/dist/TraditionalChineseConverter.js +0 -3
  309. package/dist/TraditionalChineseConverter.js.map +0 -1
  310. package/dist/TurkishConverter.js +0 -3
  311. package/dist/TurkishConverter.js.map +0 -1
  312. package/dist/UkrainianConverter.js +0 -3
  313. package/dist/UkrainianConverter.js.map +0 -1
  314. package/dist/UrduConverter.js +0 -3
  315. package/dist/UrduConverter.js.map +0 -1
  316. package/dist/VietnameseConverter.js +0 -3
  317. package/dist/VietnameseConverter.js.map +0 -1
  318. package/lib/classes/abstract-language.d.ts +0 -178
  319. package/lib/classes/abstract-language.js +0 -268
  320. package/lib/classes/greedy-scale-language.d.ts +0 -109
  321. package/lib/classes/greedy-scale-language.js +0 -201
  322. package/lib/classes/slavic-language.d.ts +0 -148
  323. package/lib/classes/slavic-language.js +0 -281
  324. package/lib/classes/south-asian-language.d.ts +0 -70
  325. package/lib/classes/south-asian-language.js +0 -154
  326. package/lib/classes/turkic-language.d.ts +0 -26
  327. package/lib/classes/turkic-language.js +0 -59
@@ -1,55 +1,263 @@
1
- import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
1
+ /**
2
+ * Korean language converter - Functional Implementation
3
+ *
4
+ * A performance-optimized number-to-words converter using precomputed lookup tables.
5
+ *
6
+ * Key features:
7
+ * - Myriad-based (만) grouping - 4 digits
8
+ * - Implicit '일' (one) omission before scale words
9
+ * - Space separation after 만+ scales
10
+ * - Hangul numerals
11
+ */
12
+
13
+ import { parseNumericValue } from '../utils/parse-numeric.js'
14
+
15
+ // ============================================================================
16
+ // Vocabulary (module-level constants)
17
+ // ============================================================================
18
+
19
+ const ONES = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구']
20
+
21
+ const TEN = '십'
22
+ const HUNDRED = '백'
23
+ const THOUSAND = '천'
24
+
25
+ const ZERO = '영'
26
+ const NEGATIVE = '마이너스'
27
+ const DECIMAL_SEP = '점'
28
+
29
+ // Myriad scale words (powers of 10,000)
30
+ // 만 (10^4), 억 (10^8), 조 (10^12), 경 (10^16), etc.
31
+ const SCALES = ['만', '억', '조', '경', '해', '자', '양']
32
+
33
+ // ============================================================================
34
+ // Precomputed Lookup Tables (built once at module load)
35
+ // ============================================================================
36
+
37
+ /**
38
+ * Builds segment word for 0-9999 (4-digit myriad segment).
39
+ * Korean omits "일" before 십, 백, 천.
40
+ */
41
+ function buildSegment (n) {
42
+ if (n === 0) return ''
43
+
44
+ const ones = n % 10
45
+ const tens = Math.floor(n / 10) % 10
46
+ const hundreds = Math.floor(n / 100) % 10
47
+ const thousands = Math.floor(n / 1000)
48
+
49
+ let result = ''
50
+
51
+ // Thousands
52
+ if (thousands > 0) {
53
+ if (thousands === 1) {
54
+ result += THOUSAND
55
+ } else {
56
+ result += ONES[thousands] + THOUSAND
57
+ }
58
+ }
59
+
60
+ // Hundreds
61
+ if (hundreds > 0) {
62
+ if (hundreds === 1) {
63
+ result += HUNDRED
64
+ } else {
65
+ result += ONES[hundreds] + HUNDRED
66
+ }
67
+ }
68
+
69
+ // Tens
70
+ if (tens > 0) {
71
+ if (tens === 1) {
72
+ result += TEN
73
+ } else {
74
+ result += ONES[tens] + TEN
75
+ }
76
+ }
77
+
78
+ // Ones
79
+ if (ones > 0) {
80
+ result += ONES[ones]
81
+ }
82
+
83
+ return result
84
+ }
85
+
86
+ // Precompute all 10000 segment words (0-9999) for myriad grouping
87
+ const SEGMENTS = new Array(10000)
88
+
89
+ for (let i = 0; i < 10000; i++) {
90
+ SEGMENTS[i] = buildSegment(i)
91
+ }
92
+
93
+ // ============================================================================
94
+ // Conversion Functions
95
+ // ============================================================================
96
+
97
+ /**
98
+ * Converts a non-negative integer to Korean words.
99
+ *
100
+ * @param {bigint} n - Non-negative integer to convert
101
+ * @returns {string} Korean words
102
+ */
103
+ function integerToWords (n) {
104
+ if (n === 0n) return ZERO
105
+
106
+ // Fast path: numbers < 10000 (direct lookup)
107
+ if (n < 10000n) {
108
+ return SEGMENTS[Number(n)]
109
+ }
110
+
111
+ // For numbers >= 10000, use myriad decomposition
112
+ return buildLargeNumberWords(n)
113
+ }
114
+
115
+ /**
116
+ * Builds words for numbers >= 10000.
117
+ * Uses myriad (만) grouping - 4 digits per segment.
118
+ *
119
+ * @param {bigint} n - Number >= 10000
120
+ * @returns {string} Korean words
121
+ */
122
+ function buildLargeNumberWords (n) {
123
+ const numStr = n.toString()
124
+ const len = numStr.length
125
+
126
+ // Build segments of 4 digits from right to left
127
+ const segments = []
128
+ const segmentSize = 4
129
+
130
+ const remainderLen = len % segmentSize
131
+ let pos = 0
132
+ if (remainderLen > 0) {
133
+ segments.push(Number(numStr.slice(0, remainderLen)))
134
+ pos = remainderLen
135
+ }
136
+ while (pos < len) {
137
+ segments.push(Number(numStr.slice(pos, pos + segmentSize)))
138
+ pos += segmentSize
139
+ }
140
+
141
+ // Convert segments to words
142
+ const parts = []
143
+ let scaleIndex = segments.length - 1
144
+
145
+ for (let i = 0; i < segments.length; i++) {
146
+ const segment = segments[i]
147
+
148
+ if (segment !== 0) {
149
+ if (scaleIndex === 0) {
150
+ // Units segment (no scale word)
151
+ parts.push({ word: SEGMENTS[segment], isScale: false })
152
+ } else {
153
+ // Segment with scale word
154
+ const scaleWord = SCALES[scaleIndex - 1]
155
+
156
+ // Korean omits segment when it's 1 before scale words
157
+ if (segment === 1) {
158
+ parts.push({ word: scaleWord, isScale: true })
159
+ } else {
160
+ parts.push({ word: SEGMENTS[segment], isScale: false })
161
+ parts.push({ word: scaleWord, isScale: true })
162
+ }
163
+ }
164
+ }
165
+
166
+ scaleIndex--
167
+ }
168
+
169
+ // Join with Korean spacing rules
170
+ return joinKoreanParts(parts)
171
+ }
172
+
173
+ /**
174
+ * Joins parts with Korean spacing rules.
175
+ * - Concatenate without spaces within segments
176
+ * - Space after scale words before next number
177
+ *
178
+ * @param {Array} parts - Parts with isScale metadata
179
+ * @returns {string} Joined string
180
+ */
181
+ function joinKoreanParts (parts) {
182
+ if (parts.length === 0) return ZERO
183
+ if (parts.length === 1) return parts[0].word
184
+
185
+ const result = []
186
+
187
+ for (let i = 0; i < parts.length; i++) {
188
+ const part = parts[i]
189
+ const prevPart = i > 0 ? parts[i - 1] : null
190
+
191
+ // Add space after scale words before next number
192
+ if (prevPart && prevPart.isScale && !part.isScale) {
193
+ result.push(' ')
194
+ }
195
+
196
+ result.push(part.word)
197
+ }
198
+
199
+ return result.join('')
200
+ }
2
201
 
3
202
  /**
4
- * Korean language converter.
203
+ * Converts decimal digits to Korean words.
5
204
  *
6
- * Supports:
7
- * - Hangul numerals (일, 이, 삼, etc.)
8
- * - Grouping by 만 (10,000) system
9
- * - Implicit '일' (one) omission before multipliers
205
+ * @param {string} decimalPart - Decimal digits (without the point)
206
+ * @returns {string} Korean words for decimal part (space-separated)
10
207
  */
11
- export class Korean extends GreedyScaleLanguage {
12
- negativeWord = '마이너스'
13
- decimalSeparatorWord = '점'
14
- zeroWord = '영'
15
-
16
- scaleWords = [
17
- [10_000_000_000_000_000_000_000_000_000n, '양'],
18
- [1_000_000_000_000_000_000_000_000n, '자'],
19
- [100_000_000_000_000_000_000n, '해'],
20
- [10_000_000_000_000_000n, '경'],
21
- [1_000_000_000_000n, '조'],
22
- [100_000_000n, '억'],
23
- [10_000n, '만'],
24
- [1000n, '천'],
25
- [100n, '백'],
26
- [10n, '십'],
27
- [9n, '구'],
28
- [8n, '팔'],
29
- [7n, '칠'],
30
- [6n, '육'],
31
- [5n, '오'],
32
- [4n, '사'],
33
- [3n, '삼'],
34
- [2n, '이'],
35
- [1n, '일'],
36
- [0n, '영']
37
- ]
38
-
39
- /** Combines two word-sets according to Korean grammar rules. */
40
- combineWordSets (preceding, following) {
41
- const precedingWord = Object.keys(preceding)[0]
42
- const followingWord = Object.keys(following)[0]
43
- const precedingValue = Object.values(preceding)[0] // BigInt
44
- const followingValue = Object.values(following)[0] // BigInt
45
-
46
- // Implicit "일": omit 1 before multipliers up to 만 (10,000)
47
- if (precedingValue === 1n && followingValue <= 10_000n) return following
48
- // Concatenate (no space) for small numbers less than 만
49
- if (precedingValue < 10_000n && precedingValue > followingValue) return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
50
- // Space-separate for large numbers (>= 만) when adding
51
- if (precedingValue >= 10_000n && precedingValue > followingValue) return { [`${precedingWord} ${followingWord}`]: precedingValue + followingValue }
52
- // Multiply for all scale combinations
53
- return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
208
+ function decimalPartToWords (decimalPart) {
209
+ const parts = []
210
+
211
+ // Handle leading zeros
212
+ let i = 0
213
+ while (i < decimalPart.length && decimalPart[i] === '0') {
214
+ parts.push(ZERO)
215
+ i++
54
216
  }
217
+
218
+ // Convert remainder as a single number
219
+ const remainder = decimalPart.slice(i)
220
+ if (remainder) {
221
+ parts.push(integerToWords(BigInt(remainder)))
222
+ }
223
+
224
+ return parts.join(' ')
55
225
  }
226
+
227
+ /**
228
+ * Converts a numeric value to Korean words.
229
+ *
230
+ * @param {number | string | bigint} value - The numeric value to convert
231
+ * @returns {string} The number in Korean words
232
+ * @throws {TypeError} If value is not a valid numeric type
233
+ * @throws {Error} If value is not a valid number format
234
+ *
235
+ * @example
236
+ * toWords(21) // '이십일'
237
+ * toWords(10000) // '만'
238
+ * toWords(1000000) // '백만'
239
+ */
240
+ function toWords (value) {
241
+ const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
242
+
243
+ const parts = []
244
+
245
+ if (isNegative) {
246
+ parts.push(NEGATIVE)
247
+ }
248
+
249
+ parts.push(integerToWords(integerPart))
250
+
251
+ if (decimalPart) {
252
+ parts.push(DECIMAL_SEP)
253
+ parts.push(decimalPartToWords(decimalPart))
254
+ }
255
+
256
+ return parts.join(' ')
257
+ }
258
+
259
+ // ============================================================================
260
+ // Public API
261
+ // ============================================================================
262
+
263
+ export { toWords }
@@ -1,70 +1,18 @@
1
1
  /**
2
- * Lithuanian language converter.
2
+ * Converts a numeric value to Lithuanian words.
3
3
  *
4
- * Supports:
5
- * - Three-form pluralization (one/few/many)
6
- * - Gender agreement (vienas/viena, du/dvi)
7
- * - Baltic declension patterns
4
+ * @param {number | string | bigint} value - The numeric value to convert
5
+ * @param {Object} [options] - Conversion options
6
+ * @param {string} [options.gender='masculine'] - Gender for numbers < 1000
7
+ * @returns {string} The number in Lithuanian 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(42) // 'keturiasdešimt du'
13
+ * toWords(1, { gender: 'feminine' }) // 'viena'
14
+ * toWords(1000000) // 'vienas milijonas'
8
15
  */
9
- export class Lithuanian extends SlavicLanguage {
10
- onesWords: {
11
- 1: string;
12
- 2: string;
13
- 3: string;
14
- 4: string;
15
- 5: string;
16
- 6: string;
17
- 7: string;
18
- 8: string;
19
- 9: string;
20
- };
21
- onesFeminineWords: {
22
- 1: string;
23
- 2: string;
24
- 3: string;
25
- 4: string;
26
- 5: string;
27
- 6: string;
28
- 7: string;
29
- 8: string;
30
- 9: string;
31
- };
32
- teensWords: {
33
- 0: string;
34
- 1: string;
35
- 2: string;
36
- 3: string;
37
- 4: string;
38
- 5: string;
39
- 6: string;
40
- 7: string;
41
- 8: string;
42
- 9: string;
43
- };
44
- twentiesWords: {
45
- 2: string;
46
- 3: string;
47
- 4: string;
48
- 5: string;
49
- 6: string;
50
- 7: string;
51
- 8: string;
52
- 9: string;
53
- };
54
- hundredsWords: string[];
55
- pluralForms: {
56
- 1: string[];
57
- 2: string[];
58
- 3: string[];
59
- 4: string[];
60
- 5: string[];
61
- 6: string[];
62
- 7: string[];
63
- 8: string[];
64
- 9: string[];
65
- 10: string[];
66
- };
67
- pluralize(n: any, forms: any): any;
68
- integerToWords(integerPart: any): string;
69
- }
70
- import { SlavicLanguage } from '../classes/slavic-language.js';
16
+ export function toWords(value: number | string | bigint, options?: {
17
+ gender?: string | undefined;
18
+ }): string;