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.
Files changed (349) hide show
  1. package/README.md +285 -156
  2. package/dist/ArabicConverter.js +3 -0
  3. package/dist/ArabicConverter.js.map +1 -0
  4. package/dist/AzerbaijaniConverter.js +3 -0
  5. package/dist/AzerbaijaniConverter.js.map +1 -0
  6. package/dist/BanglaConverter.js +3 -0
  7. package/dist/BanglaConverter.js.map +1 -0
  8. package/dist/BiblicalHebrewConverter.js +3 -0
  9. package/dist/BiblicalHebrewConverter.js.map +1 -0
  10. package/dist/CroatianConverter.js +3 -0
  11. package/dist/CroatianConverter.js.map +1 -0
  12. package/dist/CzechConverter.js +3 -0
  13. package/dist/CzechConverter.js.map +1 -0
  14. package/dist/DanishConverter.js +3 -0
  15. package/dist/DanishConverter.js.map +1 -0
  16. package/dist/DutchConverter.js +3 -0
  17. package/dist/DutchConverter.js.map +1 -0
  18. package/dist/EnglishConverter.js +3 -0
  19. package/dist/EnglishConverter.js.map +1 -0
  20. package/dist/FilipinoConverter.js +3 -0
  21. package/dist/FilipinoConverter.js.map +1 -0
  22. package/dist/FrenchBelgiumConverter.js +3 -0
  23. package/dist/FrenchBelgiumConverter.js.map +1 -0
  24. package/dist/FrenchConverter.js +3 -0
  25. package/dist/FrenchConverter.js.map +1 -0
  26. package/dist/GermanConverter.js +3 -0
  27. package/dist/GermanConverter.js.map +1 -0
  28. package/dist/GreekConverter.js +3 -0
  29. package/dist/GreekConverter.js.map +1 -0
  30. package/dist/GujaratiConverter.js +3 -0
  31. package/dist/GujaratiConverter.js.map +1 -0
  32. package/dist/HebrewConverter.js +3 -0
  33. package/dist/HebrewConverter.js.map +1 -0
  34. package/dist/HindiConverter.js +3 -0
  35. package/dist/HindiConverter.js.map +1 -0
  36. package/dist/HungarianConverter.js +3 -0
  37. package/dist/HungarianConverter.js.map +1 -0
  38. package/dist/IndonesianConverter.js +3 -0
  39. package/dist/IndonesianConverter.js.map +1 -0
  40. package/dist/ItalianConverter.js +3 -0
  41. package/dist/ItalianConverter.js.map +1 -0
  42. package/dist/JapaneseConverter.js +3 -0
  43. package/dist/JapaneseConverter.js.map +1 -0
  44. package/dist/KannadaConverter.js +3 -0
  45. package/dist/KannadaConverter.js.map +1 -0
  46. package/dist/KoreanConverter.js +3 -0
  47. package/dist/KoreanConverter.js.map +1 -0
  48. package/dist/LatvianConverter.js +3 -0
  49. package/dist/LatvianConverter.js.map +1 -0
  50. package/dist/LithuanianConverter.js +3 -0
  51. package/dist/LithuanianConverter.js.map +1 -0
  52. package/dist/MalayConverter.js +3 -0
  53. package/dist/MalayConverter.js.map +1 -0
  54. package/dist/MarathiConverter.js +3 -0
  55. package/dist/MarathiConverter.js.map +1 -0
  56. package/dist/NorwegianBokmalConverter.js +3 -0
  57. package/dist/NorwegianBokmalConverter.js.map +1 -0
  58. package/dist/PersianConverter.js +3 -0
  59. package/dist/PersianConverter.js.map +1 -0
  60. package/dist/PolishConverter.js +3 -0
  61. package/dist/PolishConverter.js.map +1 -0
  62. package/dist/PortugueseConverter.js +3 -0
  63. package/dist/PortugueseConverter.js.map +1 -0
  64. package/dist/PunjabiConverter.js +3 -0
  65. package/dist/PunjabiConverter.js.map +1 -0
  66. package/dist/RomanianConverter.js +3 -0
  67. package/dist/RomanianConverter.js.map +1 -0
  68. package/dist/RussianConverter.js +3 -0
  69. package/dist/RussianConverter.js.map +1 -0
  70. package/dist/SerbianCyrillicConverter.js +3 -0
  71. package/dist/SerbianCyrillicConverter.js.map +1 -0
  72. package/dist/SerbianLatinConverter.js +3 -0
  73. package/dist/SerbianLatinConverter.js.map +1 -0
  74. package/dist/SimplifiedChineseConverter.js +3 -0
  75. package/dist/SimplifiedChineseConverter.js.map +1 -0
  76. package/dist/SpanishConverter.js +3 -0
  77. package/dist/SpanishConverter.js.map +1 -0
  78. package/dist/SwahiliConverter.js +3 -0
  79. package/dist/SwahiliConverter.js.map +1 -0
  80. package/dist/SwedishConverter.js +3 -0
  81. package/dist/SwedishConverter.js.map +1 -0
  82. package/dist/TamilConverter.js +3 -0
  83. package/dist/TamilConverter.js.map +1 -0
  84. package/dist/TeluguConverter.js +3 -0
  85. package/dist/TeluguConverter.js.map +1 -0
  86. package/dist/ThaiConverter.js +3 -0
  87. package/dist/ThaiConverter.js.map +1 -0
  88. package/dist/TraditionalChineseConverter.js +3 -0
  89. package/dist/TraditionalChineseConverter.js.map +1 -0
  90. package/dist/TurkishConverter.js +3 -0
  91. package/dist/TurkishConverter.js.map +1 -0
  92. package/dist/UkrainianConverter.js +3 -0
  93. package/dist/UkrainianConverter.js.map +1 -0
  94. package/dist/UrduConverter.js +3 -0
  95. package/dist/UrduConverter.js.map +1 -0
  96. package/dist/VietnameseConverter.js +3 -0
  97. package/dist/VietnameseConverter.js.map +1 -0
  98. package/dist/n2words.js +3 -2
  99. package/dist/n2words.js.map +1 -1
  100. package/lib/classes/abstract-language.d.ts +178 -0
  101. package/lib/classes/abstract-language.js +192 -185
  102. package/lib/classes/greedy-scale-language.d.ts +109 -0
  103. package/lib/classes/greedy-scale-language.js +96 -90
  104. package/lib/classes/slavic-language.d.ts +148 -0
  105. package/lib/classes/slavic-language.js +136 -106
  106. package/lib/classes/south-asian-language.d.ts +70 -0
  107. package/lib/classes/south-asian-language.js +58 -65
  108. package/lib/classes/turkic-language.d.ts +26 -0
  109. package/lib/classes/turkic-language.js +22 -26
  110. package/lib/languages/ar.d.ts +30 -0
  111. package/lib/languages/ar.js +49 -133
  112. package/lib/languages/az.d.ts +12 -0
  113. package/lib/languages/az.js +7 -23
  114. package/lib/languages/bn.d.ts +11 -0
  115. package/lib/languages/bn.js +12 -7
  116. package/lib/languages/cs.d.ts +88 -0
  117. package/lib/languages/cs.js +44 -113
  118. package/lib/languages/da.d.ts +15 -0
  119. package/lib/languages/da.js +40 -87
  120. package/lib/languages/de.d.ts +14 -0
  121. package/lib/languages/de.js +34 -68
  122. package/lib/languages/el.d.ts +14 -0
  123. package/lib/languages/el.js +22 -48
  124. package/lib/languages/en.d.ts +16 -0
  125. package/lib/languages/en.js +22 -59
  126. package/lib/languages/es.d.ts +15 -0
  127. package/lib/languages/es.js +49 -81
  128. package/lib/languages/fa.d.ts +47 -0
  129. package/lib/languages/fa.js +90 -73
  130. package/lib/languages/fil.d.ts +16 -0
  131. package/lib/languages/fil.js +35 -76
  132. package/lib/languages/fr-BE.d.ts +11 -0
  133. package/lib/languages/fr-BE.js +15 -51
  134. package/lib/languages/fr.d.ts +15 -0
  135. package/lib/languages/fr.js +33 -72
  136. package/lib/languages/gu.d.ts +11 -0
  137. package/lib/languages/gu.js +10 -34
  138. package/lib/languages/hbo.d.ts +113 -0
  139. package/lib/languages/hbo.js +251 -0
  140. package/lib/languages/he.d.ts +80 -0
  141. package/lib/languages/he.js +41 -164
  142. package/lib/languages/hi.d.ts +11 -0
  143. package/lib/languages/hi.js +12 -7
  144. package/lib/languages/hr.d.ts +80 -0
  145. package/lib/languages/hr.js +51 -95
  146. package/lib/languages/hu.d.ts +22 -0
  147. package/lib/languages/hu.js +35 -53
  148. package/lib/languages/id.d.ts +37 -0
  149. package/lib/languages/id.js +29 -44
  150. package/lib/languages/it.d.ts +37 -0
  151. package/lib/languages/it.js +36 -52
  152. package/lib/languages/ja.d.ts +17 -0
  153. package/lib/languages/ja.js +22 -75
  154. package/lib/languages/kn.d.ts +11 -0
  155. package/lib/languages/kn.js +10 -39
  156. package/lib/languages/ko.d.ts +14 -0
  157. package/lib/languages/ko.js +17 -45
  158. package/lib/languages/lt.d.ts +70 -0
  159. package/lib/languages/lt.js +28 -63
  160. package/lib/languages/lv.d.ts +70 -0
  161. package/lib/languages/lv.js +35 -58
  162. package/lib/languages/mr.d.ts +11 -0
  163. package/lib/languages/mr.js +10 -34
  164. package/lib/languages/ms.d.ts +31 -0
  165. package/lib/languages/ms.js +24 -20
  166. package/lib/languages/nb.d.ts +12 -0
  167. package/lib/languages/nb.js +36 -56
  168. package/lib/languages/nl.d.ts +16 -0
  169. package/lib/languages/nl.js +58 -109
  170. package/lib/languages/pa.d.ts +11 -0
  171. package/lib/languages/{pa-Guru.js → pa.js} +12 -7
  172. package/lib/languages/pl.d.ts +80 -0
  173. package/lib/languages/pl.js +26 -105
  174. package/lib/languages/pt.d.ts +29 -0
  175. package/lib/languages/pt.js +29 -64
  176. package/lib/languages/ro.d.ts +158 -0
  177. package/lib/languages/ro.js +60 -167
  178. package/lib/languages/ru.d.ts +85 -0
  179. package/lib/languages/ru.js +17 -37
  180. package/lib/languages/sr-Cyrl.d.ts +80 -0
  181. package/lib/languages/sr-Cyrl.js +113 -0
  182. package/lib/languages/sr-Latn.d.ts +80 -0
  183. package/lib/languages/sr-Latn.js +54 -98
  184. package/lib/languages/sv.d.ts +14 -0
  185. package/lib/languages/sv.js +26 -63
  186. package/lib/languages/sw.d.ts +39 -0
  187. package/lib/languages/sw.js +26 -21
  188. package/lib/languages/ta.d.ts +20 -0
  189. package/lib/languages/ta.js +26 -26
  190. package/lib/languages/te.d.ts +22 -0
  191. package/lib/languages/te.js +28 -38
  192. package/lib/languages/th.d.ts +17 -0
  193. package/lib/languages/th.js +25 -31
  194. package/lib/languages/tr.d.ts +12 -0
  195. package/lib/languages/tr.js +11 -38
  196. package/lib/languages/uk.d.ts +85 -0
  197. package/lib/languages/uk.js +18 -44
  198. package/lib/languages/ur.d.ts +11 -0
  199. package/lib/languages/ur.js +12 -7
  200. package/lib/languages/vi.d.ts +72 -0
  201. package/lib/languages/vi.js +25 -71
  202. package/lib/languages/zh-Hans.d.ts +21 -0
  203. package/lib/languages/zh-Hans.js +33 -87
  204. package/lib/languages/zh-Hant.d.ts +21 -0
  205. package/lib/languages/zh-Hant.js +111 -0
  206. package/lib/n2words.d.ts +209 -0
  207. package/lib/n2words.js +474 -191
  208. package/package.json +106 -67
  209. package/dist/languages/ar.js +0 -2
  210. package/dist/languages/ar.js.map +0 -1
  211. package/dist/languages/az.js +0 -2
  212. package/dist/languages/az.js.map +0 -1
  213. package/dist/languages/bn.js +0 -2
  214. package/dist/languages/bn.js.map +0 -1
  215. package/dist/languages/cs.js +0 -2
  216. package/dist/languages/cs.js.map +0 -1
  217. package/dist/languages/da.js +0 -2
  218. package/dist/languages/da.js.map +0 -1
  219. package/dist/languages/de.js +0 -2
  220. package/dist/languages/de.js.map +0 -1
  221. package/dist/languages/el.js +0 -2
  222. package/dist/languages/el.js.map +0 -1
  223. package/dist/languages/en.js +0 -2
  224. package/dist/languages/en.js.map +0 -1
  225. package/dist/languages/es.js +0 -2
  226. package/dist/languages/es.js.map +0 -1
  227. package/dist/languages/fa.js +0 -2
  228. package/dist/languages/fa.js.map +0 -1
  229. package/dist/languages/fil.js +0 -2
  230. package/dist/languages/fil.js.map +0 -1
  231. package/dist/languages/fr-BE.js +0 -2
  232. package/dist/languages/fr-BE.js.map +0 -1
  233. package/dist/languages/fr.js +0 -2
  234. package/dist/languages/fr.js.map +0 -1
  235. package/dist/languages/gu.js +0 -2
  236. package/dist/languages/gu.js.map +0 -1
  237. package/dist/languages/he.js +0 -2
  238. package/dist/languages/he.js.map +0 -1
  239. package/dist/languages/hi.js +0 -2
  240. package/dist/languages/hi.js.map +0 -1
  241. package/dist/languages/hr.js +0 -2
  242. package/dist/languages/hr.js.map +0 -1
  243. package/dist/languages/hu.js +0 -2
  244. package/dist/languages/hu.js.map +0 -1
  245. package/dist/languages/id.js +0 -2
  246. package/dist/languages/id.js.map +0 -1
  247. package/dist/languages/it.js +0 -2
  248. package/dist/languages/it.js.map +0 -1
  249. package/dist/languages/ja.js +0 -2
  250. package/dist/languages/ja.js.map +0 -1
  251. package/dist/languages/kn.js +0 -2
  252. package/dist/languages/kn.js.map +0 -1
  253. package/dist/languages/ko.js +0 -2
  254. package/dist/languages/ko.js.map +0 -1
  255. package/dist/languages/lt.js +0 -2
  256. package/dist/languages/lt.js.map +0 -1
  257. package/dist/languages/lv.js +0 -2
  258. package/dist/languages/lv.js.map +0 -1
  259. package/dist/languages/mr.js +0 -2
  260. package/dist/languages/mr.js.map +0 -1
  261. package/dist/languages/ms.js +0 -2
  262. package/dist/languages/ms.js.map +0 -1
  263. package/dist/languages/nb.js +0 -2
  264. package/dist/languages/nb.js.map +0 -1
  265. package/dist/languages/nl.js +0 -2
  266. package/dist/languages/nl.js.map +0 -1
  267. package/dist/languages/pa-Guru.js +0 -2
  268. package/dist/languages/pa-Guru.js.map +0 -1
  269. package/dist/languages/pl.js +0 -2
  270. package/dist/languages/pl.js.map +0 -1
  271. package/dist/languages/pt.js +0 -2
  272. package/dist/languages/pt.js.map +0 -1
  273. package/dist/languages/ro.js +0 -2
  274. package/dist/languages/ro.js.map +0 -1
  275. package/dist/languages/ru.js +0 -2
  276. package/dist/languages/ru.js.map +0 -1
  277. package/dist/languages/sr-Latn.js +0 -2
  278. package/dist/languages/sr-Latn.js.map +0 -1
  279. package/dist/languages/sv.js +0 -2
  280. package/dist/languages/sv.js.map +0 -1
  281. package/dist/languages/sw.js +0 -2
  282. package/dist/languages/sw.js.map +0 -1
  283. package/dist/languages/ta.js +0 -2
  284. package/dist/languages/ta.js.map +0 -1
  285. package/dist/languages/te.js +0 -2
  286. package/dist/languages/te.js.map +0 -1
  287. package/dist/languages/th.js +0 -2
  288. package/dist/languages/th.js.map +0 -1
  289. package/dist/languages/tr.js +0 -2
  290. package/dist/languages/tr.js.map +0 -1
  291. package/dist/languages/uk.js +0 -2
  292. package/dist/languages/uk.js.map +0 -1
  293. package/dist/languages/ur.js +0 -2
  294. package/dist/languages/ur.js.map +0 -1
  295. package/dist/languages/vi.js +0 -2
  296. package/dist/languages/vi.js.map +0 -1
  297. package/dist/languages/zh-Hans.js +0 -2
  298. package/dist/languages/zh-Hans.js.map +0 -1
  299. package/typings/classes/abstract-language.d.ts +0 -144
  300. package/typings/classes/greedy-scale-language.d.ts +0 -148
  301. package/typings/classes/slavic-language.d.ts +0 -145
  302. package/typings/classes/south-asian-language.d.ts +0 -101
  303. package/typings/classes/turkic-language.d.ts +0 -42
  304. package/typings/languages/ar.d.ts +0 -93
  305. package/typings/languages/az.d.ts +0 -25
  306. package/typings/languages/bn.d.ts +0 -1
  307. package/typings/languages/cs.d.ts +0 -120
  308. package/typings/languages/da.d.ts +0 -53
  309. package/typings/languages/de.d.ts +0 -26
  310. package/typings/languages/el.d.ts +0 -11
  311. package/typings/languages/en.d.ts +0 -30
  312. package/typings/languages/es.d.ts +0 -43
  313. package/typings/languages/fa.d.ts +0 -81
  314. package/typings/languages/fil.d.ts +0 -12
  315. package/typings/languages/fr-BE.d.ts +0 -41
  316. package/typings/languages/fr.d.ts +0 -43
  317. package/typings/languages/gu.d.ts +0 -12
  318. package/typings/languages/he.d.ts +0 -197
  319. package/typings/languages/hi.d.ts +0 -1
  320. package/typings/languages/hr.d.ts +0 -110
  321. package/typings/languages/hu.d.ts +0 -37
  322. package/typings/languages/id.d.ts +0 -69
  323. package/typings/languages/it.d.ts +0 -51
  324. package/typings/languages/ja.d.ts +0 -58
  325. package/typings/languages/kn.d.ts +0 -11
  326. package/typings/languages/ko.d.ts +0 -25
  327. package/typings/languages/lt.d.ts +0 -110
  328. package/typings/languages/lv.d.ts +0 -99
  329. package/typings/languages/mr.d.ts +0 -12
  330. package/typings/languages/ms.d.ts +0 -37
  331. package/typings/languages/nb.d.ts +0 -27
  332. package/typings/languages/nl.d.ts +0 -65
  333. package/typings/languages/pa-Guru.d.ts +0 -1
  334. package/typings/languages/pl.d.ts +0 -116
  335. package/typings/languages/pt.d.ts +0 -39
  336. package/typings/languages/ro.d.ts +0 -229
  337. package/typings/languages/ru.d.ts +0 -108
  338. package/typings/languages/sr-Latn.d.ts +0 -98
  339. package/typings/languages/sv.d.ts +0 -30
  340. package/typings/languages/sw.d.ts +0 -1
  341. package/typings/languages/ta.d.ts +0 -1
  342. package/typings/languages/te.d.ts +0 -1
  343. package/typings/languages/th.d.ts +0 -1
  344. package/typings/languages/tr.d.ts +0 -46
  345. package/typings/languages/uk.d.ts +0 -117
  346. package/typings/languages/ur.d.ts +0 -1
  347. package/typings/languages/vi.d.ts +0 -116
  348. package/typings/languages/zh-Hans.d.ts +0 -57
  349. package/typings/n2words.d.ts +0 -177
