@ozgurguler/trnorm 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +71 -2
- package/index.d.ts +30 -0
- package/package.json +49 -4
- package/src/case_tables.js +89 -0
- package/src/casing.js +34 -0
- package/src/index.js +19 -0
- package/src/itn.js +255 -0
- package/src/lexicon.js +489 -0
- package/src/normalizer.js +1513 -0
- package/src/numbers.js +325 -0
- package/src/py.js +438 -0
- package/src/unassigned.js +100 -0
package/src/py.js
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
// The Python semantics the trnorm port relies on, where JavaScript differs (no Python file of its own: str, re and
|
|
2
|
+
// int() as CPython 3.12 defines them, the Python Pyodide runs).
|
|
3
|
+
// - re: \w \d \b are ASCII-only in JS even with the u flag; \s and trim() use another whitespace set; $ also matches
|
|
4
|
+
// before a final newline in Python; pattern.match / fullmatch / search take pos and endpos.
|
|
5
|
+
// - str: len() and indices count code points (JS counts UTF-16 units); split() and strip() use Python's
|
|
6
|
+
// whitespace; split(sep, 1) splits once (JS's limit truncates); isupper(), isdecimal()... as Python defines them;
|
|
7
|
+
// lower() and upper() as Unicode 15.0 maps case, final sigma included (case_tables.js).
|
|
8
|
+
// - int(): unbounded (BigInt), any Unicode decimal digits, and str <-> int conversion refuses more than 4300 digits
|
|
9
|
+
// (ValueError): normalize() raises there in Python, so it throws here.
|
|
10
|
+
|
|
11
|
+
import { LOWERCASE, SIGMA_CASED, SIGMA_IGNORABLE, TITLECASE, UPPERCASE } from './case_tables.js';
|
|
12
|
+
import { UNASSIGNED } from './unassigned.js';
|
|
13
|
+
|
|
14
|
+
// ---- regex fragments --------------------------------------------------------------------------------------------------
|
|
15
|
+
// Every pattern is compiled with the u flag. Python's \w (str patterns) is str.isalnum() or "_", i.e. letters and
|
|
16
|
+
// everything with a numeric value: \p{L}\p{N}_. \d is str.isdecimal(): \p{Nd}. \s is str.isspace(): Zs and the bidi
|
|
17
|
+
// classes WS, B, S, so \x1c-\x1f and \x85 more than JS's \s, and \u{feff} not. Checked over every code point against
|
|
18
|
+
// CPython 3.12 (Unicode 15.0): they differ only on characters Unicode 15.0 does not assign, which normalize() hides
|
|
19
|
+
// from the engine (normalizer.js, unassigned.js).
|
|
20
|
+
export const WC = String.raw`\p{L}\p{N}_`; // \w inside a class
|
|
21
|
+
export const W = `[${WC}]`;
|
|
22
|
+
export const D = String.raw`\p{Nd}`; // also usable inside a class
|
|
23
|
+
export const SC = String.raw`\t-\r\x1c-\x20\x85\xa0\u{1680}\u{2000}-\u{200a}\u{2028}\u{2029}\u{202f}\u{205f}\u{3000}`;
|
|
24
|
+
export const S = `[${SC}]`;
|
|
25
|
+
// Safari 26.0 to 26.5 (WebKit 2215 to 2311) decode a character of U+D800..U+DBFF or U+F800..U+FBFF followed by one of
|
|
26
|
+
// U+FC00..U+FFFF as one code point in a u-flag pattern (its surrogate test masks with 0xDC00, not 0xFC00): /\uff15/u
|
|
27
|
+
// does not find U+FF15 in "\ufb01\uff15", so "fi5" kept its digit unread. True in such an engine. normalizer.js
|
|
28
|
+
// leaves no lone surrogate to a u-flag pattern; a text that still holds such a pair is left to the Python there.
|
|
29
|
+
export const U_PAIR_BUG = !/\uff15/u.test('\ufb01\uff15');
|
|
30
|
+
export const U_PAIR_RE = /[\uf800-\ufbff][\ufc00-\uffff]/;
|
|
31
|
+
|
|
32
|
+
// (?<=[cls]) and (?<![cls]) for a class with astral members (\w, \d): the class is tested by a lookahead on the one
|
|
33
|
+
// character the lookbehind steps back over. JavaScriptCore before WebKit 2370 (Safari 16.4 to 26.5) does not match a
|
|
34
|
+
// class or a \p{} escape backwards over a surrogate pair, so (?<![\p{L}])5 matched in "\u{1D465}5"; stepping back
|
|
35
|
+
// with "." and looking ahead works in every engine, and V8 runs it as fast. cls must not hold a line terminator,
|
|
36
|
+
// which "." does not step over.
|
|
37
|
+
export const lb = (cls) => `(?<=(?=[${cls}]).)`;
|
|
38
|
+
export const nlb = (cls) => `(?<!(?=[${cls}]).)`;
|
|
39
|
+
export const B = `(?:${lb(WC)}(?!${W})|${nlb(WC)}(?=${W}))`; // \b
|
|
40
|
+
export const END = String.raw`(?=\n?$)`; // $ (no MULTILINE): the end, or before a newline that ends the text
|
|
41
|
+
export const ANY = String.raw`[^\n]`; // . (no DOTALL)
|
|
42
|
+
|
|
43
|
+
// Python's re.IGNORECASE matches a character whose simple lowercase is the pattern's, plus fixed equivalents (i ~ ı,
|
|
44
|
+
// s ~ ſ); JS's i flag folds case instead, so İ and ı would not match i. ci(word) spells a lowercase literal the way
|
|
45
|
+
// Python matches it under re.I; the classes for i, ı, k and s are Python's, checked over all code points.
|
|
46
|
+
const CI = { i: 'Iiİı', ı: 'Iiİı', k: 'Kk\u{212a}', s: 'Ssſ' };
|
|
47
|
+
export function ci(word) {
|
|
48
|
+
let out = '';
|
|
49
|
+
for (const c of word) {
|
|
50
|
+
const up = c.toUpperCase();
|
|
51
|
+
out += CI[c] ? `[${CI[c]}]` : up !== c ? `[${up}${c}]` : escape(c);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
export const CI_A_Z = 'A-Za-zİıſ\u{212a}'; // [a-z] under re.I, inside a class
|
|
56
|
+
|
|
57
|
+
// re.escape for a literal: only what is special in a u-flag pattern (Python's re.escape also escapes "-", " ", "#",
|
|
58
|
+
// "&", "~", which a u-flag pattern rejects)
|
|
59
|
+
function escape(s) {
|
|
60
|
+
return s.replace(/[\\^$.*+?()[\]{}|/]/gu, '\\$&');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// A compiled pattern. Matches are JS exec arrays: m[0], m[n] (undefined where Python has None), m.index; positions are
|
|
64
|
+
// UTF-16 indices (cp_back / cp_fwd do Python's character arithmetic on them). needs(text), when given, is false only
|
|
65
|
+
// for a text the pattern cannot match anywhere (it lacks a character every match has): finditer and sub skip the
|
|
66
|
+
// scan then, which keeps the result and saves most passes on a paragraph without digits, "%", "/"...
|
|
67
|
+
//
|
|
68
|
+
// unicode false: compiled without the u flag, for a pattern whose characters are all BMP and that has no negated class
|
|
69
|
+
// or "." (so it matches the same): Safari 16.4 runs a u-flag pattern with a lookbehind O(n²) on a long run of spaces.
|
|
70
|
+
class Pattern {
|
|
71
|
+
constructor(source, needs = null, unicode = true) {
|
|
72
|
+
this.source = unicode ? source : source.replace(/\\u\{([0-9a-f]{1,4})\}/gi, (m, h) => `\\u${h.padStart(4, '0')}`);
|
|
73
|
+
this.u = unicode ? 'u' : '';
|
|
74
|
+
this.rx = new RegExp(this.source, `g${this.u}`);
|
|
75
|
+
this.needs = needs;
|
|
76
|
+
this._y = null;
|
|
77
|
+
this._full = null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// pattern.match(text, pos): a match that starts at pos
|
|
81
|
+
match(text, pos = 0) {
|
|
82
|
+
const rx = this._y || (this._y = new RegExp(this.source, `y${this.u}`));
|
|
83
|
+
rx.lastIndex = pos;
|
|
84
|
+
return rx.exec(text);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// pattern.fullmatch(text, pos): from pos to the end
|
|
88
|
+
fullmatch(text, pos = 0) {
|
|
89
|
+
const rx = this._full || (this._full = new RegExp(`(?:${this.source})$`, `y${this.u}`));
|
|
90
|
+
rx.lastIndex = pos;
|
|
91
|
+
return rx.exec(text);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// pattern.search(text, pos, endpos): the text ends at endpos ($, lookaheads), lookbehinds still see before pos
|
|
95
|
+
search(text, pos = 0, endpos = text.length) {
|
|
96
|
+
const rx = this.rx;
|
|
97
|
+
rx.lastIndex = pos;
|
|
98
|
+
return rx.exec(endpos < text.length ? text.slice(0, endpos) : text);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// lastIndex is set before every exec, so a callback may use the same pattern in between. No pattern in trnorm
|
|
102
|
+
// matches the empty string; one that did would step past an empty match the way Python did before 3.7.
|
|
103
|
+
*finditer(text) {
|
|
104
|
+
if (this.needs && !this.needs(text)) return;
|
|
105
|
+
const rx = this.rx;
|
|
106
|
+
let pos = 0;
|
|
107
|
+
while (pos <= text.length) {
|
|
108
|
+
rx.lastIndex = pos;
|
|
109
|
+
const m = rx.exec(text);
|
|
110
|
+
if (!m) return;
|
|
111
|
+
yield m;
|
|
112
|
+
pos = m.index + m[0].length;
|
|
113
|
+
if (!m[0]) pos += cp_len_at(text, pos);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// findall for a pattern without groups
|
|
118
|
+
findall(text) {
|
|
119
|
+
return text.match(this.rx) || [];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// sub with a function of the match, or a literal string (no backreferences)
|
|
123
|
+
sub(repl, text) {
|
|
124
|
+
if (this.needs && !this.needs(text)) return text;
|
|
125
|
+
let out = '';
|
|
126
|
+
let pos = 0;
|
|
127
|
+
for (const m of this.finditer(text)) {
|
|
128
|
+
out += text.slice(pos, m.index) + (typeof repl === 'string' ? repl : repl(m));
|
|
129
|
+
pos = m.index + m[0].length;
|
|
130
|
+
}
|
|
131
|
+
return pos ? out + text.slice(pos) : text;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
split(text) {
|
|
135
|
+
return text.split(this.rx);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// The re module: re.compile(pattern), and re.sub / match / fullmatch / search / findall / split taking a pattern
|
|
140
|
+
// source, compiled once and cached (as Python's re caches), so the port can keep Python's inline calls.
|
|
141
|
+
const cache = new Map();
|
|
142
|
+
function compile(source, needs = null, unicode = true) {
|
|
143
|
+
let p = cache.get(source);
|
|
144
|
+
if (!p) cache.set(source, (p = new Pattern(source, needs, unicode)));
|
|
145
|
+
return p;
|
|
146
|
+
}
|
|
147
|
+
// needs() helpers: the text holds one of these (BMP) characters / a decimal digit. No u flag where none is needed: a
|
|
148
|
+
// plain class scan is the fastest test, and the first decimal digit outside ASCII is U+0660.
|
|
149
|
+
export const has = (chars) => {
|
|
150
|
+
if (chars.length === 1) return (text) => text.includes(chars);
|
|
151
|
+
const rx = new RegExp(`[${chars.replace(/[\\\]^-]/g, '\\$&')}]`);
|
|
152
|
+
return (text) => rx.test(text);
|
|
153
|
+
};
|
|
154
|
+
const ASCII_DIGIT = /[0-9]/;
|
|
155
|
+
const FROM_0660 = /[^\0-\u065f]/;
|
|
156
|
+
const ANY_DIGIT = /\p{Nd}/u;
|
|
157
|
+
export const has_digit = (text) => ASCII_DIGIT.test(text) || (FROM_0660.test(text) && ANY_DIGIT.test(text));
|
|
158
|
+
export const re = {
|
|
159
|
+
compile,
|
|
160
|
+
escape,
|
|
161
|
+
sub: (source, repl, text) => compile(source).sub(repl, text),
|
|
162
|
+
match: (source, text) => compile(source).match(text),
|
|
163
|
+
fullmatch: (source, text) => compile(source).fullmatch(text),
|
|
164
|
+
search: (source, text) => compile(source).search(text),
|
|
165
|
+
findall: (source, text) => compile(source).findall(text),
|
|
166
|
+
split: (source, text) => compile(source).split(text),
|
|
167
|
+
};
|
|
168
|
+
// match.end()
|
|
169
|
+
export const end = (m) => m.index + m[0].length;
|
|
170
|
+
|
|
171
|
+
// ---- code points ------------------------------------------------------------------------------------------------------
|
|
172
|
+
const isHigh = (c) => c >= 0xd800 && c <= 0xdbff;
|
|
173
|
+
const isLow = (c) => c >= 0xdc00 && c <= 0xdfff;
|
|
174
|
+
const cp_len_at = (s, i) => (isHigh(s.charCodeAt(i)) && isLow(s.charCodeAt(i + 1)) ? 2 : 1);
|
|
175
|
+
|
|
176
|
+
// len(s)
|
|
177
|
+
export function plen(s) {
|
|
178
|
+
let n = s.length;
|
|
179
|
+
for (let i = 0; i < s.length - 1; i++) {
|
|
180
|
+
if (isHigh(s.charCodeAt(i)) && isLow(s.charCodeAt(i + 1))) {
|
|
181
|
+
n--;
|
|
182
|
+
i++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return n;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// the index n code points before / after index i: Python's text[i - n:i] is s.slice(cp_back(s, i, n), i)
|
|
189
|
+
export function cp_back(s, i, n) {
|
|
190
|
+
for (; n > 0 && i > 0; n--) i -= i >= 2 && isLow(s.charCodeAt(i - 1)) && isHigh(s.charCodeAt(i - 2)) ? 2 : 1;
|
|
191
|
+
return i;
|
|
192
|
+
}
|
|
193
|
+
export function cp_fwd(s, i, n) {
|
|
194
|
+
for (; n > 0 && i < s.length; n--) i += cp_len_at(s, i);
|
|
195
|
+
return i;
|
|
196
|
+
}
|
|
197
|
+
// s[0] and s[-1] ('' for an empty string, where Python's s[:1] and s[-1:] are '')
|
|
198
|
+
export const first_cp = (s) => (s ? String.fromCodePoint(s.codePointAt(0)) : '');
|
|
199
|
+
export const last_cp = (s) => (s ? s.slice(cp_back(s, s.length, 1)) : '');
|
|
200
|
+
// the character that ends at index i (Python's text[i - 1]) and the one that starts there ('' past either end)
|
|
201
|
+
export const char_before = (s, i) => s.slice(cp_back(s, i, 1), i);
|
|
202
|
+
export const char_at = (s, i) => s.slice(i, cp_fwd(s, i, 1));
|
|
203
|
+
|
|
204
|
+
// ---- str methods ------------------------------------------------------------------------------------------------------
|
|
205
|
+
const SPACE = new Set();
|
|
206
|
+
for (const [a, b] of [[0x09, 0x0d], [0x1c, 0x20], [0x85, 0x85], [0xa0, 0xa0], [0x1680, 0x1680], [0x2000, 0x200a],
|
|
207
|
+
[0x2028, 0x2029], [0x202f, 0x202f], [0x205f, 0x205f], [0x3000, 0x3000]]) {
|
|
208
|
+
for (let c = a; c <= b; c++) SPACE.add(c);
|
|
209
|
+
}
|
|
210
|
+
// Python's whitespace is all in the BMP, so a UTF-16 unit test is a code point test.
|
|
211
|
+
const isspace_unit = (s, i) => SPACE.has(s.charCodeAt(i));
|
|
212
|
+
|
|
213
|
+
// s.strip() / s.strip(chars) and the one-sided forms; chars: BMP characters
|
|
214
|
+
function stripper(s, chars, left, right) {
|
|
215
|
+
const has = chars === undefined ? (i) => isspace_unit(s, i) : (i) => chars.includes(s[i]);
|
|
216
|
+
let a = 0;
|
|
217
|
+
let b = s.length;
|
|
218
|
+
if (left) while (a < b && has(a)) a++;
|
|
219
|
+
if (right) while (b > a && has(b - 1)) b--;
|
|
220
|
+
return a === 0 && b === s.length ? s : s.slice(a, b);
|
|
221
|
+
}
|
|
222
|
+
export const strip = (s, chars) => stripper(s, chars, true, true);
|
|
223
|
+
export const lstrip = (s, chars) => stripper(s, chars, true, false);
|
|
224
|
+
export const rstrip = (s, chars) => stripper(s, chars, false, true);
|
|
225
|
+
|
|
226
|
+
// s.split() (no separator): runs of whitespace, no empty strings
|
|
227
|
+
export function split(s) {
|
|
228
|
+
const out = [];
|
|
229
|
+
const n = s.length;
|
|
230
|
+
let i = 0;
|
|
231
|
+
while (i < n) {
|
|
232
|
+
while (i < n && isspace_unit(s, i)) i++;
|
|
233
|
+
if (i >= n) break;
|
|
234
|
+
let j = i + 1;
|
|
235
|
+
while (j < n && !isspace_unit(s, j)) j++;
|
|
236
|
+
out.push(s.slice(i, j));
|
|
237
|
+
i = j;
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// s.split(sep, 1)
|
|
243
|
+
export function split1(s, sep) {
|
|
244
|
+
const i = s.indexOf(sep);
|
|
245
|
+
return i < 0 ? [s] : [s.slice(0, i), s.slice(i + sep.length)];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// A character Unicode 15.0 does not have: newer than Python's data (case, letters, digits). Every one is above
|
|
249
|
+
// U+0377, so a text below that (Turkish and Latin text) skips the big class.
|
|
250
|
+
const NEWER = new RegExp(`[${UNASSIGNED}]`, 'u');
|
|
251
|
+
const ABOVE_0377 = /[^\0-\u0377]/;
|
|
252
|
+
const has_newer = (s) => ABOVE_0377.test(s) && NEWER.test(s);
|
|
253
|
+
const ALPHA = /^\p{L}+$/u;
|
|
254
|
+
const DECIMAL = /^\p{Nd}+$/u;
|
|
255
|
+
// str.isdigit(): decimals plus the other Numeric_Type=Digit characters (superscripts, circled digits...), from
|
|
256
|
+
// CPython 3.12's unicodedata (the same 128 in 3.13)
|
|
257
|
+
const DIGIT = new RegExp(String.raw`^[\p{Nd}\u{b2}-\u{b3}\u{b9}\u{1369}-\u{1371}\u{19da}\u{2070}\u{2074}-\u{2079}` +
|
|
258
|
+
String.raw`\u{2080}-\u{2089}\u{2460}-\u{2468}\u{2474}-\u{247c}\u{2488}-\u{2490}\u{24ea}\u{24f5}-\u{24fd}\u{24ff}` +
|
|
259
|
+
String.raw`\u{2776}-\u{277e}\u{2780}-\u{2788}\u{278a}-\u{2792}\u{10a40}-\u{10a43}\u{10e60}-\u{10e68}` +
|
|
260
|
+
String.raw`\u{11052}-\u{1105a}\u{1f100}-\u{1f10a}]+$`, 'u');
|
|
261
|
+
const ALNUM = /^[\p{L}\p{N}]+$/u; // isalpha() or a numeric value
|
|
262
|
+
|
|
263
|
+
// A character newer than Unicode 15.0 is none of these to Python (normalize() never asks about one: it hides them).
|
|
264
|
+
// one BMP character, asked often (letter by letter): answers kept, 0 unknown, 1 no, 2 yes
|
|
265
|
+
const alpha_bmp = new Uint8Array(0x10000);
|
|
266
|
+
export function isalpha(s) {
|
|
267
|
+
if (s.length === 1) {
|
|
268
|
+
const c = s.charCodeAt(0);
|
|
269
|
+
return (alpha_bmp[c] ||= ALPHA.test(s) && !has_newer(s) ? 2 : 1) === 2;
|
|
270
|
+
}
|
|
271
|
+
return ALPHA.test(s) && !has_newer(s);
|
|
272
|
+
}
|
|
273
|
+
export const isdecimal = (s) => DECIMAL.test(s) && !has_newer(s);
|
|
274
|
+
export const isdigit = (s) => DIGIT.test(s) && !has_newer(s);
|
|
275
|
+
export const isalnum = (s) => ALNUM.test(s) && !has_newer(s);
|
|
276
|
+
|
|
277
|
+
// ---- case -------------------------------------------------------------------------------------------------------------
|
|
278
|
+
// Python's case properties, not the engine's: a newer Unicode moved some assigned characters (U+0295 is no longer
|
|
279
|
+
// lowercase in Unicode 17, and Safari 26's \p{Lowercase} already says so). case_tables.js holds Python's ranges.
|
|
280
|
+
const tables = {};
|
|
281
|
+
function table(name, encoded) {
|
|
282
|
+
let t = tables[name];
|
|
283
|
+
if (!t) {
|
|
284
|
+
const nums = encoded.split(' ');
|
|
285
|
+
t = tables[name] = new Uint32Array(nums.length);
|
|
286
|
+
let prev = -1;
|
|
287
|
+
for (let i = 0; i < nums.length; i += 2) {
|
|
288
|
+
t[i] = prev + 1 + parseInt(nums[i], 36);
|
|
289
|
+
t[i + 1] = prev = t[i] + parseInt(nums[i + 1], 36);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return t;
|
|
293
|
+
}
|
|
294
|
+
export function in_table(t, cp) {
|
|
295
|
+
let lo = 0;
|
|
296
|
+
let hi = (t.length >> 1) - 1;
|
|
297
|
+
while (lo <= hi) {
|
|
298
|
+
const mid = (lo + hi) >> 1;
|
|
299
|
+
if (cp < t[2 * mid]) hi = mid - 1;
|
|
300
|
+
else if (cp > t[2 * mid + 1]) lo = mid + 1;
|
|
301
|
+
else return true;
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
const is_lower_cp = (cp) => (cp < 0x80 ? cp >= 0x61 && cp <= 0x7a : in_table(table('l', LOWERCASE), cp));
|
|
306
|
+
const is_upper_cp = (cp) => (cp < 0x80 ? cp >= 0x41 && cp <= 0x5a : in_table(table('u', UPPERCASE), cp));
|
|
307
|
+
const is_title_cp = (cp) => cp >= 0x1c5 && in_table(table('t', TITLECASE), cp);
|
|
308
|
+
|
|
309
|
+
// at least one cased character, and no character of the other case (or titlecase)
|
|
310
|
+
export function isupper(s) {
|
|
311
|
+
let cased = false;
|
|
312
|
+
for (const c of s) {
|
|
313
|
+
const cp = c.codePointAt(0);
|
|
314
|
+
if (is_lower_cp(cp) || is_title_cp(cp)) return false;
|
|
315
|
+
if (!cased && is_upper_cp(cp)) cased = true;
|
|
316
|
+
}
|
|
317
|
+
return cased;
|
|
318
|
+
}
|
|
319
|
+
export function islower(s) {
|
|
320
|
+
let cased = false;
|
|
321
|
+
for (const c of s) {
|
|
322
|
+
const cp = c.codePointAt(0);
|
|
323
|
+
if (is_upper_cp(cp) || is_title_cp(cp)) return false;
|
|
324
|
+
if (!cased && is_lower_cp(cp)) cased = true;
|
|
325
|
+
}
|
|
326
|
+
return cased;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
// The engine's case mapping of one character, unless it is newer than Unicode 15.0 or maps to a newer one: that
|
|
331
|
+
// mapping came later (case pairs never change once made; a later version only pairs an old character with a new one,
|
|
332
|
+
// as Unicode 16 did ƛ with U+A7DC), so Python leaves the character as it is. Checked over every code point against
|
|
333
|
+
// CPython 3.12 in V8, SpiderMonkey and JavaScriptCore.
|
|
334
|
+
function map_char(c, mapped) {
|
|
335
|
+
return mapped === c || (!NEWER.test(c) && !NEWER.test(mapped)) ? mapped : c;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// str.lower()'s Final_Sigma rule (CPython's handle_capital_sigma), on the code points cps around Σ at i: final when a
|
|
339
|
+
// cased character comes before it, case-ignorable ones skipped, and none after it
|
|
340
|
+
function final_sigma(cps, i) {
|
|
341
|
+
const ign = table('i', SIGMA_IGNORABLE);
|
|
342
|
+
const cased = table('c', SIGMA_CASED);
|
|
343
|
+
let j = i - 1;
|
|
344
|
+
while (j >= 0 && in_table(ign, cps[j].codePointAt(0))) j--;
|
|
345
|
+
if (j < 0 || !in_table(cased, cps[j].codePointAt(0))) return false;
|
|
346
|
+
for (j = i + 1; j < cps.length && in_table(ign, cps[j].codePointAt(0)); j++);
|
|
347
|
+
return j === cps.length || !in_table(cased, cps[j].codePointAt(0));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// str.lower(): toLowerCase() is the same full mapping, but it decides σ or ς with the engine's Case_Ignorable and
|
|
351
|
+
// Cased, which changed after 15.0 (U+1171E is no longer case-ignorable), and it knows newer case pairs
|
|
352
|
+
export function lower(s) {
|
|
353
|
+
const out = s.toLowerCase();
|
|
354
|
+
if (!s.includes('\u03a3') && !has_newer(out) && !has_newer(s)) return out;
|
|
355
|
+
const cps = Array.from(s);
|
|
356
|
+
let r = '';
|
|
357
|
+
for (let i = 0; i < cps.length; i++) {
|
|
358
|
+
const c = cps[i];
|
|
359
|
+
r += c === '\u03a3' ? (final_sigma(cps, i) ? '\u03c2' : '\u03c3') : map_char(c, c.toLowerCase());
|
|
360
|
+
}
|
|
361
|
+
return r;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// str.upper() (no context rule: each character on its own)
|
|
365
|
+
export function upper(s) {
|
|
366
|
+
const out = s.toUpperCase();
|
|
367
|
+
if (!has_newer(out) && !has_newer(s)) return out;
|
|
368
|
+
let r = '';
|
|
369
|
+
for (const c of s) r += map_char(c, c.toUpperCase());
|
|
370
|
+
return r;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ---- int() ------------------------------------------------------------------------------------------------------------
|
|
374
|
+
// Python's exceptions where the port raises one on purpose (python: true; see front-native.js)
|
|
375
|
+
export class ValueError extends Error {
|
|
376
|
+
constructor(message) {
|
|
377
|
+
super(message);
|
|
378
|
+
this.name = 'ValueError';
|
|
379
|
+
this.python = true;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
export const type_error = (message) => Object.assign(new TypeError(message), { python: true });
|
|
383
|
+
const MAX_STR_DIGITS = 4300; // sys.get_int_max_str_digits() default
|
|
384
|
+
|
|
385
|
+
// The value of a decimal digit (\p{Nd}): Unicode encodes them in runs of ten, zero to nine.
|
|
386
|
+
const ND = /^\p{Nd}$/u;
|
|
387
|
+
const digitCache = new Map();
|
|
388
|
+
export function digit_value(ch) {
|
|
389
|
+
const cp = ch.codePointAt(0);
|
|
390
|
+
if (cp >= 0x30 && cp <= 0x39) return cp - 0x30;
|
|
391
|
+
let v = digitCache.get(cp);
|
|
392
|
+
if (v === undefined) {
|
|
393
|
+
let zero = cp;
|
|
394
|
+
while (ND.test(String.fromCodePoint(zero - 1))) zero--;
|
|
395
|
+
v = (cp - zero) % 10;
|
|
396
|
+
digitCache.set(cp, v);
|
|
397
|
+
}
|
|
398
|
+
return v;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// int(s) -> BigInt: surrounding whitespace, a sign, decimal digits of any script, single underscores between digits
|
|
402
|
+
export function py_int(s) {
|
|
403
|
+
const t = strip(s);
|
|
404
|
+
let i = 0;
|
|
405
|
+
let neg = false;
|
|
406
|
+
if (t[0] === '+' || t[0] === '-') {
|
|
407
|
+
neg = t[0] === '-';
|
|
408
|
+
i = 1;
|
|
409
|
+
}
|
|
410
|
+
let ascii = '';
|
|
411
|
+
let underscore = false;
|
|
412
|
+
for (const c of t.slice(i)) {
|
|
413
|
+
if (c === '_' && ascii && !underscore) {
|
|
414
|
+
underscore = true;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (!ND.test(c)) throw new ValueError(`invalid literal for int() with base 10: '${s}'`);
|
|
418
|
+
ascii += digit_value(c);
|
|
419
|
+
underscore = false;
|
|
420
|
+
}
|
|
421
|
+
if (!ascii || underscore) throw new ValueError(`invalid literal for int() with base 10: '${s}'`);
|
|
422
|
+
if (ascii.length > MAX_STR_DIGITS) {
|
|
423
|
+
throw new ValueError(`Exceeds the limit (${MAX_STR_DIGITS} digits) for integer string conversion: value has ` +
|
|
424
|
+
`${ascii.length} digits; use sys.set_int_max_str_digits() to increase the limit`);
|
|
425
|
+
}
|
|
426
|
+
const n = BigInt(ascii);
|
|
427
|
+
return neg ? -n : n;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// str(n) for an int
|
|
431
|
+
export function int_str(n) {
|
|
432
|
+
const s = BigInt(n).toString();
|
|
433
|
+
if (s.replace('-', '').length > MAX_STR_DIGITS) {
|
|
434
|
+
throw new ValueError(`Exceeds the limit (${MAX_STR_DIGITS} digits) for integer string conversion; use ` +
|
|
435
|
+
'sys.set_int_max_str_digits() to increase the limit');
|
|
436
|
+
}
|
|
437
|
+
return s;
|
|
438
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Generated by tools/parity/gen_unassigned.py from CPython 3.12.3 (unicodedata 15.0.0); do not edit.
|
|
2
|
+
// The code points that Unicode version leaves unassigned (category Cn), outside the emoji ranges, as the inside
|
|
3
|
+
// of a u-flag regex class.
|
|
4
|
+
export const UNICODE_VERSION = '15.0.0';
|
|
5
|
+
export const UNASSIGNED =
|
|
6
|
+
String.raw`\u{378}-\u{379}\u{380}-\u{383}\u{38b}\u{38d}\u{3a2}\u{530}\u{557}-\u{558}\u{58b}-\u{58c}\u{590}\u{5c8}-\u{5cf}` +
|
|
7
|
+
String.raw`\u{5eb}-\u{5ee}\u{5f5}-\u{5ff}\u{70e}\u{74b}-\u{74c}\u{7b2}-\u{7bf}\u{7fb}-\u{7fc}\u{82e}-\u{82f}\u{83f}` +
|
|
8
|
+
String.raw`\u{85c}-\u{85d}\u{85f}\u{86b}-\u{86f}\u{88f}\u{892}-\u{897}\u{984}\u{98d}-\u{98e}\u{991}-\u{992}\u{9a9}\u{9b1}` +
|
|
9
|
+
String.raw`\u{9b3}-\u{9b5}\u{9ba}-\u{9bb}\u{9c5}-\u{9c6}\u{9c9}-\u{9ca}\u{9cf}-\u{9d6}\u{9d8}-\u{9db}\u{9de}` +
|
|
10
|
+
String.raw`\u{9e4}-\u{9e5}\u{9ff}-\u{a00}\u{a04}\u{a0b}-\u{a0e}\u{a11}-\u{a12}\u{a29}\u{a31}\u{a34}\u{a37}\u{a3a}-\u{a3b}` +
|
|
11
|
+
String.raw`\u{a3d}\u{a43}-\u{a46}\u{a49}-\u{a4a}\u{a4e}-\u{a50}\u{a52}-\u{a58}\u{a5d}\u{a5f}-\u{a65}\u{a77}-\u{a80}` +
|
|
12
|
+
String.raw`\u{a84}\u{a8e}\u{a92}\u{aa9}\u{ab1}\u{ab4}\u{aba}-\u{abb}\u{ac6}\u{aca}\u{ace}-\u{acf}\u{ad1}-\u{adf}` +
|
|
13
|
+
String.raw`\u{ae4}-\u{ae5}\u{af2}-\u{af8}\u{b00}\u{b04}\u{b0d}-\u{b0e}\u{b11}-\u{b12}\u{b29}\u{b31}\u{b34}\u{b3a}-\u{b3b}` +
|
|
14
|
+
String.raw`\u{b45}-\u{b46}\u{b49}-\u{b4a}\u{b4e}-\u{b54}\u{b58}-\u{b5b}\u{b5e}\u{b64}-\u{b65}\u{b78}-\u{b81}\u{b84}` +
|
|
15
|
+
String.raw`\u{b8b}-\u{b8d}\u{b91}\u{b96}-\u{b98}\u{b9b}\u{b9d}\u{ba0}-\u{ba2}\u{ba5}-\u{ba7}\u{bab}-\u{bad}` +
|
|
16
|
+
String.raw`\u{bba}-\u{bbd}\u{bc3}-\u{bc5}\u{bc9}\u{bce}-\u{bcf}\u{bd1}-\u{bd6}\u{bd8}-\u{be5}\u{bfb}-\u{bff}\u{c0d}` +
|
|
17
|
+
String.raw`\u{c11}\u{c29}\u{c3a}-\u{c3b}\u{c45}\u{c49}\u{c4e}-\u{c54}\u{c57}\u{c5b}-\u{c5c}\u{c5e}-\u{c5f}\u{c64}-\u{c65}` +
|
|
18
|
+
String.raw`\u{c70}-\u{c76}\u{c8d}\u{c91}\u{ca9}\u{cb4}\u{cba}-\u{cbb}\u{cc5}\u{cc9}\u{cce}-\u{cd4}\u{cd7}-\u{cdc}\u{cdf}` +
|
|
19
|
+
String.raw`\u{ce4}-\u{ce5}\u{cf0}\u{cf4}-\u{cff}\u{d0d}\u{d11}\u{d45}\u{d49}\u{d50}-\u{d53}\u{d64}-\u{d65}\u{d80}\u{d84}` +
|
|
20
|
+
String.raw`\u{d97}-\u{d99}\u{db2}\u{dbc}\u{dbe}-\u{dbf}\u{dc7}-\u{dc9}\u{dcb}-\u{dce}\u{dd5}\u{dd7}\u{de0}-\u{de5}` +
|
|
21
|
+
String.raw`\u{df0}-\u{df1}\u{df5}-\u{e00}\u{e3b}-\u{e3e}\u{e5c}-\u{e80}\u{e83}\u{e85}\u{e8b}\u{ea4}\u{ea6}\u{ebe}-\u{ebf}` +
|
|
22
|
+
String.raw`\u{ec5}\u{ec7}\u{ecf}\u{eda}-\u{edb}\u{ee0}-\u{eff}\u{f48}\u{f6d}-\u{f70}\u{f98}\u{fbd}\u{fcd}\u{fdb}-\u{fff}` +
|
|
23
|
+
String.raw`\u{10c6}\u{10c8}-\u{10cc}\u{10ce}-\u{10cf}\u{1249}\u{124e}-\u{124f}\u{1257}\u{1259}\u{125e}-\u{125f}\u{1289}` +
|
|
24
|
+
String.raw`\u{128e}-\u{128f}\u{12b1}\u{12b6}-\u{12b7}\u{12bf}\u{12c1}\u{12c6}-\u{12c7}\u{12d7}\u{1311}\u{1316}-\u{1317}` +
|
|
25
|
+
String.raw`\u{135b}-\u{135c}\u{137d}-\u{137f}\u{139a}-\u{139f}\u{13f6}-\u{13f7}\u{13fe}-\u{13ff}\u{169d}-\u{169f}` +
|
|
26
|
+
String.raw`\u{16f9}-\u{16ff}\u{1716}-\u{171e}\u{1737}-\u{173f}\u{1754}-\u{175f}\u{176d}\u{1771}\u{1774}-\u{177f}` +
|
|
27
|
+
String.raw`\u{17de}-\u{17df}\u{17ea}-\u{17ef}\u{17fa}-\u{17ff}\u{181a}-\u{181f}\u{1879}-\u{187f}\u{18ab}-\u{18af}` +
|
|
28
|
+
String.raw`\u{18f6}-\u{18ff}\u{191f}\u{192c}-\u{192f}\u{193c}-\u{193f}\u{1941}-\u{1943}\u{196e}-\u{196f}\u{1975}-\u{197f}` +
|
|
29
|
+
String.raw`\u{19ac}-\u{19af}\u{19ca}-\u{19cf}\u{19db}-\u{19dd}\u{1a1c}-\u{1a1d}\u{1a5f}\u{1a7d}-\u{1a7e}\u{1a8a}-\u{1a8f}` +
|
|
30
|
+
String.raw`\u{1a9a}-\u{1a9f}\u{1aae}-\u{1aaf}\u{1acf}-\u{1aff}\u{1b4d}-\u{1b4f}\u{1b7f}\u{1bf4}-\u{1bfb}\u{1c38}-\u{1c3a}` +
|
|
31
|
+
String.raw`\u{1c4a}-\u{1c4c}\u{1c89}-\u{1c8f}\u{1cbb}-\u{1cbc}\u{1cc8}-\u{1ccf}\u{1cfb}-\u{1cff}\u{1f16}-\u{1f17}` +
|
|
32
|
+
String.raw`\u{1f1e}-\u{1f1f}\u{1f46}-\u{1f47}\u{1f4e}-\u{1f4f}\u{1f58}\u{1f5a}\u{1f5c}\u{1f5e}\u{1f7e}-\u{1f7f}\u{1fb5}` +
|
|
33
|
+
String.raw`\u{1fc5}\u{1fd4}-\u{1fd5}\u{1fdc}\u{1ff0}-\u{1ff1}\u{1ff5}\u{1fff}\u{2065}\u{2072}-\u{2073}\u{208f}` +
|
|
34
|
+
String.raw`\u{209d}-\u{209f}\u{20c1}-\u{20cf}\u{20f1}-\u{20ff}\u{218c}-\u{218f}\u{2427}-\u{243f}\u{244b}-\u{245f}` +
|
|
35
|
+
String.raw`\u{2cf4}-\u{2cf8}\u{2d26}\u{2d28}-\u{2d2c}\u{2d2e}-\u{2d2f}\u{2d68}-\u{2d6e}\u{2d71}-\u{2d7e}\u{2d97}-\u{2d9f}` +
|
|
36
|
+
String.raw`\u{2da7}\u{2daf}\u{2db7}\u{2dbf}\u{2dc7}\u{2dcf}\u{2dd7}\u{2ddf}\u{2e5e}-\u{2e7f}\u{2e9a}\u{2ef4}-\u{2eff}` +
|
|
37
|
+
String.raw`\u{2fd6}-\u{2fef}\u{2ffc}-\u{2fff}\u{3040}\u{3097}-\u{3098}\u{3100}-\u{3104}\u{3130}\u{318f}\u{31e4}-\u{31ef}` +
|
|
38
|
+
String.raw`\u{321f}\u{a48d}-\u{a48f}\u{a4c7}-\u{a4cf}\u{a62c}-\u{a63f}\u{a6f8}-\u{a6ff}\u{a7cb}-\u{a7cf}\u{a7d2}\u{a7d4}` +
|
|
39
|
+
String.raw`\u{a7da}-\u{a7f1}\u{a82d}-\u{a82f}\u{a83a}-\u{a83f}\u{a878}-\u{a87f}\u{a8c6}-\u{a8cd}\u{a8da}-\u{a8df}` +
|
|
40
|
+
String.raw`\u{a954}-\u{a95e}\u{a97d}-\u{a97f}\u{a9ce}\u{a9da}-\u{a9dd}\u{a9ff}\u{aa37}-\u{aa3f}\u{aa4e}-\u{aa4f}` +
|
|
41
|
+
String.raw`\u{aa5a}-\u{aa5b}\u{aac3}-\u{aada}\u{aaf7}-\u{ab00}\u{ab07}-\u{ab08}\u{ab0f}-\u{ab10}\u{ab17}-\u{ab1f}\u{ab27}` +
|
|
42
|
+
String.raw`\u{ab2f}\u{ab6c}-\u{ab6f}\u{abee}-\u{abef}\u{abfa}-\u{abff}\u{d7a4}-\u{d7af}\u{d7c7}-\u{d7ca}\u{d7fc}-\u{d7ff}` +
|
|
43
|
+
String.raw`\u{fa6e}-\u{fa6f}\u{fada}-\u{faff}\u{fb07}-\u{fb12}\u{fb18}-\u{fb1c}\u{fb37}\u{fb3d}\u{fb3f}\u{fb42}\u{fb45}` +
|
|
44
|
+
String.raw`\u{fbc3}-\u{fbd2}\u{fd90}-\u{fd91}\u{fdc8}-\u{fdce}\u{fdd0}-\u{fdef}\u{fe1a}-\u{fe1f}\u{fe53}\u{fe67}` +
|
|
45
|
+
String.raw`\u{fe6c}-\u{fe6f}\u{fe75}\u{fefd}-\u{fefe}\u{ff00}\u{ffbf}-\u{ffc1}\u{ffc8}-\u{ffc9}\u{ffd0}-\u{ffd1}` +
|
|
46
|
+
String.raw`\u{ffd8}-\u{ffd9}\u{ffdd}-\u{ffdf}\u{ffe7}\u{ffef}-\u{fff8}\u{fffe}-\u{ffff}\u{1000c}\u{10027}\u{1003b}` +
|
|
47
|
+
String.raw`\u{1003e}\u{1004e}-\u{1004f}\u{1005e}-\u{1007f}\u{100fb}-\u{100ff}\u{10103}-\u{10106}\u{10134}-\u{10136}` +
|
|
48
|
+
String.raw`\u{1018f}\u{1019d}-\u{1019f}\u{101a1}-\u{101cf}\u{101fe}-\u{1027f}\u{1029d}-\u{1029f}\u{102d1}-\u{102df}` +
|
|
49
|
+
String.raw`\u{102fc}-\u{102ff}\u{10324}-\u{1032c}\u{1034b}-\u{1034f}\u{1037b}-\u{1037f}\u{1039e}\u{103c4}-\u{103c7}` +
|
|
50
|
+
String.raw`\u{103d6}-\u{103ff}\u{1049e}-\u{1049f}\u{104aa}-\u{104af}\u{104d4}-\u{104d7}\u{104fc}-\u{104ff}` +
|
|
51
|
+
String.raw`\u{10528}-\u{1052f}\u{10564}-\u{1056e}\u{1057b}\u{1058b}\u{10593}\u{10596}\u{105a2}\u{105b2}\u{105ba}` +
|
|
52
|
+
String.raw`\u{105bd}-\u{105ff}\u{10737}-\u{1073f}\u{10756}-\u{1075f}\u{10768}-\u{1077f}\u{10786}\u{107b1}` +
|
|
53
|
+
String.raw`\u{107bb}-\u{107ff}\u{10806}-\u{10807}\u{10809}\u{10836}\u{10839}-\u{1083b}\u{1083d}-\u{1083e}\u{10856}` +
|
|
54
|
+
String.raw`\u{1089f}-\u{108a6}\u{108b0}-\u{108df}\u{108f3}\u{108f6}-\u{108fa}\u{1091c}-\u{1091e}\u{1093a}-\u{1093e}` +
|
|
55
|
+
String.raw`\u{10940}-\u{1097f}\u{109b8}-\u{109bb}\u{109d0}-\u{109d1}\u{10a04}\u{10a07}-\u{10a0b}\u{10a14}\u{10a18}` +
|
|
56
|
+
String.raw`\u{10a36}-\u{10a37}\u{10a3b}-\u{10a3e}\u{10a49}-\u{10a4f}\u{10a59}-\u{10a5f}\u{10aa0}-\u{10abf}` +
|
|
57
|
+
String.raw`\u{10ae7}-\u{10aea}\u{10af7}-\u{10aff}\u{10b36}-\u{10b38}\u{10b56}-\u{10b57}\u{10b73}-\u{10b77}` +
|
|
58
|
+
String.raw`\u{10b92}-\u{10b98}\u{10b9d}-\u{10ba8}\u{10bb0}-\u{10bff}\u{10c49}-\u{10c7f}\u{10cb3}-\u{10cbf}` +
|
|
59
|
+
String.raw`\u{10cf3}-\u{10cf9}\u{10d28}-\u{10d2f}\u{10d3a}-\u{10e5f}\u{10e7f}\u{10eaa}\u{10eae}-\u{10eaf}` +
|
|
60
|
+
String.raw`\u{10eb2}-\u{10efc}\u{10f28}-\u{10f2f}\u{10f5a}-\u{10f6f}\u{10f8a}-\u{10faf}\u{10fcc}-\u{10fdf}` +
|
|
61
|
+
String.raw`\u{10ff7}-\u{10fff}\u{1104e}-\u{11051}\u{11076}-\u{1107e}\u{110c3}-\u{110cc}\u{110ce}-\u{110cf}` +
|
|
62
|
+
String.raw`\u{110e9}-\u{110ef}\u{110fa}-\u{110ff}\u{11135}\u{11148}-\u{1114f}\u{11177}-\u{1117f}\u{111e0}` +
|
|
63
|
+
String.raw`\u{111f5}-\u{111ff}\u{11212}\u{11242}-\u{1127f}\u{11287}\u{11289}\u{1128e}\u{1129e}\u{112aa}-\u{112af}` +
|
|
64
|
+
String.raw`\u{112eb}-\u{112ef}\u{112fa}-\u{112ff}\u{11304}\u{1130d}-\u{1130e}\u{11311}-\u{11312}\u{11329}\u{11331}` +
|
|
65
|
+
String.raw`\u{11334}\u{1133a}\u{11345}-\u{11346}\u{11349}-\u{1134a}\u{1134e}-\u{1134f}\u{11351}-\u{11356}` +
|
|
66
|
+
String.raw`\u{11358}-\u{1135c}\u{11364}-\u{11365}\u{1136d}-\u{1136f}\u{11375}-\u{113ff}\u{1145c}\u{11462}-\u{1147f}` +
|
|
67
|
+
String.raw`\u{114c8}-\u{114cf}\u{114da}-\u{1157f}\u{115b6}-\u{115b7}\u{115de}-\u{115ff}\u{11645}-\u{1164f}` +
|
|
68
|
+
String.raw`\u{1165a}-\u{1165f}\u{1166d}-\u{1167f}\u{116ba}-\u{116bf}\u{116ca}-\u{116ff}\u{1171b}-\u{1171c}` +
|
|
69
|
+
String.raw`\u{1172c}-\u{1172f}\u{11747}-\u{117ff}\u{1183c}-\u{1189f}\u{118f3}-\u{118fe}\u{11907}-\u{11908}` +
|
|
70
|
+
String.raw`\u{1190a}-\u{1190b}\u{11914}\u{11917}\u{11936}\u{11939}-\u{1193a}\u{11947}-\u{1194f}\u{1195a}-\u{1199f}` +
|
|
71
|
+
String.raw`\u{119a8}-\u{119a9}\u{119d8}-\u{119d9}\u{119e5}-\u{119ff}\u{11a48}-\u{11a4f}\u{11aa3}-\u{11aaf}` +
|
|
72
|
+
String.raw`\u{11af9}-\u{11aff}\u{11b0a}-\u{11bff}\u{11c09}\u{11c37}\u{11c46}-\u{11c4f}\u{11c6d}-\u{11c6f}` +
|
|
73
|
+
String.raw`\u{11c90}-\u{11c91}\u{11ca8}\u{11cb7}-\u{11cff}\u{11d07}\u{11d0a}\u{11d37}-\u{11d39}\u{11d3b}\u{11d3e}` +
|
|
74
|
+
String.raw`\u{11d48}-\u{11d4f}\u{11d5a}-\u{11d5f}\u{11d66}\u{11d69}\u{11d8f}\u{11d92}\u{11d99}-\u{11d9f}` +
|
|
75
|
+
String.raw`\u{11daa}-\u{11edf}\u{11ef9}-\u{11eff}\u{11f11}\u{11f3b}-\u{11f3d}\u{11f5a}-\u{11faf}\u{11fb1}-\u{11fbf}` +
|
|
76
|
+
String.raw`\u{11ff2}-\u{11ffe}\u{1239a}-\u{123ff}\u{1246f}\u{12475}-\u{1247f}\u{12544}-\u{12f8f}\u{12ff3}-\u{12fff}` +
|
|
77
|
+
String.raw`\u{13456}-\u{143ff}\u{14647}-\u{167ff}\u{16a39}-\u{16a3f}\u{16a5f}\u{16a6a}-\u{16a6d}\u{16abf}` +
|
|
78
|
+
String.raw`\u{16aca}-\u{16acf}\u{16aee}-\u{16aef}\u{16af6}-\u{16aff}\u{16b46}-\u{16b4f}\u{16b5a}\u{16b62}` +
|
|
79
|
+
String.raw`\u{16b78}-\u{16b7c}\u{16b90}-\u{16e3f}\u{16e9b}-\u{16eff}\u{16f4b}-\u{16f4e}\u{16f88}-\u{16f8e}` +
|
|
80
|
+
String.raw`\u{16fa0}-\u{16fdf}\u{16fe5}-\u{16fef}\u{16ff2}-\u{16fff}\u{187f8}-\u{187ff}\u{18cd6}-\u{18cff}` +
|
|
81
|
+
String.raw`\u{18d09}-\u{1afef}\u{1aff4}\u{1affc}\u{1afff}\u{1b123}-\u{1b131}\u{1b133}-\u{1b14f}\u{1b153}-\u{1b154}` +
|
|
82
|
+
String.raw`\u{1b156}-\u{1b163}\u{1b168}-\u{1b16f}\u{1b2fc}-\u{1bbff}\u{1bc6b}-\u{1bc6f}\u{1bc7d}-\u{1bc7f}` +
|
|
83
|
+
String.raw`\u{1bc89}-\u{1bc8f}\u{1bc9a}-\u{1bc9b}\u{1bca4}-\u{1ceff}\u{1cf2e}-\u{1cf2f}\u{1cf47}-\u{1cf4f}` +
|
|
84
|
+
String.raw`\u{1cfc4}-\u{1cfff}\u{1d0f6}-\u{1d0ff}\u{1d127}-\u{1d128}\u{1d1eb}-\u{1d1ff}\u{1d246}-\u{1d2bf}` +
|
|
85
|
+
String.raw`\u{1d2d4}-\u{1d2df}\u{1d2f4}-\u{1d2ff}\u{1d357}-\u{1d35f}\u{1d379}-\u{1d3ff}\u{1d455}\u{1d49d}` +
|
|
86
|
+
String.raw`\u{1d4a0}-\u{1d4a1}\u{1d4a3}-\u{1d4a4}\u{1d4a7}-\u{1d4a8}\u{1d4ad}\u{1d4ba}\u{1d4bc}\u{1d4c4}\u{1d506}` +
|
|
87
|
+
String.raw`\u{1d50b}-\u{1d50c}\u{1d515}\u{1d51d}\u{1d53a}\u{1d53f}\u{1d545}\u{1d547}-\u{1d549}\u{1d551}` +
|
|
88
|
+
String.raw`\u{1d6a6}-\u{1d6a7}\u{1d7cc}-\u{1d7cd}\u{1da8c}-\u{1da9a}\u{1daa0}\u{1dab0}-\u{1deff}\u{1df1f}-\u{1df24}` +
|
|
89
|
+
String.raw`\u{1df2b}-\u{1dfff}\u{1e007}\u{1e019}-\u{1e01a}\u{1e022}\u{1e025}\u{1e02b}-\u{1e02f}\u{1e06e}-\u{1e08e}` +
|
|
90
|
+
String.raw`\u{1e090}-\u{1e0ff}\u{1e12d}-\u{1e12f}\u{1e13e}-\u{1e13f}\u{1e14a}-\u{1e14d}\u{1e150}-\u{1e28f}` +
|
|
91
|
+
String.raw`\u{1e2af}-\u{1e2bf}\u{1e2fa}-\u{1e2fe}\u{1e300}-\u{1e4cf}\u{1e4fa}-\u{1e7df}\u{1e7e7}\u{1e7ec}\u{1e7ef}` +
|
|
92
|
+
String.raw`\u{1e7ff}\u{1e8c5}-\u{1e8c6}\u{1e8d7}-\u{1e8ff}\u{1e94c}-\u{1e94f}\u{1e95a}-\u{1e95d}\u{1e960}-\u{1ec70}` +
|
|
93
|
+
String.raw`\u{1ecb5}-\u{1ed00}\u{1ed3e}-\u{1edff}\u{1ee04}\u{1ee20}\u{1ee23}\u{1ee25}-\u{1ee26}\u{1ee28}\u{1ee33}` +
|
|
94
|
+
String.raw`\u{1ee38}\u{1ee3a}\u{1ee3c}-\u{1ee41}\u{1ee43}-\u{1ee46}\u{1ee48}\u{1ee4a}\u{1ee4c}\u{1ee50}\u{1ee53}` +
|
|
95
|
+
String.raw`\u{1ee55}-\u{1ee56}\u{1ee58}\u{1ee5a}\u{1ee5c}\u{1ee5e}\u{1ee60}\u{1ee63}\u{1ee65}-\u{1ee66}\u{1ee6b}\u{1ee73}` +
|
|
96
|
+
String.raw`\u{1ee78}\u{1ee7d}\u{1ee7f}\u{1ee8a}\u{1ee9c}-\u{1eea0}\u{1eea4}\u{1eeaa}\u{1eebc}-\u{1eeef}` +
|
|
97
|
+
String.raw`\u{1eef2}-\u{1efff}\u{1fb93}\u{1fbcb}-\u{1fbef}\u{1fbfa}-\u{1fbff}\u{1fffe}-\u{1ffff}\u{2a6e0}-\u{2a6ff}` +
|
|
98
|
+
String.raw`\u{2b73a}-\u{2b73f}\u{2b81e}-\u{2b81f}\u{2cea2}-\u{2ceaf}\u{2ebe1}-\u{2f7ff}\u{2fa1e}-\u{2ffff}` +
|
|
99
|
+
String.raw`\u{3134b}-\u{3134f}\u{323b0}-\u{e0000}\u{e0002}-\u{e001f}\u{e0080}-\u{e00ff}\u{e01f0}-\u{effff}` +
|
|
100
|
+
String.raw`\u{ffffe}-\u{fffff}\u{10fffe}-\u{10ffff}`;
|