cjk-number 0.2.1 → 0.4.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 CHANGED
@@ -39,20 +39,31 @@ import {
39
39
  hiragana
40
40
  } from "cjk-number";
41
41
 
42
- // parse string -> number/bigint
43
- integer.parseInt("一千零二十三"); // 1023
44
- integer.parseInt("壹仟零貳拾參"); // 1023
45
- integer.parseInt("負一百零二"); // -102
46
- integer.parseInt("一點二三"); // 1.23
47
- integer.parseInt("一無量大數", { preferBigInt: true }); // 10n ** 68n
48
-
49
- // format number/bigint -> string
42
+ // parse string -> number / bigint / string
43
+ number.parse("一千零二十三"); // 1023
44
+ number.parse("壹仟零貳拾參"); // 1023
45
+ number.parse("負一百零二"); // -102
46
+ number.parse("一點二三"); // 1.23
47
+ number.parse("一無量大數", { mode: "preferBigInt" }); // 10n ** 68n
48
+ number.parse("一京點一", { mode: "exactDecimal" }); // "10000000000000000.1" (lossless)
49
+
50
+ // format number/bigint/string -> CJK
50
51
  cjkIdeographic.parse(1023); // "一千零二十三"
51
52
  tradChineseFormal.parse(1023); // "壹仟零貳拾參"
52
53
  simpChineseFormal.parse(1023); // "壹仟零贰拾叁"
53
54
  koreanHangulFormal.parse(10n ** 68n); // "일무량대수"
54
55
  japaneseFormal.parse(10n ** 68n); // "壱無量大数"
55
56
 
57
+ // arithmetic on CJK strings (exact BigFloat engine)
58
+ tradChineseInformal.add(["一兆", "一點五"]); // "一兆零一點五"
59
+ tradChineseInformal.subtract(["一京", "一兆"]); // "九千九百九十九兆"
60
+ tradChineseInformal.multiply(["一億", "一億"]); // "一京"
61
+ tradChineseInformal.divide(["五", "二"]); // "二點五"
62
+ tradChineseInformal.modulo("五", "二"); // "一"
63
+ tradChineseInformal.pow("二", "十"); // "一千零二十四"
64
+ tradChineseInformal.abs("負一兆"); // "一兆"
65
+ ["三十", "二", "十一"].sort(tradChineseInformal.compare); // ["二", "十一", "三十"]
66
+
56
67
  // stem/branch
57
68
  cjkHeavenlyStem.parse(10); // "癸"
58
69
  cjkEarthlyBranch.parse(12); // "亥"
@@ -64,37 +75,68 @@ hiragana.parse(46); // "ん"
64
75
 
65
76
  ## API
66
77
 
67
- ### integer.parseInt(input, options?)
78
+ ### number.parse(input, options?)
68
79
 
69
- Parses CJK text into number or bigint.
80
+ Parses CJK text into a `number`, `bigint`, or exact decimal `string`.
70
81
 
71
82
  Options:
72
83
 
73
- - strict?: boolean
74
- - preferBigInt?: boolean
75
- - heavenlyStemMode?: "fixed" | "cyclic"
76
- - earthlyBranchMode?: "fixed" | "cyclic"
84
+ | Option | Type | Default | Description |
85
+ |---|---|---|---|
86
+ | `mode` | `"number" \| "preferBigInt" \| "exactDecimal"` | `"number"` | Controls the output numeric type |
87
+ | `strict` | `boolean` | `false` | Rejects unsupported characters early |
88
+ | `heavenlyStemMode` | `"fixed" \| "cyclic"` | `"fixed"` | How to handle out-of-range stem values |
89
+ | `earthlyBranchMode` | `"fixed" \| "cyclic"` | `"fixed"` | How to handle out-of-range branch values |
90
+ | `explicitTyping` | `ExplicitTyping` | `undefined` | Forces a specific CJK system for parsing |
91
+
92
+ **`mode` values:**
93
+
94
+ - `"number"` (default) — returns `number`; auto-promotes to `bigint` if the integer exceeds `Number.MAX_SAFE_INTEGER`.
95
+ - `"preferBigInt"` — always returns `bigint` for integer parse paths.
96
+ - `"exactDecimal"` — returns a lossless decimal `string` (e.g. `"10000000000000000.1"`), bypassing the `MAX_SAFE_INTEGER` restriction for mixed large+decimal values.
77
97
 