@@ -1,44 +1,25 @@
1
- import AbstractLanguage from '../classes/abstract-language.js'
1
+ import { AbstractLanguage } from '../classes/abstract-language.js'
2
2
 
3
3
  /**
4
4
  * Japanese language converter.
5
5
  *
6
- * Converts numbers to Japanese kanji numerals using the Sino-Japanese system:
7
- * - Uses kanji characters (一, 二, 三, etc.)
8
- * - Grouping by 万 (man, 10,000) and (oku, 100,000,000)
9
- * - Unique scale units: (chō, trillion), (kei, 10^16)
10
- * - Special rules for 1: omitted before 十 (10), 百 (100), 千 (1000), but kept for 万 and above
11
- *
12
- * Key Features:
13
- * - Sino-Japanese number system (standard for general counting)
14
- * - Grouping by powers of 10,000 (万-based system, not 1,000)
15
- * - Scale units: 万 (10^4), 億 (10^8), 兆 (10^12), 京 (10^16)
16
- * - Special handling of 一 (one) prefix
17
- * - Support for very large numbers up to 無量大数 (10^68)
18
- *
19
- * Algorithm:
20
- * 1. Split number into groups of 4 digits (万-based, not 3-digit thousand-based)
21
- * 2. Convert each group to kanji using special rules
22
- * 3. Append appropriate scale word (万, 億, 兆, etc.)
23
- * 4. Join all groups
24
- *
25
- * Special Rules:
26
- * - 10, 100, 1000: Don't use 一 prefix (十, 百, 千 not 一十, 一百, 一千)
27
- * - 10,000+: Keep 一 prefix (一万, 一億, 一兆)
28
- * - Zero: 零 or 〇 (both acceptable, 零 is more formal)
6
+ * Supports:
7
+ * - Kanji numerals (一, 二, 三, etc.)
8
+ * - Grouping by 万 (10,000) instead of 1,000
9
+ * - Special (one) omission rules (十, 百, but 一万, 一億)
29
10
  */
