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