78
- Behavior summary:
98
+ **`explicitTyping` values:**
79
99
 
80
- - If the value fits safely, returns number by default.
81
- - If out of Number safe range, returns bigint automatically.
82
- - If preferBigInt is true, always returns bigint for integer parse paths.
83
- - Decimal parse returns number.
100
+ - Choose from any of the available system names (e.g., `"hiraganaIroha"`, `"tradChineseFormal"`, `"koreanHangulFormal"`) to force the parser to use that system's mapping specifically. This is useful for resolving conflicts between systems that share the same symbols (like Hiragana Gojuon vs Iroha).
84
101
 
85
102
  Examples:
86
103
 
87
104
  ```js
88
- integer.parseInt("九千零七兆一", { preferBigInt: true }); // 9007000000000001n
89
- integer.parseInt("癸"); // 10
90
- integer.parseInt("亥"); // 12
91
- integer.parseInt("壱京", { preferBigInt: true }); // 10n ** 16n
92
- integer.parseInt("ぬ"); // 10 (iroha sequence symbol)
105
+ number.parse("九千零七兆一", { mode: "preferBigInt" }); // 9007000000000001n
106
+ number.parse("癸"); // 10
107
+ number.parse("亥"); // 12
108
+ number.parse("壱京", { mode: "preferBigInt" }); // 10n ** 16n
109
+ number.parse("ぬ", { explicitTyping: "hiraganaIroha" }); // 10
110
+ number.parse("ぬ"); // 23 (default gojuon sequence)
111
+ number.parse("一京點一", { mode: "exactDecimal" }); // "10000000000000000.1"
93
112
  ```
94
113
 
95
114
  ### Formatters
96
115
 
97
- All formatters expose parse(value).
116
+ All formatters expose the following methods:
117
+
118
+ #### `parse(value)`
119
+
120
+ Formats a `number`, `bigint`, or exact decimal `string` into a CJK numeral string.
121
+
122
+ #### Arithmetic methods
123
+
124
+ All numeric formatters (not cyclic/sequence ones) also expose arithmetic methods that accept CJK strings and return a CJK string in the same numeral system:
125
+
126
+ ```js
127
+ tradChineseInformal.add(["一千", "二十三"]); // "一千零二十三"
128
+ tradChineseInformal.subtract(["一京", "一兆"]); // "九千九百九十九兆"
129
+ tradChineseInformal.multiply(["一億", "一億"]); // "一京"
130
+ tradChineseInformal.divide(["五", "二"]); // "二點五"
131
+ tradChineseInformal.modulo("五", "二"); // "一"
132
+ tradChineseInformal.pow("二", "三"); // "八"
133
+ tradChineseInformal.pow("二", 3); // "八" (exponent can be a number)
134
+ tradChineseInformal.abs("負五十"); // "五十"
135
+ tradChineseInformal.compare("三十", "二"); // 1
136
+ ["三十", "二", "十一"].sort(tradChineseInformal.compare); // ["二", "十一", "三十"]
137
+ ```
138
+
139
+ All arithmetic uses a **zero-dependency BigFloat engine**: decimal points are scaled out to `BigInt` before any operation, so results like `"一兆" + "一點五"` are exact with no floating-point drift.
98
140
 
99
141
  Available formatters:
100
142
 
@@ -119,7 +161,7 @@ Examples:
119
161
 
120
162
  ```js
121
163
  tradChineseInformal.parse(-320); // "負三百二十"
122
- simpChineseInformal.parse(12.34); // "十二點三四"
164
+ simpChineseInformal.parse(12.34); // "十二点三四"
123
165
  tradChineseFormal.parse(10n ** 68n); // "壹無量大數"
124
166
  simpChineseFormal.parse(10n ** 64n); // "壹不可思议"
125
167
 
@@ -189,18 +231,19 @@ strict: true validates input characters against an allowed set.
189
231
  Use it when you want to reject unexpected symbols early.
190
232
 
191
233
  ```js