30
11
  export class Japanese extends AbstractLanguage {
31
12
  negativeWord = 'マイナス'
32
13
  decimalSeparatorWord = '点'
33
14
  zeroWord = '零'
34
15
  wordSeparator = '' // Japanese doesn't use spaces between characters
35
- convertDecimalsPerDigit = true // Enable digit-by-digit decimal conversion
16
+ usePerDigitDecimals = true // Enable digit-by-digit decimal conversion
36
17
 
37
- // Digits used for group conversion (1-9)
38
- digits = ['一', '二', '三', '四', '五', '六', '七', '八', '九']
18
+ // Ones words used for group conversion (1-9)
19
+ onesWords = ['一', '二', '三', '四', '五', '六', '七', '八', '九']
39
20
 
40
21
  // Scale words for grouping by 10^4
41
- scales = [
22
+ scaleWords = [
42
23
  '', // 10^0 (ones)
43
24
  '万', // 10^4 (man)
44
25
  '億', // 10^8 (oku)
@@ -59,19 +40,8 @@ export class Japanese extends AbstractLanguage {
59
40
  '無量大数' // 10^68 (muryōtaisū)
60
41
  ]
61
42
 
62
- /**
63
- * Converts a group of up to 4 digits to Japanese kanji.
64
- * Handles special rules for omitting 一 before 十, 百, 千.
65
- *
66
- * Rule: Within a group, omit 一 before 十/百/千 EXCEPT when:
67
- * - It's a lower group (not isTopGroup) AND
68
- * - It would be the only character in that position
69
- *
70
- * @param {bigint} num - Number from 0 to 9999
71
- * @param {boolean} isTopGroup - Whether this is the highest non-zero group
72
- * @returns {string} Japanese kanji representation
73
- */
74
- convertGroup (num, isTopGroup = false) {
43
+ /** Converts a segment of up to 4 digits to Japanese kanji with 一 omission rules. */
44
+ segmentToWords (num) {
75
45
  if (num === 0n) return ''
76
46
 
77
47
  const thousands = num / 1000n
@@ -87,7 +57,7 @@ export class Japanese extends AbstractLanguage {
87
57
  if (thousands === 1n) {
88
58
  result += '千'
89
59
  } else {
90
- result += this.digits[Number(thousands) - 1] + '千'
60
+ result += this.onesWords[Number(thousands) - 1] + '千'
91
61
  }
92
62
  }
93
63
 
@@ -97,7 +67,7 @@ export class Japanese extends AbstractLanguage {
97
67
  if (hundreds === 1n) {
98
68
  result += '百'
99
69
  } else {
100
- result += this.digits[Number(hundreds) - 1] + '百'
70
+ result += this.onesWords[Number(hundreds) - 1] + '百'
101
71
  }
102
72
  }
103
73
 
@@ -107,30 +77,25 @@ export class Japanese extends AbstractLanguage {
107
77
  if (tens === 1n) {
108
78
  result += '十'
109
79
  } else {
110
- result += this.digits[Number(tens) - 1] + '十'
80
+ result += this.onesWords[Number(tens) - 1] + '十'
111
81
  }
112
82
  }
113
83
 
114
84
  // Ones
115
85
  if (ones > 0n) {
116
- result += this.digits[Number(ones) - 1]
86
+ result += this.onesWords[Number(ones) - 1]
117
87
  }
118
88
 
119
89
  return result
120
90
  }
121
91
 
122
- /**
123
- * Converts a BigInt number to Japanese cardinal form.
124
- *
125
- * @param {bigint} number - The number to convert
126
- * @returns {string} Japanese kanji representation
127
- */
128
- convertWholePart (number) {
129
- if (number === 0n) {
92
+ /** Converts integer part using Japanese 万-based grouping system. */
93
+ integerToWords (integerPart) {
94
+ if (integerPart === 0n) {
130
95
  return this.zeroWord
131
96
  }
132
97
 
133
- let temp = number
98
+ let temp = integerPart
134
99
  let scaleIndex = 0
135
100
  const groups = []
136
101
 
@@ -151,17 +116,16 @@ export class Japanese extends AbstractLanguage {
151
116
 
152
117
  for (let i = 0; i < groups.length; i++) {
153
118
  const { value, scale } = groups[i]
154
- const isTopGroup = (i === 0)
155
119
 
156
- const groupStr = this.convertGroup(value, isTopGroup)
120
+ const groupStr = this.segmentToWords(value)
157
121
 
158
122
  // For scales >= 1 (万 and above), always add the scale word
159
123
  if (scale >= 1) {
160
124
  // Special case: if group is 1 and scale >= 1, we need 一 before the scale
161
125
  if (value === 1n) {
162
- result += '一' + this.scales[scale]
126
+ result += '一' + this.scaleWords[scale]
163
127
  } else {
164
- result += groupStr + this.scales[scale]
128
+ result += groupStr + this.scaleWords[scale]
165
129
  }
166
130
  } else {
167
131
  result += groupStr
@@ -171,20 +135,3 @@ export class Japanese extends AbstractLanguage {
171
135
  return result
172
136
  }
173
137
  }
174
-
175
- /**
176
- * Converts a value to cardinal (written) form in Japanese.
177
- *
178
- * @param {number|string|bigint} value - Number to convert.
179
- * @param {Object} [options] - Options for the converter.
180
- * @returns {string} Value in Japanese kanji numerals.
181
- * @throws {Error} If value is invalid.
182
- *
183
- * @example
184
- * convertToWords(42, { lang: 'ja' }); // '四十二'
185
- * convertToWords(1000, { lang: 'ja' }); // '千'
186
- * convertToWords(10000, { lang: 'ja' }); // '一万'
187
- */
188
- export default function convertToWords (value, options = {}) {
189
- return new Japanese(options).convertToWords(value)
190
- }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Kannada language converter.
3
+ *
4
+ * Supports:
5
+ * - Indian numbering system (ಸಾವಿರ, ಲಕ್ಷ, ಕೋಟಿ)
6
+ * - Kannada script
7
+ * - Complete word forms for 0-99
8
+ */
9
+ export class Kannada extends SouthAsianLanguage {
10
+ }
11
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js';
@@ -1,27 +1,21 @@
1
- /**
2
- * Converts numbers to their word representation in Kannada (ಕನ್ನಡ).
3
- * @module languages/kn
4
- */
5
-
6
- import SouthAsianLanguage from '../classes/south-asian-language.js'
1
+ import { SouthAsianLanguage } from '../classes/south-asian-language.js'
7
2
 
8
3
  /**
9
- * Kannada language implementation using Indian-style number grouping.
10
- * @extends SouthAsianLanguage
4
+ * Kannada language converter.
5
+ *
6
+ * Supports:
7
+ * - Indian numbering system (ಸಾವಿರ, ಲಕ್ಷ, ಕೋಟಿ)
8
+ * - Kannada script
9
+ * - Complete word forms for 0-99
11
10
  */
12
- class KannadaLanguage extends SouthAsianLanguage {
11
+ export class Kannada extends SouthAsianLanguage {
13
12
  negativeWord = 'ಋಣಾತ್ಮಕ'
14
13
  decimalSeparatorWord = 'ದಶಮಾಂಶ'
15
14
  zeroWord = 'ಸೊನ್ನೆ'
16
15
  hundredWord = 'ನೂರು'
17
- convertDecimalsPerDigit = true
16
+ usePerDigitDecimals = true
18
17
 
19
- /**
20
- * Array of number words from 0 to 99.
21
- * Index matches the number value.
22
- * @type {string[]}
23
- */
24
- belowHundred = [
18
+ belowHundredWords = [
25
19
  'ಸೊನ್ನೆ', 'ಒಂದು', 'ಎರಡು', 'ಮೂರು', 'ನಾಲ್ಕು', 'ಐದು', 'ಆರು', 'ಏಳು', 'ಎಂಟು', 'ಒಂಬತ್ತು',
26
20
  'ಹತ್ತು', 'ಹನ್ನೊಂದು', 'ಹನ್ನೆರಡು', 'ಹದಿಮೂರು', 'ಹದಿನಾಲ್ಕು', 'ಹದಿನೈದು', 'ಹದಿನಾರು', 'ಹದಿನೇಳು', 'ಹದಿನೆಂಟು', 'ಹತ್ತೊಂಬತ್ತು',
27
21
  'ಇಪ್ಪತ್ತು', 'ಇಪ್ಪತ್ತೊಂದು', 'ಇಪ್ಪತ್ತೆರಡು', 'ಇಪ್ಪತ್ತಮೂರು', 'ಇಪ್ಪತ್ತನಾಲ್ಕು', 'ಇಪ್ಪತ್ತೈದು', 'ಇಪ್ಪತ್ತಾರು', 'ಇಪ್ಪತ್ತೇಳು', 'ಇಪ್ಪತ್ತೆಂಟು', 'ಇಪ್ಪತ್ತೊಂಬತ್ತು',
@@ -34,11 +28,6 @@ class KannadaLanguage extends SouthAsianLanguage {
34
28
  'ತೊಂಬತ್ತು', 'ತೊಂಬತ್ತೊಂದು', 'ತೊಂಬತ್ತೆರಡು', 'ತೊಂಬತ್ತಮೂರು', 'ತೊಂಬತ್ತನಾಲ್ಕು', 'ತೊಂಬತ್ತೈದು', 'ತೊಂಬತ್ತಾರು', 'ತೊಂಬತ್ತೇಳು', 'ತೊಂಬತ್ತೆಂಟು', 'ತೊಂಬತ್ತೊಂಬತ್ತು'
35
29
  ]
36
30
 
37
- /**
38
- * Scale words for powers of ten in Indian numbering system.
39
- * Index 0 = units, 1 = thousand, 2 = lakh, 3 = crore, etc.
40
- * @type {string[]}
41
- */
42
31
  scaleWords = [
43
32
  '', // units
44
33
  'ಸಾವಿರ', // thousand (1,000)
@@ -50,22 +39,4 @@ class KannadaLanguage extends SouthAsianLanguage {
50
39
  'ಪದ್ಮ', // padma (1,000,000,000,000,000)
51
40
  'ಶಂಖ' // shankh (100,000,000,000,000,000)
52
41
  ]
53
-
54
- /**
55
- * Converts numbers using the belowHundred array directly.
56
- */
57
- }
58
-
59
- /**
60
- * Converts a number to its word representation in Kannada.
61
- * @param {number|string|bigint} value - The number to convert
62
- * @param {Object} [options={}] - Conversion options
63
- * @returns {string} The word representation of the number
64
- * @example
65
- * convertToWords(42) // 'ನಲವತ್ತೆರಡು'
66
- * convertToWords(1000) // 'ಒಂದು ಸಾವಿರ'
67
- * convertToWords(100000) // 'ಒಂದು ಲಕ್ಷ'
68
- */
69
- export default function convertToWords (value, options = {}) {
70
- return new KannadaLanguage(options).convertToWords(value)
71
42
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Korean language converter.
3
+ *
4
+ * Supports:
5
+ * - Hangul numerals (일, 이, 삼, etc.)
6
+ * - Grouping by 만 (10,000) system
7
+ * - Implicit '일' (one) omission before multipliers
8
+ */
9
+ export class Korean extends GreedyScaleLanguage {
10
+ scaleWords: (string | bigint)[][];
11
+ /** Combines two word-sets according to Korean grammar rules. */
12
+ combineWordSets(preceding: any, following: any): any;
13
+ }
14
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
@@ -1,18 +1,19 @@
1
- import GreedyScaleLanguage from '../classes/greedy-scale-language.js'
1
+ import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
2
2
 
3
3
  /**
4
4
  * Korean language converter.
5
5
  *
6
- * Features:
7
- * - Space-separated for large numbers (>= 만/10,000)
8
- * - Concatenated for smaller numbers
9
- * - Omits '일' (1) before multipliers
6
+ * Supports:
7
+ * - Hangul numerals (일, 이, 삼, etc.)
8
+ * - Grouping by (10,000) system
9
+ * - Implicit '일' (one) omission before multipliers
10
10
  */
11
11
  export class Korean extends GreedyScaleLanguage {
12
12
  negativeWord = '마이너스'
13
13
  decimalSeparatorWord = '점'
14
14
  zeroWord = '영'
15
- scaleWordPairs = [
15
+
16
+ scaleWords = [
16
17
  [10_000_000_000_000_000_000_000_000_000n, '양'],
17
18
  [1_000_000_000_000_000_000_000_000n, '자'],
18
19
  [100_000_000_000_000_000_000n, '해'],
@@ -35,49 +36,20 @@ export class Korean extends GreedyScaleLanguage {
35
36
  [0n, '영']
36
37
  ]
37
38
 
38
- /**
39
- * Merges two adjacent word-number pairs according to Korean grammar rules.
40
- *
41
- * Korean-specific rules:
42
- * - Omits '일' (1) before multipliers <= 만 (10,000)
43
- * - Concatenates without space for small numbers (< 만)
44
- * - Separates with space for large numbers (>= 만)
45
- * - Multiplies when right > left, adds when left > right
46
- *
47
- * @param {Object} leftPair The left operand as `{ word: number }`.
48
- * @param {Object} rightPair The right operand as `{ word: number }`.
49
- * @returns {Object} Merged pair with combined word and resulting number.
50
- */
51
- mergeScales (leftPair, rightPair) {
52
- const leftWord = Object.keys(leftPair)[0]
53
- const rightWord = Object.keys(rightPair)[0]
54
- const leftNumber = Object.values(leftPair)[0] // BigInt
55
- const rightNumber = Object.values(rightPair)[0] // BigInt
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
56
45
 
57
46
  // Implicit "일": omit 1 before multipliers up to 만 (10,000)
58
- if (leftNumber === 1n && rightNumber <= 10_000n) return rightPair
47
+ if (precedingValue === 1n && followingValue <= 10_000n) return following
59
48
  // Concatenate (no space) for small numbers less than 만
60
- if (leftNumber < 10_000n && leftNumber > rightNumber) return { [`${leftWord}${rightWord}`]: leftNumber + rightNumber }
49
+ if (precedingValue < 10_000n && precedingValue > followingValue) return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
61
50
  // Space-separate for large numbers (>= 만) when adding
62
- if (leftNumber >= 10_000n && leftNumber > rightNumber) return { [`${leftWord} ${rightWord}`]: leftNumber + rightNumber }
51
+ if (precedingValue >= 10_000n && precedingValue > followingValue) return { [`${precedingWord} ${followingWord}`]: precedingValue + followingValue }
63
52
  // Multiply for all scale combinations
64
- return { [`${leftWord}${rightWord}`]: leftNumber * rightNumber }
53
+ return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
65
54
  }
66
55
  }
67
-
68
- /**
69
- * Converts a number to Korean cardinal (written) form.
70
- *
71
- * @param {number|string|bigint} value The number to convert.
72
- * @param {Object} [options] Conversion options (see Korean class options).
73
- * @returns {string} The number expressed in Korean words.
74
- * @throws {TypeError} If value is NaN or invalid type.
75
- * @throws {Error} If value is an invalid number string.
76
- *
77
- * @example
78
- * convertToWords(42); // '사십이'
79
- * convertToWords(10001); // '만 일'
80
- */
81
- export default function convertToWords (value, options = {}) {
82
- return new Korean(options).convertToWords(value)
83
- }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Lithuanian language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Gender agreement (vienas/viena, du/dvi)
7
+ * - Baltic declension patterns
8
+ */
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';
@@ -1,40 +1,19 @@
1
- import SlavicLanguage from '../classes/slavic-language.js'
2
-
3
- /**
4
- * @typedef {Object} SlavicOptions
5
- * @property {boolean} [feminine=false] Use feminine forms for numbers.
6
- */
1
+ import { SlavicLanguage } from '../classes/slavic-language.js'
7
2
 
8
3
  /**
9
4
  * Lithuanian language converter.
10
5
  *
11
- * Implements Lithuanian number words using the Slavic language pattern:
12
- * - Lithuanian number words (vienas/viena, du/dvi, trys, keturi...)
13
- * - Gender-aware forms (masculine/feminine)
14
- * - Baltic three-form pluralization (tūkstantis/tūkstančiai/tūkstančių)
15
- * - Lithuanian-specific declension patterns
16
- *
17
- * Key Features:
18
- * - Three-form pluralization system shared across Slavic/Baltic languages
19
- * * Form 1 (singular): 1 (e.g., "tūkstantis")
20
- * * Form 2 (few): 2-4, 22-24, 32-34... excluding teens (e.g., "tūkstančiai")
21
- * * Form 3 (many): all other numbers (e.g., "tūkstančių")
22
- * - Chunk-based decomposition (splits into groups of 3 digits: ones, thousands, millions, etc.)
23
- * - Large number handling via thousands[] array with indexed [singular, few, many] forms
24
- * - Gender-specific number forms for 1 and 2 (masculine/feminine dual forms)
25
- *
26
- * Features:
27
- * - Dual gender forms (vienas/viena, du/dvi, keturi/keturios)
28
- * - Complex declension patterns for large numbers
29
- * - Baltic language characteristics
30
- *
31
- * Inherits from SlavicLanguage as Lithuanian uses similar pluralization.
6
+ * Supports:
7
+ * - Three-form pluralization (one/few/many)
8
+ * - Gender agreement (vienas/viena, du/dvi)
9
+ * - Baltic declension patterns
32
10
  */
33
11
  export class Lithuanian extends SlavicLanguage {
34
12
  negativeWord = 'minus'
35
13
  decimalSeparatorWord = 'kablelis'
36
14
  zeroWord = 'nulis'
37
- ones = {
15
+
16
+ onesWords = {
38
17
  1: 'vienas',
39
18
  2: 'du',
40
19
  3: 'trys',
@@ -46,7 +25,7 @@ export class Lithuanian extends SlavicLanguage {
46
25
  9: 'devyni'
47
26
  }
48
27
 
49
- onesFeminine = {
28
+ onesFeminineWords = {
50
29
  1: 'viena',
51
30
  2: 'dvi',
52
31
  3: 'trys',
@@ -58,7 +37,7 @@ export class Lithuanian extends SlavicLanguage {
58
37
  9: 'devynios'
59
38
  }
60
39
 
61
- tens = {
40
+ teensWords = {
62
41
  0: 'dešimt',
63
42
  1: 'vienuolika',
64
43
  2: 'dvylika',
@@ -71,7 +50,7 @@ export class Lithuanian extends SlavicLanguage {
71
50
  9: 'devyniolika'
72
51
  }
73
52
 
74
- twenties = {
53
+ twentiesWords = {
75
54
  2: 'dvidešimt',
76
55
  3: 'trisdešimt',
77
56
  4: 'keturiasdešimt',
@@ -82,9 +61,9 @@ export class Lithuanian extends SlavicLanguage {
82
61
  9: 'devyniasdešimt'
83
62
  }
84
63
 
85
- hundreds = ['šimtas', 'šimtai']
64
+ hundredsWords = ['šimtas', 'šimtai']
86
65
 
87
- thousands = {
66
+ pluralForms = {
88
67
  1: ['tūkstantis', 'tūkstančiai', 'tūkstančių'],
89
68
  2: ['milijonas', 'milijonai', 'milijonų'],
90
69
  3: ['milijardas', 'milijardai', 'milijardų'],
@@ -102,7 +81,7 @@ export class Lithuanian extends SlavicLanguage {
102
81
  return forms[2]
103
82
  }
104
83
 
105
- const [n1, n2] = this.getDigits(n)
84
+ const [n1, n2] = this.extractDigits(n)
106
85
 
107
86
  if (n2 === 1n || n1 === 0n) {
108
87
  return forms[2]
@@ -115,57 +94,43 @@ export class Lithuanian extends SlavicLanguage {
115
94
  return forms[1]
116
95
  }
117
96
 
118
- convertWholePart (number) {
119
- if (number === 0n) {
97
+ integerToWords (integerPart) {
98
+ if (integerPart === 0n) {
120
99
  return this.zeroWord
121
100
  }
122
101
  const words = []
123
- const chunks = this.splitByX(number.toString(), 3)
124
- let index = chunks.length
125
- for (const x of chunks) {
102
+ const segments = this.splitToSegments(integerPart.toString(), 3)
103
+ let index = segments.length
104
+ for (const x of segments) {
126
105
  index = index - 1
127
106
  if (x === 0n) {
128
107
  continue
129
108
  }
130
- const [n1, n2, n3] = this.getDigits(x)
109
+ const [n1, n2, n3] = this.extractDigits(x)
131
110
  if (n3 > 0n) {
132
- words.push(this.ones[n3])
111
+ words.push(this.onesWords[n3])
133
112
  if (n3 > 1n) {
134
- words.push(this.hundreds[1])
113
+ words.push(this.hundredsWords[1])
135
114
  } else {
136
- words.push(this.hundreds[0])
115
+ words.push(this.hundredsWords[0])
137
116
  }
138
117
  }
139
118
  if (n2 > 1n) {
140
- words.push(this.twenties[n2])
119
+ words.push(this.twentiesWords[n2])
141
120
  }
142
121
  if (n2 === 1n) {
143
- words.push(this.tens[n1])
122
+ words.push(this.teensWords[n1])
144
123
  } else if (n1 > 0n) {
145
- if ((index === 1 || (this.feminine && index === 0)) && number < 1000n) {
146
- words.push(this.onesFeminine[n1])
124
+ if ((index === 1 || (this.options.gender === 'feminine' && index === 0)) && integerPart < 1000n) {
125
+ words.push(this.onesFeminineWords[n1])
147
126
  } else {
148
- words.push(this.ones[n1])
127
+ words.push(this.onesWords[n1])
149
128
  }
150
129
  }
151
130
  if (index > 0) {
152
- words.push(this.pluralize(x, this.thousands[index]))
131
+ words.push(this.pluralize(x, this.pluralForms[index]))
153
132
  }
154
133
  }
155
134
  return words.join(' ')
156
135
  }
157
136
  }
158
-
159
- /**
160
- * Converts a number to Lithuanian cardinal (written) form.
161
- *
162
- * @param {number|string|bigint} value The number to convert.
163
- * @param {Object} [options={}] Configuration options.
164
- * @param {boolean} [options.feminine=false] Use feminine forms for numbers.
165
- * @returns {string} The number expressed in Lithuanian words.
166
- * @throws {TypeError} If value is NaN or invalid type.
167
- * @throws {Error} If value is an invalid number string.
168
- */
169
- export default function convertToWords (value, options = {}) {
170
- return new Lithuanian(options).convertToWords(value)
171
- }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Latvian language converter.
3
+ *
4
+ * Supports:
5
+ * - Three-form pluralization (one/few/many)
6
+ * - Latvian diacritical marks (ī, ā, ē, ū)
7
+ * - Compound number formation (divdesmit, trīsdesmit)
8
+ */
9
+ export class Latvian 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';