xshell 1.2.57 → 1.2.59

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.
@@ -1,651 +1,86 @@
1
- /** 在浏览器端修改 prototype,需要更加小心 */
2
- import EmojiRegex from 'emoji-regex';
3
- import { t } from "./i18n/instance.js";
4
- export const emoji_regex = EmojiRegex();
5
- export const noop = () => { };
6
- export const ident = (x) => x;
7
- export const select = (key) => (obj) => obj[key];
8
- /** value 不为 null 或 undefined */
9
- export const not_empty = (value) => value !== null && value !== undefined;
10
- export const empty = (value) => value === undefined || value === null;
11
- const key_types = ['string', 'number', 'symbol'];
12
- export const is_key_type = ((key) => key_types.includes(typeof key));
13
- export function rethrow(error) {
14
- throw error;
15
- }
16
- export function to_snake_case(str) {
17
- return str.replace(/([A-Z])/g, '_$1')
18
- .toLowerCase()
19
- .replace('-', '_')
20
- .strip_if_start('_');
21
- }
22
- export function to_method_property_descriptors(methods) {
23
- return Object.fromEntries(Object.entries(methods)
24
- .map(([name, value]) => ([name, {
25
- configurable: true,
26
- writable: true,
27
- enumerable: false,
28
- value,
29
- }])));
30
- }
31
- export function to_getter_property_descriptors(getters) {
32
- return Object.fromEntries(Object.entries(getters)
33
- .map(([name, get]) => ([name, {
34
- configurable: true,
35
- enumerable: false,
36
- get,
37
- }])));
38
- }
39
- export const cjk = '([\u2e80-\u9fff\uf900-\ufaff])';
40
- export const quotes = {
41
- single: "'",
42
- double: '"',
43
- backtick: '`',
44
- };
45
- export const brackets = {
46
- round: ['(', ')'],
47
- square: ['[', ']'],
48
- curly: ['{', '}'],
49
- pointy: ['<', '>'],
50
- corner: ['「', '」'],
51
- fat: ['【', '】'],
52
- tortoise_shell: ['〔', '〕'],
53
- };
54
- // ------------------------------------ String.prototype
55
- Object.defineProperties(String.prototype, {
56
- ...to_getter_property_descriptors({
57
- width() {
58
- const s = this.replace(emoji_regex, ' ');
59
- let width = 0;
60
- for (let i = 0; i < s.length; i++) {
61
- const code = s.codePointAt(i);
62
- if ((code <= 0x1f || (code >= 0x7f && code <= 0x9f)) || // ignore control characters
63
- code >= 0x300 && code <= 0x36f // ignore combining characters
64
- )
65
- continue;
66
- // surrogates
67
- if (code > 0xffff)
68
- i++;
69
- width += is_codepoint_fullwidth(code) ? 2 : 1;
70
- }
71
- return width;
72
- }
73
- }),
74
- // ------------ 文本处理工具方法
75
- ...to_method_property_descriptors({
76
- /** 截取字符串不超过 width 显示宽度的部分,并保留颜色
77
- 找到并记录能容纳 字符串 + … 的最后一个字符的位置 i_fitted
78
- - 若完整的字符串长度超过 width,返回 slice(0, i_fitted + 1) + …
79
- - 否则 返回 this
80
- */
81
- truncate(width) {
82
- const color_bak = this.startsWith('\u001b') ? this.slice(0, 5) : '';
83
- if (width <= 2)
84
- return this.slice(0, width);
85
- let i_fitted = 0;
86
- let fitted_width = 0;
87
- let cur_width = 0;
88
- for (let i = 0; i < this.length; i++) {
89
- const code = this.codePointAt(i);
90
- if ((code <= 0x1F || (code >= 0x7F && code <= 0x9F)) || // Ignore control characters
91
- code >= 0x300 && code <= 0x36F // Ignore combining characters
92
- )
93
- continue;
94
- // surrogates (codepoint 需要用两个 utf-16 编码单位表示,因此这里跳过第二个编码单位,防止重复计算显示宽度)
95
- if (code > 0xFFFF)
96
- i++;
97
- const w = is_codepoint_fullwidth(code) ? 2 : 1;
98
- if (cur_width + w + 2 <= width) {
99
- i_fitted = i;
100
- fitted_width += w;
101
- }
102
- cur_width += w;
103
- if (cur_width > width) {
104
- const i_fitted_next = i_fitted + 1;
105
- const t = this.slice(0, i_fitted_next) + ' '.repeat(width - 2 - fitted_width) + '…';
106
- return color_bak ? color_bak + t + '\u001b[39m' : t;
1
+ import { emoji_regex, cjk, to_getter_property_descriptors, to_method_property_descriptors, is_codepoint_fullwidth } from "./prototype.common.js";
2
+ export * from "./prototype.common.js";
3
+ if (!globalThis.my_prototype_defined) {
4
+ // ------------------------------------ String.prototype
5
+ Object.defineProperties(String.prototype, {
6
+ ...to_getter_property_descriptors({
7
+ width() {
8
+ const s = this.replace(emoji_regex, ' ');
9
+ let width = 0;
10
+ for (let i = 0; i < s.length; i++) {
11
+ const code = s.codePointAt(i);
12
+ if ((code <= 0x1f || (code >= 0x7f && code <= 0x9f)) || // ignore control characters
13
+ code >= 0x300 && code <= 0x36f // ignore combining characters
14
+ )
15
+ continue;
16
+ // surrogates
17
+ if (code > 0xffff)
18
+ i++;
19
+ width += is_codepoint_fullwidth(code) ? 2 : 1;
107
20
  }
21
+ return width;
108
22
  }
109
- return this;
110
- },
111
- pad(width, { character = ' ', position = 'right' } = {}) {
112
- const _width = this.width;
113
- if (_width >= width)
114
- return this;
115
- if (position === 'right')
116
- return this + character.repeat((width - _width) / character.width);
117
- return character.repeat(width - _width) + this;
118
- },
119
- limit(width, { character = ' ', position = 'right' } = {}) {
120
- return this.pad(width, { character, position }).truncate(width);
121
- },
122
- to_regexp(preservations, flags = '') {
123
- const preserved_chars = new Set(preservations);
124
- const replace_chars = Array.prototype.filter.call('|\\{}()[]^$+*?.-', (c) => !preserved_chars.has(c))
125
- .map((c) => c === ']' ? '\\]' : c).join('');
126
- return new RegExp(this.replace(new RegExp(`[${replace_chars}]`, 'g'), '\\$&'), flags);
127
- },
128
- to_snake_case() {
129
- return to_snake_case(this);
130
- },
131
- refmt(pattern, pattern_, preservations = '', flags = '', transformer = (name, value) => value || '', pattern_placeholder = /\{.*?\}/g) {
132
- // --- 转换 pattern 为 pattern_regx
133
- let last_end = 0;
134
- // placeholder matched group indexes
135
- let $placeholders = {};
136
- let regx_parts = [];
137
- function add_part(left, right) {
138
- const part = pattern.slice(left, right);
139
- if (part)
140
- regx_parts.push(part.to_regexp(preservations).source.bracket());
141
- }
142
- pattern.replace(pattern_placeholder, ($0, offset) => {
143
- add_part(last_end, offset);
144
- last_end = offset + $0.length;
145
- const placeholder = $0.slice(1, -1);
146
- let [placeholder_name, placeholder_pattern] = placeholder.split(':').map(s => s.trim());
147
- let optional = false;
148
- if (placeholder_name.endsWith('?')) {
149
- placeholder_name = placeholder_name.slice(0, -1);
150
- optional = true;
23
+ }),
24
+ // ------------ 文本处理工具方法
25
+ ...to_method_property_descriptors({
26
+ /** 截取字符串不超过 width 显示宽度的部分,并保留颜色
27
+ 找到并记录能容纳 字符串 + … 的最后一个字符的位置 i_fitted
28
+ - 若完整的字符串长度超过 width,返回 slice(0, i_fitted + 1) + …
29
+ - 否则 返回 this
30
+ */
31
+ truncate(width) {
32
+ const color_bak = this.startsWith('\u001b') ? this.slice(0, 5) : '';
33
+ if (width <= 2)
34
+ return this.slice(0, width);
35
+ let i_fitted = 0;
36
+ let fitted_width = 0;
37
+ let cur_width = 0;
38
+ for (let i = 0; i < this.length; i++) {
39
+ const code = this.codePointAt(i);
40
+ if ((code <= 0x1F || (code >= 0x7F && code <= 0x9F)) || // Ignore control characters
41
+ code >= 0x300 && code <= 0x36F // Ignore combining characters
42
+ )
43
+ continue;
44
+ // surrogates (codepoint 需要用两个 utf-16 编码单位表示,因此这里跳过第二个编码单位,防止重复计算显示宽度)
45
+ if (code > 0xFFFF)
46
+ i++;
47
+ const w = is_codepoint_fullwidth(code) ? 2 : 1;
48
+ if (cur_width + w + 2 <= width) {
49
+ i_fitted = i;
50
+ fitted_width += w;
51
+ }
52
+ cur_width += w;
53
+ if (cur_width > width) {
54
+ const i_fitted_next = i_fitted + 1;
55
+ const t = this.slice(0, i_fitted_next) + ' '.repeat(width - 2 - fitted_width) + '…';
56
+ return color_bak ? color_bak + t + '\u001b[39m' : t;
57
+ }
151
58
  }
152
- $placeholders[placeholder_name] = regx_parts.push(placeholder_pattern ?
153
- `${placeholder_pattern.bracket()}${optional ? '?' : ''}`
154
- :
155
- '(.*?)');
156
- return '';
157
- });
158
- add_part(last_end);
159
- // 最后一个 (.*?) 改为贪心匹配,满足 .{suffix} 的需要
160
- regx_parts = regx_parts.filter(part => part);
161
- if (regx_parts[regx_parts.length - 1] === '(.*?)')
162
- regx_parts[regx_parts.length - 1] = '(.*)';
163
- const pattern_regx = new RegExp(regx_parts.join(''), flags);
164
- // --- 根据 pattern_regx 去匹配原有字符串,获取匹配结果,生成 placeholders 词典
165
- const matches = pattern_regx.exec(this);
166
- if (!matches)
167
59
  return this;
168
- const placeholders = Object.fromEntries(Object.entries($placeholders)
169
- .map(([name, $i]) => [
170
- [name, matches[$i]],
171
- [`${name}.before`, matches[$i - 1] || ''],
172
- [`${name}.after`, matches[$i + 1] || ''],
173
- ])
174
- .flat());
175
- // --- 转换 pattern_ 为 replacement_str,如果有 transformer 则在遇到 placeholder 时应用
176
- last_end = 0;
177
- let replacement_parts = [];
178
- pattern_.replace(pattern_placeholder, ($0, offset) => {
179
- replacement_parts.push(pattern_.slice(last_end, offset));
180
- last_end = offset + $0.length;
181
- const placeholder_name = $0.slice(1, -1);
182
- replacement_parts.push(transformer(placeholder_name, placeholders[placeholder_name], placeholders));
183
- return '';
184
- });
185
- replacement_parts.push(pattern_.slice(last_end));
186
- return this.replace(pattern_regx, replacement_parts.join(''));
187
- },
188
- find(pattern, preservations = '', flags = '', pattern_placeholder = /\{.*?\}/g) {
189
- // --- 转换 pattern 为 pattern_regx
190
- let last_end = 0;
191
- // placeholder matched group index
192
- let $placeholders = {};
193
- let regx_parts = [];
194
- function add_part(left, right) {
195
- const part = pattern.slice(left, right);
196
- if (part)
197
- regx_parts.push(part.to_regexp(preservations).source.bracket());
198
- }
199
- pattern.replace(pattern_placeholder, ($0, offset) => {
200
- add_part(last_end, offset);
201
- last_end = offset + $0.length;
202
- const placeholder = $0.slice(1, -1);
203
- let [placeholder_name, placeholder_pattern] = placeholder.split(':').map(s => s.trim());
204
- let optional = false;
205
- if (placeholder_name.endsWith('?')) {
206
- placeholder_name = placeholder_name.slice(0, -1);
207
- optional = true;
208
- }
209
- $placeholders[placeholder_name] = regx_parts.push(placeholder_pattern ?
210
- `${placeholder_pattern.bracket()}${optional ? '?' : ''}`
211
- :
212
- '(.*?)');
213
- return '';
214
- });
215
- add_part(last_end);
216
- // 最后一个 (.*?) 改为贪心匹配,满足 .{suffix} 的需要
217
- regx_parts = regx_parts.filter(part => part);
218
- if (regx_parts[regx_parts.length - 1] === '(.*?)')
219
- regx_parts[regx_parts.length - 1] = '(.*)';
220
- const pattern_regx = new RegExp(regx_parts.join(''), flags);
221
- // --- 根据 pattern_regx 去匹配原有字符串,获取匹配结果,生成 placeholders 词典
222
- const matches = pattern_regx.exec(this);
223
- if (!matches)
224
- return {};
225
- return Object.fromEntries(Object.entries($placeholders)
226
- .map(([name, $i]) => [name, matches[$i] || '']));
227
- },
228
- /** 查找子串或字符出现的次数 */
229
- count(search) {
230
- if (!search)
231
- throw new Error('count 的 search 不能为空');
232
- let count = 0;
233
- for (let i = 0; (i = this.indexOf(search, i)) !== -1; i += search.length)
234
- count++;
235
- return count;
236
- },
237
- quote(type = 'single') {
238
- if (type === 'psh')
239
- return `& ${this.quote()}`;
240
- return this.surround(quotes[type]);
241
- },
242
- bracket(shape = 'round') {
243
- return this.surround(...brackets[shape]);
244
- },
245
- surround(left, right) {
246
- return left + this + (right || left);
247
- },
248
- surround_tag(tag_name) {
249
- return '<' + tag_name + '>' + this + '</' + tag_name + '>';
250
- },
251
- to_lf() {
252
- return this.replace(/\r\n/g, '\n');
253
- },
254
- rm(pattern, flags = 'g') {
255
- if (typeof pattern === 'string')
256
- pattern = new RegExp(pattern, flags);
257
- return this.replace(pattern, '');
258
- },
259
- split_lines(delimiter = /\r?\n/) {
260
- let lines = this.split(delimiter);
261
- if (lines[lines.length - 1] === '')
262
- lines.pop();
263
- return lines;
264
- },
265
- split_indent() {
266
- let i = 0;
267
- let indent = 0;
268
- for (; i < this.length; i++)
269
- if (this[i] === ' ')
270
- indent++;
271
- else if (this[i] === '\t')
272
- indent += 4;
273
- else
274
- break;
275
- return {
276
- indent,
277
- text: this.slice(i)
278
- };
279
- },
280
- split2(splitter, { last = false, optional = false } = {}) {
281
- const isplitter = last ? this.lastIndexOf(splitter) : this.indexOf(splitter);
282
- if (isplitter === -1)
283
- if (optional)
284
- return [this];
285
- else
286
- throw new Error(`字符串: ${this} 必须包含 splitter: ${splitter}`);
287
- return [this.slice(0, isplitter), this.slice(isplitter + splitter.length)];
288
- },
289
- strip_start(prefix, validate) {
290
- if (validate && !this.startsWith(prefix))
291
- throw new Error(`字符串没有以前缀 ${prefix} 开头: ${this}`);
292
- return this.slice(prefix.length);
293
- },
294
- strip_if_start(prefix) {
295
- return this.startsWith(prefix) ? this.slice(prefix.length) : this;
296
- },
297
- strip_end(suffix, validate) {
298
- if (validate && !this.endsWith(suffix))
299
- throw new Error(`字符串没有以后缀 ${suffix} 结尾: ${this}`);
300
- return this.slice(0, -suffix.length);
301
- },
302
- strip_if_end(suffix) {
303
- return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this;
304
- },
305
- ensure_start(prefix) {
306
- return this.startsWith(prefix) ? this : prefix + this;
307
- },
308
- ensure_end(suffix = '\n') {
309
- return this.endsWith(suffix) ? this : this + suffix;
310
- },
311
- slice_from(search, { include = false, last = false, optional = false } = {}) {
312
- const i = last ? this.lastIndexOf(search) : this.indexOf(search);
313
- if (i === -1)
314
- if (optional)
315
- return this;
316
- else
317
- throw new Error(`slice_from 在字符串 ${this} 中找不到 search: ${search}`);
318
- else
319
- return this.slice(include ? i : i + search.length);
320
- },
321
- slice_to(search, { include = false, last = false, optional = false } = {}) {
322
- const i = last ? this.lastIndexOf(search) : this.indexOf(search);
323
- if (i === -1)
324
- if (optional)
60
+ },
61
+ space() {
62
+ if (!this)
325
63
  return this;
326
- else
327
- throw new Error(`slice_to 在字符串 ${this} 中找不到 search: ${search}`);
328
- else
329
- return this.slice(0, include ? i + search.length : i);
330
- },
331
- space() {
332
- if (!this)
333
- return this;
334
- let text_;
335
- text_ = this
336
- .replace(new RegExp(cjk + '([\'"])', 'g'), '$1 $2')
337
- .replace(new RegExp('([\'"])' + cjk, 'g'), '$1 $2')
338
- .replace(/(["']+)\s*(.+?)\s*(["']+)/g, '$1$2$3')
339
- .replace(new RegExp(cjk + '([\\+\\-\\*\\/=&\\\\\\|<>])([A-Za-z0-9])', 'g'), '$1 $2 $3')
340
- .replace(new RegExp('([A-Za-z0-9])([\\+\\-\\*\\/=&\\\\\\|<>])' + cjk, 'g'), '$1$2 $3');
341
- const text_bak = text_;
342
- text_ = text_.replace(new RegExp(cjk + '([\\(\\[\\{<\u201c]+(.*?)[\\)\\]\\}>\u201d]+)' + cjk, 'g'), '$1 $2 $4');
343
- if (text_ === text_bak)
344
- text_ = text_
345
- .replace(new RegExp(cjk + '([\\(\\[\\{<\u201c>])', 'g'), '$1 $2')
346
- .replace(new RegExp('([\\)\\]\\}>\u201d<])' + cjk, 'g'), '$1 $2');
347
- return text_
348
- .replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5')
349
- .replace(new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'), '$1$2 $3')
350
- .replace(new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'), '$1 $2')
351
- .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
352
- }
353
- }),
354
- // ------------ 文件路径操作
355
- ...to_getter_property_descriptors({
356
- isdir() {
357
- return this.endsWith('/');
358
- },
359
- fp() {
360
- if (!this)
361
- return this;
362
- const fp = this.replaceAll('\\', '/');
363
- // 转换小写盘符开头的路径
364
- return fp[1] === ':' && 'a' <= fp[0] && fp[0] <= 'z'
365
- ? fp[0].toUpperCase() + fp.slice(1)
366
- : fp;
367
- },
368
- fpd() {
369
- const { fp } = this;
370
- return fp.endsWith('/') ? fp : `${fp}/`;
371
- },
372
- fdir() {
373
- return this.fp.strip_end(this.fname);
374
- },
375
- fname() {
376
- const { fp } = this;
377
- const ilast = fp.lastIndexOf('/');
378
- if (ilast === -1)
379
- return fp; // 没有斜杠时返回整个字符串
380
- // 以斜杠结尾的情况
381
- if (ilast === fp.length - 1) {
382
- const iprev = fp.lastIndexOf('/', ilast - 1);
383
- return iprev === -1
384
- ? fp // 只有一个斜杠且在末尾
385
- : fp.slice(iprev + 1);
386
- }
387
- // 返回最后一个斜杠后的内容
388
- return fp.slice(ilast + 1);
389
- },
390
- fext() {
391
- const { fname } = this;
392
- const index = fname.lastIndexOf('.');
393
- return index <= 0
394
- ? ''
395
- : fname.slice(index + 1);
396
- }
397
- })
398
- });
399
- // ------------------------------------ Date.prototype
400
- Object.defineProperties(Date.prototype, to_method_property_descriptors({
401
- to_str(ms) {
402
- return `${this.to_date_str()} ${this.to_time_str(ms)}`;
403
- },
404
- to_date_str() {
405
- // 2024.01.01
406
- return this.getFullYear() + '.' +
407
- String(this.getMonth() + 1).padStart(2, '0') + '.' +
408
- String(this.getDate()).padStart(2, '0');
409
- },
410
- to_time_str(ms) {
411
- // 早上 09:00:00
412
- const [ampm, hour] = get_twelve_hour_clock(this);
413
- return `${ampm} ${get_time_str(this, hour, ms, ':')}`;
414
- },
415
- to_dot_time_str(ms) {
416
- // 17.03.02
417
- return get_time_str(this, this.getHours(), ms, '.');
418
- },
419
- to_dot_str(ms) {
420
- return `${this.to_date_str()} ${this.to_dot_time_str(ms)}`;
421
- },
422
- to_formal_time_str(ms) {
423
- // 17:03:02
424
- return get_time_str(this, this.getHours(), ms, ':');
425
- },
426
- to_formal_str(ms) {
427
- return `${this.to_date_str()} ${this.to_formal_time_str(ms)}`;
428
- }
429
- }));
430
- function get_twelve_hour_clock(date) {
431
- let hour = date.getHours();
432
- if (hour <= 6)
433
- return [t('凌晨'), hour];
434
- if (hour <= 8)
435
- return [t('清晨'), hour];
436
- if (hour <= 9)
437
- return [t('早上'), hour];
438
- if (hour <= 10)
439
- return [t('上午'), hour];
440
- if (hour <= 12)
441
- return [t('中午'), hour];
442
- hour -= 12;
443
- if (hour <= 5)
444
- return [t('下午'), hour];
445
- if (hour <= 10)
446
- return [t('晚上'), hour];
447
- return [t('深夜'), hour];
448
- }
449
- function get_time_str(date, hour, ms, splitter) {
450
- return String(hour).padStart(2, '0') + splitter +
451
- String(date.getMinutes()).padStart(2, '0') + splitter +
452
- String(date.getSeconds()).padStart(2, '0') +
453
- (ms
454
- ? '.' + String(date.getMilliseconds()).padStart(3, '0')
455
- : '');
456
- }
457
- // ------------------------------------ Number.prototype
458
- Object.defineProperties(Number.prototype, to_method_property_descriptors({
459
- to_fsize_str() {
460
- return byte_size(this);
461
- },
462
- to_bin_str() {
463
- return `0b${this.toString(2)}`;
464
- },
465
- to_hex_str(length) {
466
- const s = Math.abs(this).toString(16);
467
- // 长度自动对齐到 4 的倍数
468
- if (length === undefined)
469
- length = Math.ceil(s.length / 4) * 4;
470
- return `${this < 0 ? '-' : ''}0x${'0'.repeat(length - s.length)}${s}`;
471
- },
472
- to_oct_str() {
473
- return `0o${this.toString(8)}`;
474
- },
475
- }));
476
- // ------------------------------------ Array.prototype
477
- Object.defineProperties(Array.prototype, {
478
- ...to_getter_property_descriptors({
479
- last() {
480
- return this.at(-1);
481
- }
482
- }),
483
- // --- 文本处理工具方法
484
- ...to_method_property_descriptors({
485
- trim_lines({ trim_line = true, rm_empty_lines = true, rm_last_empty_lines = false } = {}) {
486
- if (!this.length)
487
- return this;
488
- let lines = this;
489
- if (trim_line)
490
- lines = lines.map(line => line.trim());
491
- if (rm_empty_lines)
492
- return lines.filter(Boolean);
493
- if (rm_last_empty_lines) {
494
- lines.reverse();
495
- const i_not_empty = lines.findIndex(Boolean);
496
- if (i_not_empty !== -1)
497
- lines = lines.slice(i_not_empty);
498
- lines.reverse();
499
- return lines;
64
+ let text_;
65
+ text_ = this
66
+ .replace(new RegExp(cjk + '([\'"])', 'g'), '$1 $2')
67
+ .replace(new RegExp('([\'"])' + cjk, 'g'), '$1 $2')
68
+ .replace(/(["']+)\s*(.+?)\s*(["']+)/g, '$1$2$3')
69
+ .replace(new RegExp(cjk + '([\\+\\-\\*\\/=&\\\\\\|<>])([A-Za-z0-9])', 'g'), '$1 $2 $3')
70
+ .replace(new RegExp('([A-Za-z0-9])([\\+\\-\\*\\/=&\\\\\\|<>])' + cjk, 'g'), '$1 $2 $3');
71
+ const text_bak = text_;
72
+ text_ = text_.replace(new RegExp(cjk + '([\\(\\[\\{<\u201c]+(.*?)[\\)\\]\\}>\u201d]+)' + cjk, 'g'), '$1 $2 $4');
73
+ if (text_ === text_bak)
74
+ text_ = text_
75
+ .replace(new RegExp(cjk + '([\\(\\[\\{<\u201c>])', 'g'), '$1 $2')
76
+ .replace(new RegExp('([\\)\\]\\}>\u201d<])' + cjk, 'g'), '$1$2');
77
+ return text_
78
+ .replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5')
79
+ .replace(new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'), '$1$2 $3')
80
+ .replace(new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'), '$1 $2')
81
+ .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
500
82
  }
501
- return lines;
502
- },
503
- indent(width = 4, character = ' ') {
504
- const indent = character.repeat(width);
505
- return this.map(line => indent + line);
506
- },
507
- sum(zero, mapper) {
508
- if (!this.length)
509
- return undefined;
510
- // 快捷路径
511
- const first = this[0];
512
- if ((typeof first === 'number' || typeof first === 'bigint') && !mapper)
513
- return this.reduce((acc, x) => acc + x, zero);
514
- if (is_key_type(mapper))
515
- mapper = select(mapper);
516
- mapper ??= ident;
517
- return this.reduce((acc, x) => acc + mapper(x), zero);
518
- },
519
- max(mapper = ident) {
520
- if (!this.length)
521
- return undefined;
522
- if (is_key_type(mapper))
523
- mapper = select(mapper);
524
- let max = mapper(this[0]);
525
- let imax = 0;
526
- for (let i = 0; i < this.length; i++) {
527
- const value = mapper(this[i]);
528
- if (value > max) {
529
- max = value;
530
- imax = i;
531
- }
532
- }
533
- return this[imax];
534
- },
535
- min(mapper = ident) {
536
- if (!this.length)
537
- return undefined;
538
- if (is_key_type(mapper))
539
- mapper = select(mapper);
540
- let min = mapper(this[0]);
541
- let imin = 0;
542
- for (let i = 0; i < this.length; i++) {
543
- const value = mapper(this[i]);
544
- if (value < min) {
545
- min = value;
546
- imin = i;
547
- }
548
- }
549
- return this[imin];
550
- },
551
- unique(mapper) {
552
- if (!mapper)
553
- return [...new Set(this)];
554
- if (is_key_type(mapper))
555
- mapper = select(mapper);
556
- let map = new Map();
557
- for (const x of this)
558
- map.set(mapper(x), x);
559
- return [...map.values()];
560
- },
561
- join_lines(append = Boolean(this.length)) {
562
- return `${this.join('\n')}${append ? '\n' : ''}`;
563
- }
564
- })
565
- });
566
- Object.defineProperties(BigInt.prototype, to_method_property_descriptors({
567
- to_fsize_str() {
568
- return byte_size(this);
569
- },
570
- toJSON() {
571
- return this.toString();
572
- }
573
- }));
574
- Object.defineProperties(Error.prototype, to_method_property_descriptors({
575
- toJSON() {
576
- return Object.fromEntries(Object.getOwnPropertyNames(this)
577
- .map(name => [name, this[name]]));
578
- }
579
- }));
580
- Object.defineProperties(Set.prototype, to_method_property_descriptors({
581
- map(mapfn) {
582
- return Array.from(this, mapfn);
583
- }
584
- }));
585
- Object.defineProperties(Uint8Array.prototype, to_getter_property_descriptors({
586
- dataview() {
587
- return new DataView(this.buffer, this.byteOffset, this.byteLength);
588
- }
589
- }));
590
- export function to_json(obj, replacer) {
591
- return JSON.stringify(obj, replacer, 4) + '\n';
592
- }
593
- export function is_codepoint_fullwidth(codepoint) {
594
- // code points are derived from:
595
- // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
596
- return (!Number.isNaN(codepoint) &&
597
- codepoint >= 0x1100 &&
598
- (codepoint <= 0x115f || // hangul jamo
599
- codepoint === 0x201c || codepoint === 0x201d || //
600
- codepoint === 0x2026 || // …
601
- codepoint === 0x203b || // ※
602
- // arrows
603
- (0x2190 <= codepoint && codepoint <= 0x21FF) ||
604
- codepoint === 0x2329 || // left-pointing angle bracket
605
- codepoint === 0x232a || // right-pointing angle bracket
606
- // ①
607
- (0x2460 <= codepoint && codepoint <= 0x24ff) ||
608
- // box drawing
609
- (0x2500 <= codepoint && codepoint <= 0x257f) ||
610
- // shapes, symbols, …
611
- (0x2580 <= codepoint && codepoint <= 0x2bef) ||
612
- // cjk radicals supplement .. enclosed cjk letters and months
613
- (0x2e80 <= codepoint && codepoint <= 0x3247 && codepoint !== 0x303f) ||
614
- // enclosed cjk letters and months .. cjk unified ideographs extension a
615
- (0x3250 <= codepoint && codepoint <= 0x4dbf) ||
616
- // cjk unified ideographs .. yi radicals
617
- (0x4E00 <= codepoint && codepoint <= 0xA4C6) ||
618
- // hangul jamo extended-a
619
- (0xa960 <= codepoint && codepoint <= 0xa97c) ||
620
- // hangul syllables
621
- (0xac00 <= codepoint && codepoint <= 0xd7a3) ||
622
- // cjk compatibility ideographs
623
- (0xf900 <= codepoint && codepoint <= 0xfaff) ||
624
- // vertical forms
625
- (0xfe10 <= codepoint && codepoint <= 0xfe19) ||
626
- // cjk compatibility forms .. small form variants
627
- (0xfe30 <= codepoint && codepoint <= 0xfe6b) ||
628
- // halfwidth and fullwidth forms
629
- (0xff01 <= codepoint && codepoint <= 0xff60) ||
630
- (0xffe0 <= codepoint && codepoint <= 0xffe6) ||
631
- // kana supplement
632
- (0x1b000 <= codepoint && codepoint <= 0x1b001) ||
633
- // enclosed ideographic supplement
634
- (0x1f200 <= codepoint && codepoint <= 0x1f251) ||
635
- // cjk unified ideographs extension b .. tertiary ideographic plane
636
- (0x20000 <= codepoint && codepoint <= 0x3fffd)));
637
- }
638
- const units = ['b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
639
- const bytes_table = units.map((unit, i) => ({
640
- start: i === 0 ? 0 : 2 ** (i * 10),
641
- end: 2 ** ((i + 1) * 10),
642
- unit
643
- }));
644
- export function byte_size(bytes) {
645
- bytes = Number(bytes);
646
- const sign = bytes < 0 ? '-' : '';
647
- bytes = Math.abs(bytes);
648
- const { unit, start } = bytes_table.find(range => bytes >= range.start && bytes < range.end);
649
- return `${sign}${start === 0 ? bytes : (bytes / start).toFixed()} ${unit}`;
83
+ })
84
+ });
650
85
  }
651
86
  //# sourceMappingURL=prototype.browser.js.map