192
- integer.parseInt("一億", { strict: true }); // ok
193
- integer.parseInt("abc", { strict: true }); // throws SyntaxError
234
+ number.parse("一億", { strict: true }); // ok
235
+ number.parse("abc", { strict: true }); // throws SyntaxError
194
236
  ```
195
237
 
196
238
  ## Error Cases
197
239
 
198
240
  Common thrown errors:
199
241
 
200
- - SyntaxError: unsupported/invalid text shape
201
- - RangeError: invalid formatter range in fixed sequence mode
202
- - RangeError: non-integer passed to integer-only paths
203
- - RangeError: decimal parse integer part exceeds Number.MAX_SAFE_INTEGER
242
+ - `SyntaxError`: unsupported or invalid text shape
243
+ - `RangeError`: invalid formatter range in fixed sequence mode
244
+ - `RangeError`: non-integer passed to integer-only paths
245
+ - `RangeError`: decimal parse integer part exceeds `Number.MAX_SAFE_INTEGER` — use `{ mode: "exactDecimal" }` to bypass
246
+ - `RangeError`: division by zero in `divide` or `modulo`
204
247
 
205
248
  ## Development
206
249
 
@@ -0,0 +1,30 @@
1
+ import { DigitSet } from "./types.js";
2
+ export declare const STEMS: readonly ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
3
+ export declare const BRANCHES: readonly ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
4
+ export declare const KOREAN_HANGUL_DIGITS: readonly ["일", "이", "삼", "사", "오", "육", "칠", "팔", "구"];
5
+ export declare const KOREAN_HANJA_FORMAL_DIGITS: readonly ["壹", "貳", "參", "四", "五", "六", "七", "八", "九"];
6
+ export declare const KOREAN_HANJA_INFORMAL_DIGITS: readonly ["一", "二", "三", "四", "五", "六", "七", "八", "九"];
7
+ export declare const JAPANESE_FORMAL_DIGITS: readonly ["壱", "弍", "参", "四", "伍", "六", "七", "八", "九"];
8
+ export declare const JAPANESE_INFORMAL_DIGITS: readonly ["一", "二", "三", "四", "五", "六", "七", "八", "九"];
9
+ export declare const HIRAGANA: readonly ["あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "つ", "て", "と", "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", "ま", "み", "む", "め", "も", "や", "ゆ", "よ", "ら", "り", "る", "れ", "ろ", "わ", "を", "ん"];
10
+ export declare const HIRAGANA_IROHA: readonly ["い", "ろ", "は", "に", "ほ", "へ", "と", "ち", "り", "ぬ", "る", "を", "わ", "か", "よ", "た", "れ", "そ", "つ", "ね", "な", "ら", "む", "う", "ゐ", "の", "お", "く", "や", "ま", "け", "ふ", "こ", "え", "て", "あ", "さ", "き", "ゆ", "め", "み", "し", "ゑ", "ひ", "も", "せ", "す"];
11
+ export declare const KATAKANA: readonly ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン"];
12
+ export declare const KATAKANA_IROHA: readonly ["イ", "ロ", "ハ", "ニ", "ホ", "ヘ", "ト", "チ", "リ", "ヌ", "ル", "ヲ", "ワ", "カ", "ヨ", "タ", "レ", "ソ", "ツ", "ネ", "ナ", "ラ", "ム", "ウ", "ヰ", "ノ", "オ", "ク", "ヤ", "マ", "ケ", "フ", "コ", "エ", "テ", "ア", "サ", "キ", "ユ", "メ", "ミ", "シ", "ヱ", "ヒ", "モ", "セ", "ス"];
13
+ export declare const KOREAN_BIG_UNITS: readonly ["만", "억", "조", "경", "해", "자", "양", "구", "간", "정", "재", "극", "항하사", "아승기", "나유타", "불가사의", "무량대수"];
14
+ export declare const JAPANESE_BIG_UNITS: readonly ["万", "億", "兆", "京", "垓", "秭", "穣", "溝", "澗", "正", "載", "極", "恒河沙", "阿僧祇", "那由他", "不可思議", "無量大数"];
15
+ export declare const SEQUENCE_SYMBOL_TO_NUMBER: Record<string, number>;
16
+ export declare const CANONICAL_DIGITS: Record<string, number>;
17
+ export declare const SMALL_UNITS: Record<string, bigint>;
18
+ export declare const TRAD_BIG_UNITS: readonly ["萬", "億", "兆", "京", "垓", "秭", "穰", "溝", "澗", "正", "載", "極", "恆河沙", "阿僧祇", "那由他", "不可思議", "無量大數"];
19
+ export declare const SIMP_BIG_UNITS: readonly ["万", "亿", "兆", "京", "垓", "秭", "穰", "沟", "涧", "正", "载", "极", "恒河沙", "阿僧祇", "那由他", "不可思议", "无量大数"];
20
+ export declare const TRAD_INFORMAL_SET: DigitSet;
21
+ export declare const TRAD_FORMAL_SET: DigitSet;
22
+ export declare const SIMP_INFORMAL_SET: DigitSet;
23
+ export declare const SIMP_FORMAL_SET: DigitSet;
24
+ export declare const KOREAN_HANGUL_SET: DigitSet;
25
+ export declare const KOREAN_HANJA_FORMAL_SET: DigitSet;
26
+ export declare const KOREAN_HANJA_INFORMAL_SET: DigitSet;
27
+ export declare const JAPANESE_FORMAL_SET: DigitSet;
28
+ export declare const JAPANESE_INFORMAL_SET: DigitSet;
29
+ export declare const BIG_UNIT_ORDER: [string, bigint][];
30
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,eAAO,MAAM,KAAK,6DAWR,CAAC;AACX,eAAO,MAAM,QAAQ,uEAaX,CAAC;AACX,eAAO,MAAM,oBAAoB,wDAUvB,CAAC;AACX,eAAO,MAAM,0BAA0B,wDAU7B,CAAC;AACX,eAAO,MAAM,4BAA4B,wDAU/B,CAAC;AACX,eAAO,MAAM,sBAAsB,wDAUzB,CAAC;AACX,eAAO,MAAM,wBAAwB,wDAU3B,CAAC;AACX,eAAO,MAAM,QAAQ,iPA+CX,CAAC;AACX,eAAO,MAAM,cAAc,sPAgDjB,CAAC;AACX,eAAO,MAAM,QAAQ,iPA+CX,CAAC;AACX,eAAO,MAAM,cAAc,sPAgDjB,CAAC;AAEX,eAAO,MAAM,gBAAgB,4GAkBnB,CAAC;AAEX,eAAO,MAAM,kBAAkB,4GAkBrB,CAAC;AAEX,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmBzD,CAAC;AAEL,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA6BnD,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO9C,CAAC;AAEF,eAAO,MAAM,cAAc,4GAkBjB,CAAC;AAEX,eAAO,MAAM,cAAc,4GAkBjB,CAAC;AAWX,eAAO,MAAM,iBAAiB,EAAE,QAO/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,QAO7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAO/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,QAO7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAO/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,QAOrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,QAOvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,QAOjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,QAOnC,CAAC;AAEF,eAAO,MAAM,cAAc,oBAAqC,CAAC"}
@@ -0,0 +1,485 @@
1
+ export const STEMS = [
2
+ "甲",
3
+ "乙",
4
+ "丙",
5
+ "丁",
6
+ "戊",
7
+ "己",
8
+ "庚",
9
+ "辛",
10
+ "壬",
11
+ "癸",
12
+ ];
13
+ export const BRANCHES = [
14
+ "子",
15
+ "丑",
16
+ "寅",
17
+ "卯",
18
+ "辰",
19
+ "巳",
20
+ "午",
21
+ "未",
22
+ "申",
23
+ "酉",
24
+ "戌",
25
+ "亥",
26
+ ];
27
+ export const KOREAN_HANGUL_DIGITS = [
28
+ "일",
29
+ "이",
30
+ "삼",
31
+ "사",
32
+ "오",
33
+ "육",
34
+ "칠",
35
+ "팔",
36
+ "구",
37
+ ];
38
+ export const KOREAN_HANJA_FORMAL_DIGITS = [
39
+ "壹",
40
+ "貳",
41
+ "參",
42
+ "四",
43
+ "五",
44
+ "六",
45
+ "七",
46
+ "八",
47
+ "九",
48
+ ];
49
+ export const KOREAN_HANJA_INFORMAL_DIGITS = [
50
+ "一",
51
+ "二",
52
+ "三",
53
+ "四",
54
+ "五",
55
+ "六",
56
+ "七",
57
+ "八",
58
+ "九",
59
+ ];
60
+ export const JAPANESE_FORMAL_DIGITS = [
61
+ "壱",
62
+ "弍",
63
+ "参",
64
+ "四",
65
+ "伍",
66
+ "六",
67
+ "七",
68
+ "八",
69
+ "九",
70
+ ];
71
+ export const JAPANESE_INFORMAL_DIGITS = [
72
+ "一",
73
+ "二",
74
+ "三",
75
+ "四",
76
+ "五",
77
+ "六",
78
+ "七",
79
+ "八",
80
+ "九",
81
+ ];
82
+ export const HIRAGANA = [
83
+ "あ",
84
+ "い",
85
+ "う",
86
+ "え",
87
+ "お",
88
+ "か",
89
+ "き",
90
+ "く",
91
+ "け",
92
+ "こ",
93
+ "さ",
94
+ "し",
95
+ "す",
96
+ "せ",
97
+ "そ",
98
+ "た",
99
+ "ち",
100
+ "つ",
101
+ "て",
102
+ "と",
103
+ "な",
104
+ "に",
105
+ "ぬ",
106
+ "ね",
107
+ "の",
108
+ "は",
109
+ "ひ",
110
+ "ふ",
111
+ "へ",
112
+ "ほ",
113
+ "ま",
114
+ "み",
115
+ "む",
116
+ "め",
117
+ "も",
118
+ "や",
119
+ "ゆ",
120
+ "よ",
121
+ "ら",
122
+ "り",
123
+ "る",
124
+ "れ",
125
+ "ろ",
126
+ "わ",
127
+ "を",
128
+ "ん",
129
+ ];
130
+ export const HIRAGANA_IROHA = [
131
+ "い",
132
+ "ろ",
133
+ "は",
134
+ "に",
135
+ "ほ",
136
+ "へ",
137
+ "と",
138
+ "ち",
139
+ "り",
140
+ "ぬ",
141
+ "る",
142
+ "を",
143
+ "わ",
144
+ "か",
145
+ "よ",
146
+ "た",
147
+ "れ",
148
+ "そ",
149
+ "つ",
150
+ "ね",
151
+ "な",
152
+ "ら",
153
+ "む",
154
+ "う",
155
+ "ゐ",
156
+ "の",
157
+ "お",
158
+ "く",
159
+ "や",
160
+ "ま",
161
+ "け",
162
+ "ふ",
163
+ "こ",
164
+ "え",
165
+ "て",
166
+ "あ",
167
+ "さ",
168
+ "き",
169
+ "ゆ",
170
+ "め",
171
+ "み",
172
+ "し",
173
+ "ゑ",
174
+ "ひ",
175
+ "も",
176
+ "せ",
177
+ "す",
178
+ ];
179
+ export const KATAKANA = [
180
+ "ア",
181
+ "イ",
182
+ "ウ",
183
+ "エ",
184
+ "オ",
185
+ "カ",
186
+ "キ",
187
+ "ク",
188
+ "ケ",
189
+ "コ",
190
+ "サ",
191
+ "シ",
192
+ "ス",
193
+ "セ",
194
+ "ソ",
195
+ "タ",
196
+ "チ",
197
+ "ツ",
198
+ "テ",
199
+ "ト",
200
+ "ナ",
201
+ "ニ",
202
+ "ヌ",
203
+ "ネ",
204
+ "ノ",
205
+ "ハ",
206
+ "ヒ",
207
+ "フ",
208
+ "ヘ",
209
+ "ホ",
210
+ "マ",
211
+ "ミ",
212
+ "ム",
213
+ "メ",
214
+ "モ",
215
+ "ヤ",
216
+ "ユ",
217
+ "ヨ",
218
+ "ラ",
219
+ "リ",
220
+ "ル",
221
+ "レ",
222
+ "ロ",
223
+ "ワ",
224
+ "ヲ",
225
+ "ン",
226
+ ];
227
+ export const KATAKANA_IROHA = [
228
+ "イ",
229
+ "ロ",
230
+ "ハ",
231
+ "ニ",
232
+ "ホ",
233
+ "ヘ",
234
+ "ト",
235
+ "チ",
236
+ "リ",
237
+ "ヌ",
238
+ "ル",
239
+ "ヲ",
240
+ "ワ",
241
+ "カ",
242
+ "ヨ",
243
+ "タ",
244
+ "レ",
245
+ "ソ",
246
+ "ツ",
247
+ "ネ",
248
+ "ナ",
249
+ "ラ",
250
+ "ム",
251
+ "ウ",
252
+ "ヰ",
253
+ "ノ",
254
+ "オ",
255
+ "ク",
256
+ "ヤ",
257
+ "マ",
258
+ "ケ",
259
+ "フ",
260
+ "コ",
261
+ "エ",
262
+ "テ",
263
+ "ア",
264
+ "サ",
265
+ "キ",
266
+ "ユ",
267
+ "メ",
268
+ "ミ",
269
+ "シ",
270
+ "ヱ",
271
+ "ヒ",
272
+ "モ",
273
+ "セ",
274
+ "ス",
275
+ ];
276
+ export const KOREAN_BIG_UNITS = [
277
+ "만",
278
+ "억",
279
+ "조",
280
+ "경",
281
+ "해",
282
+ "자",
283
+ "양",
284
+ "구",
285
+ "간",
286
+ "정",
287
+ "재",
288
+ "극",
289
+ "항하사",
290
+ "아승기",
291
+ "나유타",
292
+ "불가사의",
293
+ "무량대수",
294
+ ];
295
+ export const JAPANESE_BIG_UNITS = [
296
+ "万",
297
+ "億",
298
+ "兆",
299
+ "京",
300
+ "垓",
301
+ "秭",
302
+ "穣",
303
+ "溝",
304
+ "澗",
305
+ "正",
306
+ "載",
307
+ "極",
308
+ "恒河沙",
309
+ "阿僧祇",
310
+ "那由他",
311
+ "不可思議",
312
+ "無量大数",
313
+ ];
314
+ export const SEQUENCE_SYMBOL_TO_NUMBER = (() => {
315
+ const map = {};
316
+ const put = (chars) => {
317
+ chars.forEach((char, index) => {
318
+ // Prioritize the first mapping we encounter (e.g. Gojuon over Iroha)
319
+ if (map[char] === undefined) {
320
+ map[char] = index + 1;
321
+ }
322
+ });
323
+ };
324
+ put(STEMS);
325
+ put(BRANCHES);
326
+ put(HIRAGANA);
327
+ put(HIRAGANA_IROHA);
328
+ put(KATAKANA);
329
+ put(KATAKANA_IROHA);
330
+ return map;
331
+ })();
332
+ export const CANONICAL_DIGITS = {
333
+ 零: 0,
334
+ 영: 0,
335
+ 령: 0,
336
+ 〇: 0,
337
+ "○": 0,
338
+ 一: 1,
339
+ 壹: 1,
340
+ 二: 2,
341
+ 貳: 2,
342
+ 贰: 2,
343
+ 兩: 2,
344
+ 两: 2,
345
+ 三: 3,
346
+ 參: 3,
347
+ 叁: 3,
348
+ 四: 4,
349
+ 肆: 4,
350
+ 五: 5,
351
+ 伍: 5,
352
+ 六: 6,
353
+ 陸: 6,
354
+ 陆: 6,
355
+ 七: 7,
356
+ 柒: 7,
357
+ 八: 8,
358
+ 捌: 8,
359
+ 九: 9,
360
+ 玖: 9,
361
+ };
362
+ export const SMALL_UNITS = {
363
+ 十: 10n,
364
+ 拾: 10n,
365
+ 百: 100n,
366
+ 佰: 100n,
367
+ 千: 1000n,
368
+ 仟: 1000n,
369
+ };
370
+ export const TRAD_BIG_UNITS = [
371
+ "萬",
372
+ "億",
373
+ "兆",
374
+ "京",
375
+ "垓",
376
+ "秭",
377
+ "穰",
378
+ "溝",
379
+ "澗",
380
+ "正",
381
+ "載",
382
+ "極",
383
+ "恆河沙",
384
+ "阿僧祇",
385
+ "那由他",
386
+ "不可思議",
387
+ "無量大數",
388
+ ];
389
+ export const SIMP_BIG_UNITS = [
390
+ "万",
391
+ "亿",
392
+ "兆",
393
+ "京",
394
+ "垓",
395
+ "秭",
396
+ "穰",
397
+ "沟",
398
+ "涧",
399
+ "正",
400
+ "载",
401
+ "极",
402
+ "恒河沙",
403
+ "阿僧祇",
404
+ "那由他",
405
+ "不可思议",
406
+ "无量大数",
407
+ ];
408
+ function createBigUnitOrder(units) {
409
+ return units
410
+ .map((unit, index) => [unit, 10n ** BigInt((index + 1) * 4)])
411
+ .reverse();
412
+ }
413
+ export const TRAD_INFORMAL_SET = {
414
+ zero: "零",
415
+ point: "點",
416
+ digits: ["一", "二", "三", "四", "五", "六", "七", "八", "九"],
417
+ smallUnits: ["十", "百", "千"],
418
+ bigUnits: [...TRAD_BIG_UNITS],
419
+ dropTenOne: true,
420
+ };
421
+ export const TRAD_FORMAL_SET = {
422
+ zero: "零",
423
+ point: "點",
424
+ digits: ["壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖"],
425
+ smallUnits: ["拾", "佰", "仟"],
426
+ bigUnits: [...TRAD_BIG_UNITS],
427
+ dropTenOne: false,
428
+ };
429
+ export const SIMP_INFORMAL_SET = {
430
+ zero: "零",
431
+ point: "点",
432
+ digits: ["一", "二", "三", "四", "五", "六", "七", "八", "九"],
433
+ smallUnits: ["十", "百", "千"],
434
+ bigUnits: [...SIMP_BIG_UNITS],
435
+ dropTenOne: true,
436
+ };
437
+ export const SIMP_FORMAL_SET = {
438
+ zero: "零",
439
+ point: "点",
440
+ digits: ["壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"],
441
+ smallUnits: ["拾", "佰", "仟"],
442
+ bigUnits: [...SIMP_BIG_UNITS],
443
+ dropTenOne: false,
444
+ };
445
+ export const KOREAN_HANGUL_SET = {
446
+ zero: "영",
447
+ point: "점",
448
+ digits: [...KOREAN_HANGUL_DIGITS],
449
+ smallUnits: ["십", "백", "천"],
450
+ bigUnits: [...KOREAN_BIG_UNITS],
451
+ dropTenOne: false,
452
+ };
453
+ export const KOREAN_HANJA_FORMAL_SET = {
454
+ zero: "零",
455
+ point: "점",
456
+ digits: [...KOREAN_HANJA_FORMAL_DIGITS],
457
+ smallUnits: ["拾", "佰", "仟"],
458
+ bigUnits: [...TRAD_BIG_UNITS],
459
+ dropTenOne: false,
460
+ };
461
+ export const KOREAN_HANJA_INFORMAL_SET = {
462
+ zero: "零",
463
+ point: "점",
464
+ digits: [...KOREAN_HANJA_INFORMAL_DIGITS],
465
+ smallUnits: ["十", "百", "千"],
466
+ bigUnits: [...TRAD_BIG_UNITS],
467
+ dropTenOne: true,
468
+ };
469
+ export const JAPANESE_FORMAL_SET = {
470
+ zero: "零",
471
+ point: "点",
472
+ digits: [...JAPANESE_FORMAL_DIGITS],
473
+ smallUnits: ["拾", "百", "千"],
474
+ bigUnits: [...JAPANESE_BIG_UNITS],
475
+ dropTenOne: false,
476
+ };
477
+ export const JAPANESE_INFORMAL_SET = {
478
+ zero: "零",
479
+ point: "点",
480
+ digits: [...JAPANESE_INFORMAL_DIGITS],
481
+ smallUnits: ["十", "百", "千"],
482
+ bigUnits: [...JAPANESE_BIG_UNITS],
483
+ dropTenOne: true,
484
+ };
485
+ export const BIG_UNIT_ORDER = createBigUnitOrder(SIMP_BIG_UNITS);