cjk-number 0.4.0 → 0.4.2
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 +22 -3
- package/dist/constants.d.ts +21 -17
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +41 -364
- package/dist/index.d.ts +185 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +137 -104
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ npm install cjk-number
|
|
|
26
26
|
|
|
27
27
|
```js
|
|
28
28
|
import {
|
|
29
|
-
|
|
29
|
+
number,
|
|
30
30
|
cjkIdeographic,
|
|
31
31
|
tradChineseInformal,
|
|
32
32
|
tradChineseFormal,
|
|
@@ -85,8 +85,6 @@ Options:
|
|
|
85
85
|
|---|---|---|---|
|
|
86
86
|
| `mode` | `"number" \| "preferBigInt" \| "exactDecimal"` | `"number"` | Controls the output numeric type |
|
|
87
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
88
|
| `explicitTyping` | `ExplicitTyping` | `undefined` | Forces a specific CJK system for parsing |
|
|
91
89
|
|
|
92
90
|
**`mode` values:**
|
|
@@ -138,6 +136,7 @@ tradChineseInformal.compare("三十", "二"); // 1
|
|
|
138
136
|
|
|
139
137
|
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.
|
|
140
138
|
|
|
139
|
+
|
|
141
140
|
Available formatters:
|
|
142
141
|
|
|
143
142
|
- cjkIdeographic
|
|
@@ -157,6 +156,26 @@ Available formatters:
|
|
|
157
156
|
- katakana
|
|
158
157
|
- katakanaIroha
|
|
159
158
|
|
|
159
|
+
#### Sequence system methods
|
|
160
|
+
|
|
161
|
+
All sequence systems (stems, branches, and kana) also expose methods for traversing and decoding the sequence:
|
|
162
|
+
|
|
163
|
+
- `decode(symbol)`: Returns the 1-indexed numeric value of a symbol in the specific sequence.
|
|
164
|
+
- `next(symbol, count?)`: Returns the next symbol in the sequence (cyclic).
|
|
165
|
+
- `prev(symbol, count?)`: Returns the previous symbol in the sequence (cyclic).
|
|
166
|
+
- `range(start, end)`: Returns an array of symbols from `start` to `end` (inclusive).
|
|
167
|
+
|
|
168
|
+
Example:
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
hiraganaIroha.decode("ぬ"); // 10
|
|
172
|
+
hiragana.decode("ぬ"); // 23 (gojuon)
|
|
173
|
+
|
|
174
|
+
cjkHeavenlyStem.next("癸"); // "甲"
|
|
175
|
+
cjkEarthlyBranch.prev("子", 2); // "戌"
|
|
176
|
+
hiraganaIroha.range("ゑ", "す"); // ["ゑ", "ひ", "も", "せ", "す"]
|
|
177
|
+
```
|
|
178
|
+
|
|
160
179
|
Examples:
|
|
161
180
|
|
|
162
181
|
```js
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
import { DigitSet } from "./types.js";
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const
|
|
1
|
+
import { DigitArray9, DigitSet } from "./types.js";
|
|
2
|
+
export declare const TRAD_INFORMAL_DIGITS: DigitArray9;
|
|
3
|
+
export declare const SIMP_INFORMAL_DIGITS: DigitArray9;
|
|
4
|
+
export declare const TRAD_FORMAL_DIGITS: DigitArray9;
|
|
5
|
+
export declare const SIMP_FORMAL_DIGITS: DigitArray9;
|
|
6
|
+
export declare const KOREAN_HANGUL_DIGITS: DigitArray9;
|
|
7
|
+
export declare const KOREAN_HANJA_FORMAL_DIGITS: DigitArray9;
|
|
8
|
+
export declare const KOREAN_HANJA_INFORMAL_DIGITS: DigitArray9;
|
|
9
|
+
export declare const JAPANESE_FORMAL_DIGITS: DigitArray9;
|
|
10
|
+
export declare const JAPANESE_INFORMAL_DIGITS: DigitArray9;
|
|
11
|
+
export declare const STEMS: string[];
|
|
12
|
+
export declare const BRANCHES: string[];
|
|
13
|
+
export declare const HIRAGANA: string[];
|
|
14
|
+
export declare const HIRAGANA_IROHA: string[];
|
|
15
|
+
export declare const KATAKANA: string[];
|
|
16
|
+
export declare const KATAKANA_IROHA: string[];
|
|
17
|
+
export declare const KOREAN_BIG_UNITS: string[];
|
|
18
|
+
export declare const JAPANESE_BIG_UNITS: string[];
|
|
19
|
+
export declare const TRAD_BIG_UNITS: string[];
|
|
20
|
+
export declare const SIMP_BIG_UNITS: string[];
|
|
21
|
+
export declare function getSequenceMap(): Record<string, number>;
|
|
16
22
|
export declare const CANONICAL_DIGITS: Record<string, number>;
|
|
17
23
|
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
24
|
export declare const TRAD_INFORMAL_SET: DigitSet;
|
|
21
25
|
export declare const TRAD_FORMAL_SET: DigitSet;
|
|
22
26
|
export declare const SIMP_INFORMAL_SET: DigitSet;
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AASnD,eAAO,MAAM,oBAAoB,aAA6B,CAAC;AAC/D,eAAO,MAAM,oBAAoB,aAA6B,CAAC;AAC/D,eAAO,MAAM,kBAAkB,aAA6B,CAAC;AAC7D,eAAO,MAAM,kBAAkB,aAA6B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,aAA6B,CAAC;AAC/D,eAAO,MAAM,0BAA0B,aAA6B,CAAC;AACrE,eAAO,MAAM,4BAA4B,aAA6B,CAAC;AACvE,eAAO,MAAM,sBAAsB,aAA6B,CAAC;AACjE,eAAO,MAAM,wBAAwB,aAA6B,CAAC;AAEnE,eAAO,MAAM,KAAK,UAA2B,CAAC;AAC9C,eAAO,MAAM,QAAQ,UAA6B,CAAC;AACnD,eAAO,MAAM,QAAQ,UAA6D,CAAC;AACnF,eAAO,MAAM,cAAc,UAA8D,CAAC;AAC1F,eAAO,MAAM,QAAQ,UAA6D,CAAC;AACnF,eAAO,MAAM,cAAc,UAA8D,CAAC;AAC1F,eAAO,MAAM,gBAAgB,UAA6D,CAAC;AAC3F,eAAO,MAAM,kBAAkB,UAA6D,CAAC;AAC7F,eAAO,MAAM,cAAc,UAA6D,CAAC;AACzF,eAAO,MAAM,cAAc,UAA6D,CAAC;AAGzF,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBvD;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA6BnD,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO9C,CAAC;AAWF,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"}
|
package/dist/constants.js
CHANGED
|
@@ -1,321 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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 = (() => {
|
|
1
|
+
function toDigitArray9(str) {
|
|
2
|
+
const chars = str.split("");
|
|
3
|
+
if (chars.length !== 9) {
|
|
4
|
+
throw new Error(`Invalid digit string length: expected 9, got ${chars.length}`);
|
|
5
|
+
}
|
|
6
|
+
return chars;
|
|
7
|
+
}
|
|
8
|
+
export const TRAD_INFORMAL_DIGITS = toDigitArray9("一二三四五六七八九");
|
|
9
|
+
export const SIMP_INFORMAL_DIGITS = toDigitArray9("一二三四五六七八九");
|
|
10
|
+
export const TRAD_FORMAL_DIGITS = toDigitArray9("壹貳參肆伍陸柒捌玖");
|
|
11
|
+
export const SIMP_FORMAL_DIGITS = toDigitArray9("壹贰叁肆伍陆柒捌玖");
|
|
12
|
+
export const KOREAN_HANGUL_DIGITS = toDigitArray9("일이삼사오육칠팔구");
|
|
13
|
+
export const KOREAN_HANJA_FORMAL_DIGITS = toDigitArray9("壹貳參四五六七八九");
|
|
14
|
+
export const KOREAN_HANJA_INFORMAL_DIGITS = toDigitArray9("一二三四五六七八九");
|
|
15
|
+
export const JAPANESE_FORMAL_DIGITS = toDigitArray9("壱弍参四伍六七八九");
|
|
16
|
+
export const JAPANESE_INFORMAL_DIGITS = toDigitArray9("一二三四五六七八九");
|
|
17
|
+
export const STEMS = ("甲乙丙丁戊己庚辛壬癸").split("");
|
|
18
|
+
export const BRANCHES = ("子丑寅卯辰巳午未申酉戌亥").split("");
|
|
19
|
+
export const HIRAGANA = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん".split("");
|
|
20
|
+
export const HIRAGANA_IROHA = "いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす".split("");
|
|
21
|
+
export const KATAKANA = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン".split("");
|
|
22
|
+
export const KATAKANA_IROHA = "イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス".split("");
|
|
23
|
+
export const KOREAN_BIG_UNITS = "만,억,조,경,해,자,양,구,간,정,재,극,항하사,아승기,나유타,불가사의,무량대수".split(",");
|
|
24
|
+
export const JAPANESE_BIG_UNITS = "万,億,兆,京,垓,秭,穣,溝,澗,正,載,極,恒河沙,阿僧祇,那由他,不可思議,無量大数".split(",");
|
|
25
|
+
export const TRAD_BIG_UNITS = "萬,億,兆,京,垓,秭,穰,溝,澗,正,載,極,恆河沙,阿僧祇,那由他,不可思議,無量大數".split(",");
|
|
26
|
+
export const SIMP_BIG_UNITS = "万,亿,兆,京,垓,秭,穰,沟,涧,正,载,极,恒河沙,阿僧祇,那由他,不可思议,无量大数".split(",");
|
|
27
|
+
let cachedMap;
|
|
28
|
+
export function getSequenceMap() {
|
|
29
|
+
if (cachedMap)
|
|
30
|
+
return cachedMap;
|
|
315
31
|
const map = {};
|
|
316
32
|
const put = (chars) => {
|
|
317
33
|
chars.forEach((char, index) => {
|
|
318
|
-
// Prioritize the first mapping we encounter (e.g. Gojuon over Iroha)
|
|
319
34
|
if (map[char] === undefined) {
|
|
320
35
|
map[char] = index + 1;
|
|
321
36
|
}
|
|
@@ -327,8 +42,8 @@ export const SEQUENCE_SYMBOL_TO_NUMBER = (() => {
|
|
|
327
42
|
put(HIRAGANA_IROHA);
|
|
328
43
|
put(KATAKANA);
|
|
329
44
|
put(KATAKANA_IROHA);
|
|
330
|
-
return map;
|
|
331
|
-
}
|
|
45
|
+
return (cachedMap = map);
|
|
46
|
+
}
|
|
332
47
|
export const CANONICAL_DIGITS = {
|
|
333
48
|
零: 0,
|
|
334
49
|
영: 0,
|
|
@@ -367,44 +82,6 @@ export const SMALL_UNITS = {
|
|
|
367
82
|
千: 1000n,
|
|
368
83
|
仟: 1000n,
|
|
369
84
|
};
|
|
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
85
|
function createBigUnitOrder(units) {
|
|
409
86
|
return units
|
|
410
87
|
.map((unit, index) => [unit, 10n ** BigInt((index + 1) * 4)])
|
|
@@ -413,7 +90,7 @@ function createBigUnitOrder(units) {
|
|
|
413
90
|
export const TRAD_INFORMAL_SET = {
|
|
414
91
|
zero: "零",
|
|
415
92
|
point: "點",
|
|
416
|
-
digits:
|
|
93
|
+
digits: TRAD_INFORMAL_DIGITS,
|
|
417
94
|
smallUnits: ["十", "百", "千"],
|
|
418
95
|
bigUnits: [...TRAD_BIG_UNITS],
|
|
419
96
|
dropTenOne: true,
|
|
@@ -421,7 +98,7 @@ export const TRAD_INFORMAL_SET = {
|
|
|
421
98
|
export const TRAD_FORMAL_SET = {
|
|
422
99
|
zero: "零",
|
|
423
100
|
point: "點",
|
|
424
|
-
digits:
|
|
101
|
+
digits: TRAD_FORMAL_DIGITS,
|
|
425
102
|
smallUnits: ["拾", "佰", "仟"],
|
|
426
103
|
bigUnits: [...TRAD_BIG_UNITS],
|
|
427
104
|
dropTenOne: false,
|
|
@@ -429,7 +106,7 @@ export const TRAD_FORMAL_SET = {
|
|
|
429
106
|
export const SIMP_INFORMAL_SET = {
|
|
430
107
|
zero: "零",
|
|
431
108
|
point: "点",
|
|
432
|
-
digits:
|
|
109
|
+
digits: SIMP_INFORMAL_DIGITS,
|
|
433
110
|
smallUnits: ["十", "百", "千"],
|
|
434
111
|
bigUnits: [...SIMP_BIG_UNITS],
|
|
435
112
|
dropTenOne: true,
|
|
@@ -437,7 +114,7 @@ export const SIMP_INFORMAL_SET = {
|
|
|
437
114
|
export const SIMP_FORMAL_SET = {
|
|
438
115
|
zero: "零",
|
|
439
116
|
point: "点",
|
|
440
|
-
digits:
|
|
117
|
+
digits: SIMP_FORMAL_DIGITS,
|
|
441
118
|
smallUnits: ["拾", "佰", "仟"],
|
|
442
119
|
bigUnits: [...SIMP_BIG_UNITS],
|
|
443
120
|
dropTenOne: false,
|
|
@@ -445,7 +122,7 @@ export const SIMP_FORMAL_SET = {
|
|
|
445
122
|
export const KOREAN_HANGUL_SET = {
|
|
446
123
|
zero: "영",
|
|
447
124
|
point: "점",
|
|
448
|
-
digits:
|
|
125
|
+
digits: KOREAN_HANGUL_DIGITS,
|
|
449
126
|
smallUnits: ["십", "백", "천"],
|
|
450
127
|
bigUnits: [...KOREAN_BIG_UNITS],
|
|
451
128
|
dropTenOne: false,
|
|
@@ -453,7 +130,7 @@ export const KOREAN_HANGUL_SET = {
|
|
|
453
130
|
export const KOREAN_HANJA_FORMAL_SET = {
|
|
454
131
|
zero: "零",
|
|
455
132
|
point: "점",
|
|
456
|
-
digits:
|
|
133
|
+
digits: KOREAN_HANJA_FORMAL_DIGITS,
|
|
457
134
|
smallUnits: ["拾", "佰", "仟"],
|
|
458
135
|
bigUnits: [...TRAD_BIG_UNITS],
|
|
459
136
|
dropTenOne: false,
|
|
@@ -461,7 +138,7 @@ export const KOREAN_HANJA_FORMAL_SET = {
|
|
|
461
138
|
export const KOREAN_HANJA_INFORMAL_SET = {
|
|
462
139
|
zero: "零",
|
|
463
140
|
point: "점",
|
|
464
|
-
digits:
|
|
141
|
+
digits: KOREAN_HANJA_INFORMAL_DIGITS,
|
|
465
142
|
smallUnits: ["十", "百", "千"],
|
|
466
143
|
bigUnits: [...TRAD_BIG_UNITS],
|
|
467
144
|
dropTenOne: true,
|
|
@@ -469,7 +146,7 @@ export const KOREAN_HANJA_INFORMAL_SET = {
|
|
|
469
146
|
export const JAPANESE_FORMAL_SET = {
|
|
470
147
|
zero: "零",
|
|
471
148
|
point: "点",
|
|
472
|
-
digits:
|
|
149
|
+
digits: JAPANESE_FORMAL_DIGITS,
|
|
473
150
|
smallUnits: ["拾", "百", "千"],
|
|
474
151
|
bigUnits: [...JAPANESE_BIG_UNITS],
|
|
475
152
|
dropTenOne: false,
|
|
@@ -477,7 +154,7 @@ export const JAPANESE_FORMAL_SET = {
|
|
|
477
154
|
export const JAPANESE_INFORMAL_SET = {
|
|
478
155
|
zero: "零",
|
|
479
156
|
point: "点",
|
|
480
|
-
digits:
|
|
157
|
+
digits: JAPANESE_INFORMAL_DIGITS,
|
|
481
158
|
smallUnits: ["十", "百", "千"],
|
|
482
159
|
bigUnits: [...JAPANESE_BIG_UNITS],
|
|
483
160
|
dropTenOne: true,
|
package/dist/index.d.ts
CHANGED
|
@@ -521,6 +521,35 @@ export declare const cjkHeavenlyStem: {
|
|
|
521
521
|
* @returns The character mapped to the specific sequence position.
|
|
522
522
|
*/
|
|
523
523
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
524
|
+
/**
|
|
525
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
526
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
527
|
+
* @param symbol The sequence symbol to decode.
|
|
528
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
529
|
+
*/
|
|
530
|
+
decode(symbol: string): number;
|
|
531
|
+
/**
|
|
532
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
533
|
+
* @param symbol The starting symbol.
|
|
534
|
+
* @param step The number of positions to move forward.
|
|
535
|
+
* @returns The resulting sequence character.
|
|
536
|
+
*/
|
|
537
|
+
next(symbol: string, step?: number | bigint): string;
|
|
538
|
+
/**
|
|
539
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
540
|
+
* @param symbol The starting symbol.
|
|
541
|
+
* @param step The number of positions to move backward.
|
|
542
|
+
* @returns The resulting sequence character.
|
|
543
|
+
*/
|
|
544
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
545
|
+
/**
|
|
546
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
547
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
548
|
+
* @param start The starting symbol.
|
|
549
|
+
* @param end The ending symbol.
|
|
550
|
+
* @returns A list of symbols in the sequence.
|
|
551
|
+
*/
|
|
552
|
+
range(start: string, end: string): string[];
|
|
524
553
|
};
|
|
525
554
|
export declare const cjkEarthlyBranch: {
|
|
526
555
|
/**
|
|
@@ -531,6 +560,35 @@ export declare const cjkEarthlyBranch: {
|
|
|
531
560
|
* @returns The character mapped to the specific sequence position.
|
|
532
561
|
*/
|
|
533
562
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
563
|
+
/**
|
|
564
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
565
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
566
|
+
* @param symbol The sequence symbol to decode.
|
|
567
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
568
|
+
*/
|
|
569
|
+
decode(symbol: string): number;
|
|
570
|
+
/**
|
|
571
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
572
|
+
* @param symbol The starting symbol.
|
|
573
|
+
* @param step The number of positions to move forward.
|
|
574
|
+
* @returns The resulting sequence character.
|
|
575
|
+
*/
|
|
576
|
+
next(symbol: string, step?: number | bigint): string;
|
|
577
|
+
/**
|
|
578
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
579
|
+
* @param symbol The starting symbol.
|
|
580
|
+
* @param step The number of positions to move backward.
|
|
581
|
+
* @returns The resulting sequence character.
|
|
582
|
+
*/
|
|
583
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
584
|
+
/**
|
|
585
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
586
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
587
|
+
* @param start The starting symbol.
|
|
588
|
+
* @param end The ending symbol.
|
|
589
|
+
* @returns A list of symbols in the sequence.
|
|
590
|
+
*/
|
|
591
|
+
range(start: string, end: string): string[];
|
|
534
592
|
};
|
|
535
593
|
export declare const hiragana: {
|
|
536
594
|
/**
|
|
@@ -541,6 +599,35 @@ export declare const hiragana: {
|
|
|
541
599
|
* @returns The character mapped to the specific sequence position.
|
|
542
600
|
*/
|
|
543
601
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
602
|
+
/**
|
|
603
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
604
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
605
|
+
* @param symbol The sequence symbol to decode.
|
|
606
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
607
|
+
*/
|
|
608
|
+
decode(symbol: string): number;
|
|
609
|
+
/**
|
|
610
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
611
|
+
* @param symbol The starting symbol.
|
|
612
|
+
* @param step The number of positions to move forward.
|
|
613
|
+
* @returns The resulting sequence character.
|
|
614
|
+
*/
|
|
615
|
+
next(symbol: string, step?: number | bigint): string;
|
|
616
|
+
/**
|
|
617
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
618
|
+
* @param symbol The starting symbol.
|
|
619
|
+
* @param step The number of positions to move backward.
|
|
620
|
+
* @returns The resulting sequence character.
|
|
621
|
+
*/
|
|
622
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
623
|
+
/**
|
|
624
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
625
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
626
|
+
* @param start The starting symbol.
|
|
627
|
+
* @param end The ending symbol.
|
|
628
|
+
* @returns A list of symbols in the sequence.
|
|
629
|
+
*/
|
|
630
|
+
range(start: string, end: string): string[];
|
|
544
631
|
};
|
|
545
632
|
export declare const hiraganaIroha: {
|
|
546
633
|
/**
|
|
@@ -551,6 +638,35 @@ export declare const hiraganaIroha: {
|
|
|
551
638
|
* @returns The character mapped to the specific sequence position.
|
|
552
639
|
*/
|
|
553
640
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
641
|
+
/**
|
|
642
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
643
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
644
|
+
* @param symbol The sequence symbol to decode.
|
|
645
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
646
|
+
*/
|
|
647
|
+
decode(symbol: string): number;
|
|
648
|
+
/**
|
|
649
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
650
|
+
* @param symbol The starting symbol.
|
|
651
|
+
* @param step The number of positions to move forward.
|
|
652
|
+
* @returns The resulting sequence character.
|
|
653
|
+
*/
|
|
654
|
+
next(symbol: string, step?: number | bigint): string;
|
|
655
|
+
/**
|
|
656
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
657
|
+
* @param symbol The starting symbol.
|
|
658
|
+
* @param step The number of positions to move backward.
|
|
659
|
+
* @returns The resulting sequence character.
|
|
660
|
+
*/
|
|
661
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
662
|
+
/**
|
|
663
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
664
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
665
|
+
* @param start The starting symbol.
|
|
666
|
+
* @param end The ending symbol.
|
|
667
|
+
* @returns A list of symbols in the sequence.
|
|
668
|
+
*/
|
|
669
|
+
range(start: string, end: string): string[];
|
|
554
670
|
};
|
|
555
671
|
export declare const katakana: {
|
|
556
672
|
/**
|
|
@@ -561,6 +677,35 @@ export declare const katakana: {
|
|
|
561
677
|
* @returns The character mapped to the specific sequence position.
|
|
562
678
|
*/
|
|
563
679
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
680
|
+
/**
|
|
681
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
682
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
683
|
+
* @param symbol The sequence symbol to decode.
|
|
684
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
685
|
+
*/
|
|
686
|
+
decode(symbol: string): number;
|
|
687
|
+
/**
|
|
688
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
689
|
+
* @param symbol The starting symbol.
|
|
690
|
+
* @param step The number of positions to move forward.
|
|
691
|
+
* @returns The resulting sequence character.
|
|
692
|
+
*/
|
|
693
|
+
next(symbol: string, step?: number | bigint): string;
|
|
694
|
+
/**
|
|
695
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
696
|
+
* @param symbol The starting symbol.
|
|
697
|
+
* @param step The number of positions to move backward.
|
|
698
|
+
* @returns The resulting sequence character.
|
|
699
|
+
*/
|
|
700
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
701
|
+
/**
|
|
702
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
703
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
704
|
+
* @param start The starting symbol.
|
|
705
|
+
* @param end The ending symbol.
|
|
706
|
+
* @returns A list of symbols in the sequence.
|
|
707
|
+
*/
|
|
708
|
+
range(start: string, end: string): string[];
|
|
564
709
|
};
|
|
565
710
|
export declare const katakanaIroha: {
|
|
566
711
|
/**
|
|
@@ -571,18 +716,47 @@ export declare const katakanaIroha: {
|
|
|
571
716
|
* @returns The character mapped to the specific sequence position.
|
|
572
717
|
*/
|
|
573
718
|
parse(value: NumberLike, options?: SystemParseOptions): string;
|
|
719
|
+
/**
|
|
720
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
721
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
722
|
+
* @param symbol The sequence symbol to decode.
|
|
723
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
724
|
+
*/
|
|
725
|
+
decode(symbol: string): number;
|
|
726
|
+
/**
|
|
727
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
728
|
+
* @param symbol The starting symbol.
|
|
729
|
+
* @param step The number of positions to move forward.
|
|
730
|
+
* @returns The resulting sequence character.
|
|
731
|
+
*/
|
|
732
|
+
next(symbol: string, step?: number | bigint): string;
|
|
733
|
+
/**
|
|
734
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
735
|
+
* @param symbol The starting symbol.
|
|
736
|
+
* @param step The number of positions to move backward.
|
|
737
|
+
* @returns The resulting sequence character.
|
|
738
|
+
*/
|
|
739
|
+
prev(symbol: string, step?: number | bigint): string;
|
|
740
|
+
/**
|
|
741
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
742
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
743
|
+
* @param start The starting symbol.
|
|
744
|
+
* @param end The ending symbol.
|
|
745
|
+
* @returns A list of symbols in the sequence.
|
|
746
|
+
*/
|
|
747
|
+
range(start: string, end: string): string[];
|
|
574
748
|
};
|
|
575
749
|
export declare const systems: {
|
|
576
|
-
heavenlyStem:
|
|
577
|
-
earthlyBranch:
|
|
578
|
-
koreanHangulFormal:
|
|
579
|
-
koreanHanjaFormal:
|
|
580
|
-
koreanHanjaInformal:
|
|
581
|
-
japaneseFormal:
|
|
582
|
-
japaneseInformal:
|
|
583
|
-
hiragana:
|
|
584
|
-
hiraganaIroha:
|
|
585
|
-
katakana:
|
|
586
|
-
katakanaIroha:
|
|
750
|
+
heavenlyStem: string[];
|
|
751
|
+
earthlyBranch: string[];
|
|
752
|
+
koreanHangulFormal: import("./types.js").DigitArray9;
|
|
753
|
+
koreanHanjaFormal: import("./types.js").DigitArray9;
|
|
754
|
+
koreanHanjaInformal: import("./types.js").DigitArray9;
|
|
755
|
+
japaneseFormal: import("./types.js").DigitArray9;
|
|
756
|
+
japaneseInformal: import("./types.js").DigitArray9;
|
|
757
|
+
hiragana: string[];
|
|
758
|
+
hiraganaIroha: string[];
|
|
759
|
+
katakana: string[];
|
|
760
|
+
katakanaIroha: string[];
|
|
587
761
|
};
|
|
588
762
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { STEMS, BRANCHES, KOREAN_HANGUL_DIGITS, KOREAN_HANJA_FORMAL_DIGITS, KOREAN_HANJA_INFORMAL_DIGITS, JAPANESE_FORMAL_DIGITS, JAPANESE_INFORMAL_DIGITS, HIRAGANA, HIRAGANA_IROHA, KATAKANA, KATAKANA_IROHA,
|
|
1
|
+
import { STEMS, BRANCHES, KOREAN_HANGUL_DIGITS, KOREAN_HANJA_FORMAL_DIGITS, KOREAN_HANJA_INFORMAL_DIGITS, JAPANESE_FORMAL_DIGITS, JAPANESE_INFORMAL_DIGITS, HIRAGANA, HIRAGANA_IROHA, KATAKANA, KATAKANA_IROHA, getSequenceMap, CANONICAL_DIGITS, SMALL_UNITS, BIG_UNIT_ORDER, TRAD_INFORMAL_SET, TRAD_FORMAL_SET, SIMP_INFORMAL_SET, SIMP_FORMAL_SET, KOREAN_HANGUL_SET, KOREAN_HANJA_FORMAL_SET, KOREAN_HANJA_INFORMAL_SET, JAPANESE_FORMAL_SET, JAPANESE_INFORMAL_SET, } from "./constants.js";
|
|
2
2
|
export * from "./types.js";
|
|
3
3
|
const NORMALIZE_MAP = {
|
|
4
4
|
負: "-",
|
|
@@ -53,29 +53,16 @@ const NORMALIZE_MAP = {
|
|
|
53
53
|
仟: "千",
|
|
54
54
|
};
|
|
55
55
|
const NORMALIZE_KEYS = Object.keys(NORMALIZE_MAP).sort((a, b) => b.length - a.length);
|
|
56
|
+
let normalizeRegex;
|
|
56
57
|
function normalizeInput(raw) {
|
|
57
58
|
const trimmed = raw.trim();
|
|
58
59
|
if (!trimmed) {
|
|
59
60
|
throw new SyntaxError("Empty string is not a valid number");
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
while (i < trimmed.length) {
|
|
64
|
-
let matched = false;
|
|
65
|
-
for (const key of NORMALIZE_KEYS) {
|
|
66
|
-
if (trimmed.startsWith(key, i)) {
|
|
67
|
-
result += NORMALIZE_MAP[key];
|
|
68
|
-
i += key.length;
|
|
69
|
-
matched = true;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (!matched) {
|
|
74
|
-
result += trimmed[i];
|
|
75
|
-
i += 1;
|
|
76
|
-
}
|
|
62
|
+
if (!normalizeRegex) {
|
|
63
|
+
normalizeRegex = new RegExp(NORMALIZE_KEYS.join("|"), "g");
|
|
77
64
|
}
|
|
78
|
-
return
|
|
65
|
+
return trimmed.replace(normalizeRegex, (matched) => NORMALIZE_MAP[matched]);
|
|
79
66
|
}
|
|
80
67
|
function toBigInt(value) {
|
|
81
68
|
if (typeof value === "bigint")
|
|
@@ -177,9 +164,13 @@ function toBestNumeric(value, preferBigInt) {
|
|
|
177
164
|
}
|
|
178
165
|
return Number(value);
|
|
179
166
|
}
|
|
167
|
+
let allowedRegex;
|
|
180
168
|
function validateStrictCharacters(input) {
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
if (!allowedRegex) {
|
|
170
|
+
allowedRegex =
|
|
171
|
+
/^[0-9零〇○一二三四五六七八九十百千萬万億亿兆京垓秭穰穣溝沟澗涧正載载極极恆恒河沙阿僧祇那由他不思議议可無无量大數数點点점壹貳贰參叁肆伍陸陆柒捌玖兩两拾佰仟負负壱弍弐参甲乙丙丁戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥ぁ-ゟ゠-ヿ가-힣.-]+$/;
|
|
172
|
+
}
|
|
173
|
+
if (!allowedRegex.test(input)) {
|
|
183
174
|
throw new SyntaxError("Input contains unsupported characters in strict mode");
|
|
184
175
|
}
|
|
185
176
|
}
|
|
@@ -195,16 +186,12 @@ function fromCycle(value, chars, mode) {
|
|
|
195
186
|
const normalized = (((asBigInt - 1n) % length) + length) % length;
|
|
196
187
|
return chars[Number(normalized)];
|
|
197
188
|
}
|
|
198
|
-
function parseCycle(input, chars
|
|
189
|
+
function parseCycle(input, chars) {
|
|
199
190
|
const index = chars.indexOf(input);
|
|
200
191
|
if (index < 0) {
|
|
201
192
|
throw new SyntaxError(`Unknown symbol ${input}`);
|
|
202
193
|
}
|
|
203
|
-
|
|
204
|
-
if (mode === "fixed") {
|
|
205
|
-
return value;
|
|
206
|
-
}
|
|
207
|
-
return value;
|
|
194
|
+
return index + 1;
|
|
208
195
|
}
|
|
209
196
|
function formatSection(section, set) {
|
|
210
197
|
const values = [1000, 100, 10, 1];
|
|
@@ -289,14 +276,12 @@ function formatDecimal(value, set) {
|
|
|
289
276
|
return negative ? `負${withSign}` : withSign;
|
|
290
277
|
}
|
|
291
278
|
function parseValue(input, options = {}) {
|
|
292
|
-
const modeStem = options.heavenlyStemMode ?? "fixed";
|
|
293
|
-
const modeBranch = options.earthlyBranchMode ?? "fixed";
|
|
294
279
|
const explicit = options.explicitTyping;
|
|
295
280
|
if (explicit === "cjkHeavenlyStem") {
|
|
296
|
-
return parseCycle(input, STEMS
|
|
281
|
+
return parseCycle(input, STEMS);
|
|
297
282
|
}
|
|
298
283
|
if (explicit === "cjkEarthlyBranch") {
|
|
299
|
-
return parseCycle(input, BRANCHES
|
|
284
|
+
return parseCycle(input, BRANCHES);
|
|
300
285
|
}
|
|
301
286
|
if (explicit === "hiragana") {
|
|
302
287
|
const idx = HIRAGANA.indexOf(input);
|
|
@@ -320,7 +305,7 @@ function parseValue(input, options = {}) {
|
|
|
320
305
|
}
|
|
321
306
|
// Handle other explicit numeric systems by validating characters?
|
|
322
307
|
// Or just fall through if not a sequence symbol.
|
|
323
|
-
const sequenceValue =
|
|
308
|
+
const sequenceValue = getSequenceMap()[input];
|
|
324
309
|
if (sequenceValue !== undefined) {
|
|
325
310
|
return sequenceValue;
|
|
326
311
|
}
|
|
@@ -353,76 +338,56 @@ function parseValue(input, options = {}) {
|
|
|
353
338
|
const signed = negative ? -parsed : parsed;
|
|
354
339
|
return toBestNumeric(signed, options.mode === "preferBigInt");
|
|
355
340
|
}
|
|
356
|
-
function
|
|
341
|
+
function toScaled(val) {
|
|
342
|
+
if (typeof val === "bigint")
|
|
343
|
+
return { big: val, scale: 0 };
|
|
357
344
|
const str = String(val);
|
|
345
|
+
const dotIndex = str.indexOf(".");
|
|
346
|
+
if (dotIndex < 0)
|
|
347
|
+
return { big: BigInt(str), scale: 0 };
|
|
348
|
+
const intPart = str.slice(0, dotIndex);
|
|
349
|
+
const fracPart = str.slice(dotIndex + 1);
|
|
358
350
|
const isNeg = str.startsWith("-");
|
|
359
|
-
const
|
|
360
|
-
const
|
|
361
|
-
return {
|
|
362
|
-
intPart: parts[0] || "0",
|
|
363
|
-
fracPart: parts[1] || "",
|
|
364
|
-
isNeg,
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
function alignScales(a, b) {
|
|
368
|
-
const parsedA = toScaleFormat(a);
|
|
369
|
-
const parsedB = toScaleFormat(b);
|
|
370
|
-
const maxDec = Math.max(parsedA.fracPart.length, parsedB.fracPart.length);
|
|
371
|
-
const strA = parsedA.intPart + parsedA.fracPart.padEnd(maxDec, "0");
|
|
372
|
-
const strB = parsedB.intPart + parsedB.fracPart.padEnd(maxDec, "0");
|
|
373
|
-
const bigA = BigInt(strA) * (parsedA.isNeg ? -1n : 1n);
|
|
374
|
-
const bigB = BigInt(strB) * (parsedB.isNeg ? -1n : 1n);
|
|
375
|
-
return { bigA, bigB, scale: maxDec };
|
|
376
|
-
}
|
|
377
|
-
function applyScale(val, scale) {
|
|
378
|
-
let str = (val < 0n ? -val : val).toString();
|
|
379
|
-
if (scale === 0)
|
|
380
|
-
return (val < 0n ? "-" : "") + str;
|
|
381
|
-
str = str.padStart(scale + 1, "0");
|
|
382
|
-
const intPart = str.slice(0, -scale);
|
|
383
|
-
const fracPart = str.slice(-scale).replace(/0+$/, "");
|
|
384
|
-
const joined = fracPart ? `${intPart || "0"}.${fracPart}` : (intPart || "0");
|
|
385
|
-
return (val < 0n ? "-" : "") + joined;
|
|
386
|
-
}
|
|
387
|
-
function mixedAdd(a, b) {
|
|
388
|
-
const { bigA, bigB, scale } = alignScales(a, b);
|
|
389
|
-
return applyScale(bigA + bigB, scale);
|
|
390
|
-
}
|
|
391
|
-
function mixedSubtract(a, b) {
|
|
392
|
-
const { bigA, bigB, scale } = alignScales(a, b);
|
|
393
|
-
return applyScale(bigA - bigB, scale);
|
|
351
|
+
const cleanInt = isNeg ? intPart.slice(1) : intPart;
|
|
352
|
+
const big = BigInt(cleanInt + fracPart) * (isNeg ? -1n : 1n);
|
|
353
|
+
return { big, scale: fracPart.length };
|
|
394
354
|
}
|
|
395
|
-
function
|
|
396
|
-
|
|
397
|
-
|
|
355
|
+
function fromScaled(val) {
|
|
356
|
+
if (val.scale === 0)
|
|
357
|
+
return val.big;
|
|
358
|
+
let str = (val.big < 0n ? -val.big : val.big).toString();
|
|
359
|
+
str = str.padStart(val.scale + 1, "0");
|
|
360
|
+
const intPart = str.slice(0, -val.scale);
|
|
361
|
+
const fracPart = str.slice(-val.scale).replace(/0+$/, "");
|
|
362
|
+
const res = fracPart ? `${intPart || "0"}.${fracPart}` : (intPart || "0");
|
|
363
|
+
return (val.big < 0n ? "-" : "") + res;
|
|
398
364
|
}
|
|
399
|
-
function
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const result = (bigA * (10n ** EXTRA)) / bigB;
|
|
405
|
-
return applyScale(result, Number(EXTRA));
|
|
365
|
+
function align(a, b) {
|
|
366
|
+
const maxScale = Math.max(a.scale, b.scale);
|
|
367
|
+
const bigA = a.big * 10n ** BigInt(maxScale - a.scale);
|
|
368
|
+
const bigB = b.big * 10n ** BigInt(maxScale - b.scale);
|
|
369
|
+
return { a: bigA, b: bigB, scale: maxScale };
|
|
406
370
|
}
|
|
407
371
|
function mixedModulo(a, b) {
|
|
408
|
-
const
|
|
409
|
-
|
|
372
|
+
const scaledA = toScaled(a);
|
|
373
|
+
const scaledB = toScaled(b);
|
|
374
|
+
const { a: bigA, b: bigB, scale } = align(scaledA, scaledB);
|
|
375
|
+
return fromScaled({ big: bigA % bigB, scale });
|
|
410
376
|
}
|
|
411
377
|
function mixedPow(base, exponent) {
|
|
412
|
-
const
|
|
413
|
-
if (
|
|
378
|
+
const scaledExp = toScaled(exponent);
|
|
379
|
+
if (scaledExp.scale > 0)
|
|
414
380
|
return Number(base) ** Number(exponent);
|
|
415
|
-
const expNum =
|
|
381
|
+
const expNum = scaledExp.big;
|
|
416
382
|
if (expNum < 0n)
|
|
417
383
|
return Number(base) ** Number(exponent);
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
return applyScale(parsedBase.isNeg && expNum % 2n !== 0n ? -result : result, scale);
|
|
384
|
+
const scaledBase = toScaled(base);
|
|
385
|
+
const resScale = Number(BigInt(scaledBase.scale) * expNum);
|
|
386
|
+
const resBig = scaledBase.big ** expNum;
|
|
387
|
+
return fromScaled({ big: resBig, scale: resScale });
|
|
423
388
|
}
|
|
424
389
|
function mixedCompare(a, b) {
|
|
425
|
-
const { bigA, bigB } =
|
|
390
|
+
const { a: bigA, b: bigB } = align(toScaled(a), toScaled(b));
|
|
426
391
|
return bigA > bigB ? 1 : bigA < bigB ? -1 : 0;
|
|
427
392
|
}
|
|
428
393
|
function createSystem(set) {
|
|
@@ -445,12 +410,15 @@ function createSystem(set) {
|
|
|
445
410
|
* @returns The sum of the CJK numeric strings.
|
|
446
411
|
*/
|
|
447
412
|
add(values) {
|
|
448
|
-
if (values.length === 0)
|
|
413
|
+
if (values.length === 0)
|
|
449
414
|
return set.zero;
|
|
415
|
+
let acc = toScaled(number.parse(values[0]));
|
|
416
|
+
for (let i = 1; i < values.length; i++) {
|
|
417
|
+
const next = toScaled(number.parse(values[i]));
|
|
418
|
+
const aligned = align(acc, next);
|
|
419
|
+
acc = { big: aligned.a + aligned.b, scale: aligned.scale };
|
|
450
420
|
}
|
|
451
|
-
|
|
452
|
-
const sum = rest.reduce(mixedAdd, first);
|
|
453
|
-
return this.parse(sum);
|
|
421
|
+
return this.parse(fromScaled(acc));
|
|
454
422
|
},
|
|
455
423
|
/**
|
|
456
424
|
* Subtracts multiple CJK numeric strings from the first one.
|
|
@@ -458,12 +426,15 @@ function createSystem(set) {
|
|
|
458
426
|
* @returns The difference of the CJK numeric strings.
|
|
459
427
|
*/
|
|
460
428
|
subtract(values) {
|
|
461
|
-
if (values.length === 0)
|
|
429
|
+
if (values.length === 0)
|
|
462
430
|
return set.zero;
|
|
431
|
+
let acc = toScaled(number.parse(values[0]));
|
|
432
|
+
for (let i = 1; i < values.length; i++) {
|
|
433
|
+
const next = toScaled(number.parse(values[i]));
|
|
434
|
+
const aligned = align(acc, next);
|
|
435
|
+
acc = { big: aligned.a - aligned.b, scale: aligned.scale };
|
|
463
436
|
}
|
|
464
|
-
|
|
465
|
-
const diff = rest.reduce(mixedSubtract, first);
|
|
466
|
-
return this.parse(diff);
|
|
437
|
+
return this.parse(fromScaled(acc));
|
|
467
438
|
},
|
|
468
439
|
/**
|
|
469
440
|
* Multiplies multiple CJK numeric strings together.
|
|
@@ -471,12 +442,14 @@ function createSystem(set) {
|
|
|
471
442
|
* @returns The product of the CJK numeric strings.
|
|
472
443
|
*/
|
|
473
444
|
multiply(values) {
|
|
474
|
-
if (values.length === 0)
|
|
445
|
+
if (values.length === 0)
|
|
475
446
|
return set.zero;
|
|
447
|
+
let acc = toScaled(number.parse(values[0]));
|
|
448
|
+
for (let i = 1; i < values.length; i++) {
|
|
449
|
+
const next = toScaled(number.parse(values[i]));
|
|
450
|
+
acc = { big: acc.big * next.big, scale: acc.scale + next.scale };
|
|
476
451
|
}
|
|
477
|
-
|
|
478
|
-
const product = rest.reduce(mixedMultiply, first);
|
|
479
|
-
return this.parse(product);
|
|
452
|
+
return this.parse(fromScaled(acc));
|
|
480
453
|
},
|
|
481
454
|
/**
|
|
482
455
|
* Divides multiple CJK numeric strings from the first one.
|
|
@@ -484,12 +457,21 @@ function createSystem(set) {
|
|
|
484
457
|
* @returns The quotient of the CJK numeric strings.
|
|
485
458
|
*/
|
|
486
459
|
divide(values) {
|
|
487
|
-
if (values.length === 0)
|
|
460
|
+
if (values.length === 0)
|
|
488
461
|
return set.zero;
|
|
462
|
+
let acc = toScaled(number.parse(values[0]));
|
|
463
|
+
const EXTRA = 16n;
|
|
464
|
+
for (let i = 1; i < values.length; i++) {
|
|
465
|
+
const next = toScaled(number.parse(values[i]));
|
|
466
|
+
if (next.big === 0n)
|
|
467
|
+
throw new RangeError("Division by zero");
|
|
468
|
+
const aligned = align(acc, next);
|
|
469
|
+
acc = {
|
|
470
|
+
big: (aligned.a * 10n ** EXTRA) / aligned.b,
|
|
471
|
+
scale: Number(EXTRA),
|
|
472
|
+
};
|
|
489
473
|
}
|
|
490
|
-
|
|
491
|
-
const quotient = rest.reduce(mixedDivide, first);
|
|
492
|
-
return this.parse(quotient);
|
|
474
|
+
return this.parse(fromScaled(acc));
|
|
493
475
|
},
|
|
494
476
|
/**
|
|
495
477
|
* Calculates the remainder of the first string divided by the second.
|
|
@@ -543,6 +525,57 @@ function createCyclicSystem(chars) {
|
|
|
543
525
|
parse(value, options = {}) {
|
|
544
526
|
return fromCycle(value, chars, options.mode ?? "fixed");
|
|
545
527
|
},
|
|
528
|
+
/**
|
|
529
|
+
* Parses a single sequence symbol into its numeric position (1-based index).
|
|
530
|
+
* This is system-specific, so "ぬ" resolves to 23 in hiragana but 10 in hiraganaIroha.
|
|
531
|
+
* @param symbol The sequence symbol to decode.
|
|
532
|
+
* @returns The 1-based index of the symbol in the sequence.
|
|
533
|
+
*/
|
|
534
|
+
decode(symbol) {
|
|
535
|
+
const index = chars.indexOf(symbol);
|
|
536
|
+
if (index < 0) {
|
|
537
|
+
throw new SyntaxError(`Symbol "${symbol}" is not part of this system`);
|
|
538
|
+
}
|
|
539
|
+
return index + 1;
|
|
540
|
+
},
|
|
541
|
+
/**
|
|
542
|
+
* Returns the character at a specific distance after the given symbol (wraps around).
|
|
543
|
+
* @param symbol The starting symbol.
|
|
544
|
+
* @param step The number of positions to move forward.
|
|
545
|
+
* @returns The resulting sequence character.
|
|
546
|
+
*/
|
|
547
|
+
next(symbol, step = 1n) {
|
|
548
|
+
const current = this.decode(symbol);
|
|
549
|
+
return this.parse(BigInt(current) + BigInt(step), { mode: "cyclic" });
|
|
550
|
+
},
|
|
551
|
+
/**
|
|
552
|
+
* Returns the character at a specific distance before the given symbol (wraps around).
|
|
553
|
+
* @param symbol The starting symbol.
|
|
554
|
+
* @param step The number of positions to move backward.
|
|
555
|
+
* @returns The resulting sequence character.
|
|
556
|
+
*/
|
|
557
|
+
prev(symbol, step = 1n) {
|
|
558
|
+
const current = this.decode(symbol);
|
|
559
|
+
return this.parse(BigInt(current) - BigInt(step), { mode: "cyclic" });
|
|
560
|
+
},
|
|
561
|
+
/**
|
|
562
|
+
* Returns an array of symbols between the start and end (inclusive).
|
|
563
|
+
* Follows the cyclic order if the start index is greater than the end index.
|
|
564
|
+
* @param start The starting symbol.
|
|
565
|
+
* @param end The ending symbol.
|
|
566
|
+
* @returns A list of symbols in the sequence.
|
|
567
|
+
*/
|
|
568
|
+
range(start, end) {
|
|
569
|
+
const iStart = this.decode(start) - 1;
|
|
570
|
+
const iEnd = this.decode(end) - 1;
|
|
571
|
+
if (iStart <= iEnd) {
|
|
572
|
+
return chars.slice(iStart, iEnd + 1);
|
|
573
|
+
}
|
|
574
|
+
return [
|
|
575
|
+
...chars.slice(iStart),
|
|
576
|
+
...chars.slice(0, iEnd + 1),
|
|
577
|
+
];
|
|
578
|
+
},
|
|
546
579
|
};
|
|
547
580
|
}
|
|
548
581
|
export const number = {
|
package/dist/types.d.ts
CHANGED
|
@@ -43,10 +43,6 @@ export interface NumberParseOptions {
|
|
|
43
43
|
strict?: boolean;
|
|
44
44
|
/** Controls the numeric output type. Defaults to `"number"`. */
|
|
45
45
|
mode?: NumberMode;
|
|
46
|
-
/** Controls the heavenly stem mode. Defaults to `"fixed"`. */
|
|
47
|
-
heavenlyStemMode?: CyclicMode;
|
|
48
|
-
/** Controls the earthly branch mode. Defaults to `"fixed"`. */
|
|
49
|
-
earthlyBranchMode?: CyclicMode;
|
|
50
46
|
/**
|
|
51
47
|
* Controls the explicit typing of the output.
|
|
52
48
|
* - `"cjkIdeographic"` – always return CJK ideographic characters.
|
|
@@ -88,4 +84,8 @@ export interface DigitSet {
|
|
|
88
84
|
bigUnits: string[];
|
|
89
85
|
dropTenOne?: boolean;
|
|
90
86
|
}
|
|
87
|
+
export interface ScaledValue {
|
|
88
|
+
big: bigint;
|
|
89
|
+
scale: number;
|
|
90
|
+
}
|
|
91
91
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,UAAU,GAAG,eAAe,GAAG,UAAU,GAAG,eAAe,CAAC;AAE9V,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,UAAU,GAAG,eAAe,GAAG,UAAU,GAAG,eAAe,CAAC;AAE9V,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;;;;;;;;;;;;;;;OAkBG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,SAAS;IACjC,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cjk-number",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Convert between numbers and CJK number systems",
|
|
5
5
|
"author": "tse-wei-chen",
|
|
6
6
|
"repository": {
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"earthly-branches"
|
|
59
59
|
],
|
|
60
60
|
"license": "MIT",
|
|
61
|
+
"sideEffects": false,
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@types/node": "^25.5.0",
|
|
63
64
|
"@vitest/coverage-v8": "^4.1.2",
|