@pawover/kit 0.0.0-beta.9 → 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.
Files changed (47) hide show
  1. package/package.json +94 -70
  2. package/packages/hooks/dist/alova.d.ts +30 -0
  3. package/packages/hooks/dist/alova.js +64 -0
  4. package/packages/hooks/dist/index.d.ts +1 -0
  5. package/packages/hooks/dist/index.js +0 -0
  6. package/packages/hooks/dist/metadata.json +15 -0
  7. package/packages/hooks/dist/react.d.ts +155 -0
  8. package/packages/hooks/dist/react.js +2678 -0
  9. package/packages/utils/dist/index.d.ts +4884 -0
  10. package/packages/utils/dist/index.js +1741 -0
  11. package/packages/utils/dist/math.d.ts +58 -0
  12. package/packages/utils/dist/math.js +56 -0
  13. package/packages/utils/dist/metadata.json +14 -0
  14. package/packages/utils/dist/string-C_OCj9Lg.js +950 -0
  15. package/packages/utils/dist/vite.d.ts +29 -0
  16. package/packages/utils/dist/vite.js +39 -0
  17. package/packages/zod/dist/index.d.ts +58 -0
  18. package/packages/zod/dist/index.js +61 -0
  19. package/dist/enums.d.ts +0 -25
  20. package/dist/enums.d.ts.map +0 -1
  21. package/dist/enums.js +0 -25
  22. package/dist/enums.js.map +0 -1
  23. package/dist/hooks-alova.d.ts +0 -23
  24. package/dist/hooks-alova.d.ts.map +0 -1
  25. package/dist/hooks-alova.js +0 -39
  26. package/dist/hooks-alova.js.map +0 -1
  27. package/dist/hooks-react.d.ts +0 -95
  28. package/dist/hooks-react.d.ts.map +0 -1
  29. package/dist/hooks-react.js +0 -328
  30. package/dist/hooks-react.js.map +0 -1
  31. package/dist/index.d.ts +0 -3726
  32. package/dist/index.d.ts.map +0 -1
  33. package/dist/index.js +0 -1469
  34. package/dist/index.js.map +0 -1
  35. package/dist/patches-fetchEventSource.d.ts +0 -815
  36. package/dist/patches-fetchEventSource.d.ts.map +0 -1
  37. package/dist/patches-fetchEventSource.js +0 -316
  38. package/dist/patches-fetchEventSource.js.map +0 -1
  39. package/dist/vite.d.ts +0 -13
  40. package/dist/vite.d.ts.map +0 -1
  41. package/dist/vite.js +0 -23
  42. package/dist/vite.js.map +0 -1
  43. package/dist/zod.d.ts +0 -109
  44. package/dist/zod.d.ts.map +0 -1
  45. package/dist/zod.js +0 -143
  46. package/dist/zod.js.map +0 -1
  47. package/metadata.json +0 -167
@@ -0,0 +1,2678 @@
1
+ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
2
+ //#region src/react/useLatest.ts
3
+ /**
4
+ * 返回当前最新值的 Hook
5
+ *
6
+ * @param value
7
+ */
8
+ function useLatest(value) {
9
+ const ref = useRef(value);
10
+ ref.current = value;
11
+ return ref;
12
+ }
13
+ //#endregion
14
+ //#region ../utils/dist/string-C_OCj9Lg.js
15
+ function _typeof(o) {
16
+ "@babel/helpers - typeof";
17
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
18
+ return typeof o;
19
+ } : function(o) {
20
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
21
+ }, _typeof(o);
22
+ }
23
+ function toPrimitive(t, r) {
24
+ if ("object" != _typeof(t) || !t) return t;
25
+ var e = t[Symbol.toPrimitive];
26
+ if (void 0 !== e) {
27
+ var i = e.call(t, r || "default");
28
+ if ("object" != _typeof(i)) return i;
29
+ throw new TypeError("@@toPrimitive must return a primitive value.");
30
+ }
31
+ return ("string" === r ? String : Number)(t);
32
+ }
33
+ function toPropertyKey(t) {
34
+ var i = toPrimitive(t, "string");
35
+ return "symbol" == _typeof(i) ? i : i + "";
36
+ }
37
+ function _defineProperty(e, r, t) {
38
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
39
+ value: t,
40
+ enumerable: !0,
41
+ configurable: !0,
42
+ writable: !0
43
+ }) : e[r] = t, e;
44
+ }
45
+ /**
46
+ * 类型工具类
47
+ */
48
+ var TypeUtil = class {
49
+ /**
50
+ * 获取值的 [[Prototype]] 标签
51
+ *
52
+ * @param value - 任意 JavaScript 值
53
+ * @returns 标准化的类型标签字符串
54
+ */
55
+ static getPrototypeString(value) {
56
+ return Object.prototype.toString.call(value);
57
+ }
58
+ static isConstructable(fn) {
59
+ try {
60
+ Reflect.construct(fn, []);
61
+ return true;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+ /**
67
+ * 检查 value 是否为 string 类型
68
+ *
69
+ * @param value 待检查值
70
+ * @param checkEmpty 是否检查空字符串
71
+ * @returns 是否为字符串
72
+ * @example
73
+ * ```ts
74
+ * TypeUtil.isString("abc"); // true
75
+ * TypeUtil.isString(""); // true
76
+ * TypeUtil.isString("", true); // false
77
+ * ```
78
+ */
79
+ static isString(value, checkEmpty = false) {
80
+ return typeof value === "string" && (!checkEmpty || !!value.length);
81
+ }
82
+ /**
83
+ * 检查 value 是否为 number 类型
84
+ * - 默认会调用 `TypeUtil.isNaN`(内部基于 `Number.isNaN`)过滤掉 `NaN`
85
+ *
86
+ * @param value 待检查值
87
+ * @param checkNaN 是否检查 `NaN`,默认为 `true`
88
+ * @returns 是否为 number
89
+ * @example
90
+ * ```ts
91
+ * TypeUtil.isNumber(1); // true
92
+ * TypeUtil.isNumber(NaN); // false (default)
93
+ * TypeUtil.isNumber(NaN, false); // true
94
+ * ```
95
+ */
96
+ static isNumber(value, checkNaN = true) {
97
+ return typeof value === "number" && (!checkNaN || !this.isNaN(value));
98
+ }
99
+ /**
100
+ * 检查 value 是否为 NaN
101
+ * - 禁止使用全局 `isNaN`,其会先进行隐式数字转换,可能导致误判(例如 `isNaN("foo") === true`)
102
+ * - 使用 `Number.isNaN` 仅在值本身就是 `NaN` 时返回 `true`,语义更严格且更安全
103
+ *
104
+ * @param value 待检查值
105
+ * @returns 是否为 NaN
106
+ * @example
107
+ * ```ts
108
+ * TypeUtil.isNaN(NaN); // true
109
+ * ```
110
+ */
111
+ static isNaN(value) {
112
+ return Number.isNaN(value);
113
+ }
114
+ /**
115
+ * 检查 value 是否为整数
116
+ *
117
+ * @param value 待检查值
118
+ * @param checkSafe 是否附加安全整数检查
119
+ * @returns 是否为整数
120
+ * @example
121
+ * ```ts
122
+ * TypeUtil.isInteger(1); // true
123
+ * TypeUtil.isInteger(1.1); // false
124
+ * ```
125
+ */
126
+ static isInteger(value, checkSafe = true) {
127
+ const check = Number.isInteger(value);
128
+ return checkSafe ? check && Number.isSafeInteger(value) : check;
129
+ }
130
+ /**
131
+ * 检查 value 是否为正整数
132
+ * - 此函数中 `0` 不被视为正整数
133
+ *
134
+ * @param value 待检查值
135
+ * @param checkSafe 是否附加安全整数检查
136
+ * @example
137
+ * ```ts
138
+ * TypeUtil.isPositiveInteger(1); // true
139
+ * TypeUtil.isPositiveInteger(0); // false
140
+ * ```
141
+ */
142
+ static isPositiveInteger(value, checkSafe = true) {
143
+ return this.isInteger(value, checkSafe) && value > 0;
144
+ }
145
+ /**
146
+ * 检查 value 是否为负整数
147
+ * - 此函数中 `0` 不被视为负整数
148
+ *
149
+ * @param value 待检查值
150
+ * @param checkSafe 是否附加安全整数检查
151
+ * @example
152
+ * ```ts
153
+ * TypeUtil.isNegativeInteger(-1); // true
154
+ * TypeUtil.isNegativeInteger(0); // false
155
+ * ```
156
+ */
157
+ static isNegativeInteger(value, checkSafe = true) {
158
+ return this.isInteger(value, checkSafe) && value < 0;
159
+ }
160
+ /**
161
+ * 检查 value 是否为 Infinity
162
+ * - 排除 `NaN`
163
+ *
164
+ * @param value 待检查值
165
+ * @example
166
+ * ```ts
167
+ * TypeUtil.isInfinity(Infinity); // true
168
+ * TypeUtil.isInfinity(1); // false
169
+ * ```
170
+ */
171
+ static isInfinity(value) {
172
+ return this.isNumber(value) && (Number.POSITIVE_INFINITY === value || Number.NEGATIVE_INFINITY === value);
173
+ }
174
+ /**
175
+ * 检查 value 是否类似 Infinity
176
+ * - 排除 `NaN`
177
+ *
178
+ * @param value 待检查值
179
+ * @example
180
+ * ```ts
181
+ * TypeUtil.isInfinityLike("Infinity"); // true
182
+ * TypeUtil.isInfinityLike("123"); // false
183
+ * ```
184
+ */
185
+ static isInfinityLike(value) {
186
+ const check = this.isInfinity(value);
187
+ if (check) return check;
188
+ if (typeof value === "string") return [
189
+ "infinity",
190
+ "-infinity",
191
+ "+infinity",
192
+ "Infinity",
193
+ "-Infinity",
194
+ "+Infinity"
195
+ ].includes(value.trim());
196
+ return false;
197
+ }
198
+ /**
199
+ * 检查 value 是否为 Boolean
200
+ * @param value 待检查值
201
+ * @returns 是否为 Boolean
202
+ * @example
203
+ * ```ts
204
+ * TypeUtil.isBoolean(false); // true
205
+ * ```
206
+ */
207
+ static isBoolean(value) {
208
+ return typeof value === "boolean";
209
+ }
210
+ /**
211
+ * 检查 value 是否为 BigInt
212
+ * @param value 待检查值
213
+ * @returns 是否为 BigInt
214
+ * @example
215
+ * ```ts
216
+ * TypeUtil.isBigInt(1n); // true
217
+ * ```
218
+ */
219
+ static isBigInt(value) {
220
+ return typeof value === "bigint";
221
+ }
222
+ /**
223
+ * 检查 value 是否为 Symbol
224
+ * @param value 待检查值
225
+ * @returns 是否为 Symbol
226
+ * @example
227
+ * ```ts
228
+ * TypeUtil.isSymbol(Symbol("a")); // true
229
+ * ```
230
+ */
231
+ static isSymbol(value) {
232
+ return typeof value === "symbol";
233
+ }
234
+ /**
235
+ * 检查 value 是否为 undefined
236
+ * @param value 待检查值
237
+ * @returns 是否为 undefined
238
+ * @example
239
+ * ```ts
240
+ * TypeUtil.isUndefined(undefined); // true
241
+ * ```
242
+ */
243
+ static isUndefined(value) {
244
+ return typeof value === "undefined";
245
+ }
246
+ /**
247
+ * 检查 value 是否为 null
248
+ * @param value 待检查值
249
+ * @returns 是否为 null
250
+ * @example
251
+ * ```ts
252
+ * TypeUtil.isNull(null); // true
253
+ * ```
254
+ */
255
+ static isNull(value) {
256
+ return value === null;
257
+ }
258
+ /**
259
+ * 检查 value 是否为 Function
260
+ * @param value 待检查值
261
+ * @returns 是否为 Function
262
+ * @example
263
+ * ```ts
264
+ * TypeUtil.isFunction(() => {}); // true
265
+ * ```
266
+ */
267
+ static isFunction(value) {
268
+ return typeof value === "function";
269
+ }
270
+ /**
271
+ * 检查 value 是否为 AsyncFunction
272
+ * @param value 待检查值
273
+ * @returns 是否为 AsyncFunction
274
+ * @example
275
+ * ```ts
276
+ * TypeUtil.isAsyncFunction(async () => {}); // true
277
+ * ```
278
+ */
279
+ static isAsyncFunction(value) {
280
+ return this.isFunction(value) && this.getPrototypeString(value) === this.PROTOTYPE_TAGS.ASYNC_FUNCTION;
281
+ }
282
+ /**
283
+ * 检查 value 是否为 GeneratorFunction
284
+ * @param value 待检查值
285
+ * @returns 是否为 GeneratorFunction
286
+ * @example
287
+ * ```ts
288
+ * TypeUtil.isGeneratorFunction(function * a () {}); // true
289
+ * ```
290
+ */
291
+ static isGeneratorFunction(value) {
292
+ return this.isFunction(value) && this.getPrototypeString(value) === this.PROTOTYPE_TAGS.GENERATOR_FUNCTION;
293
+ }
294
+ /**
295
+ * 检查 value 是否为 AsyncGeneratorFunction
296
+ * @param value 待检查值
297
+ * @returns 是否为 AsyncGeneratorFunction
298
+ * @example
299
+ * ```ts
300
+ * TypeUtil.isAsyncGeneratorFunction(async function * a () {}); // true
301
+ * ```
302
+ */
303
+ static isAsyncGeneratorFunction(value) {
304
+ return this.isFunction(value) && this.getPrototypeString(value) === this.PROTOTYPE_TAGS.ASYNC_GENERATOR_FUNCTION;
305
+ }
306
+ /**
307
+ * 检查 value 是否为 Promise
308
+ * @param value 待检查值
309
+ * @returns 是否为 Promise
310
+ * @example
311
+ * ```ts
312
+ * TypeUtil.isPromise(Promise.resolve(1)); // true
313
+ * ```
314
+ */
315
+ static isPromise(value) {
316
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.PROMISE;
317
+ }
318
+ /**
319
+ * 检查 value 是否为 PromiseLike
320
+ * - 可识别拥有 then 方法的非 Promise 对象
321
+ * @param value 待检查值
322
+ * @returns 是否为 PromiseLike
323
+ * @example
324
+ * ```ts
325
+ * TypeUtil.isPromiseLike({ then: () => {} }); // true
326
+ * ```
327
+ */
328
+ static isPromiseLike(value) {
329
+ return this.isPromise(value) || this.isObject(value, false) && this.isFunction(value["then"]);
330
+ }
331
+ /**
332
+ * 判断是否为普通对象类型
333
+ * - 可选是否检查原型为 `Object.prototype`,防止原型链污染
334
+ *
335
+ * @param value 待检查值
336
+ * @param prototypeCheck 是否进行原型检查,默认 `true`
337
+ * @returns 是否为 Plain Object (当 checkPrototype=true) 或 object
338
+ * @example
339
+ * ```ts
340
+ * TypeUtil.isObject({}); // true
341
+ * TypeUtil.isObject([]); // false
342
+ * TypeUtil.isObject(new Date()); // false
343
+ * TypeUtil.isObject(new Date(), false); // true
344
+ * TypeUtil.isObject(Object.create(null)) // false
345
+ * TypeUtil.isObject(Object.create(null), false) // true
346
+ * ```
347
+ */
348
+ static isObject(value, prototypeCheck = true) {
349
+ const check = this.getPrototypeString(value) === this.PROTOTYPE_TAGS.OBJECT;
350
+ return prototypeCheck ? check && Object.getPrototypeOf(value) === Object.prototype : check;
351
+ }
352
+ /**
353
+ * 判断一个对象是否为有效的枚举
354
+ * - 枚举成员不能为空
355
+ * - 枚举成员的键不能具有数值名
356
+ * - 枚举成员的值必须类型一致且为 `string` 或 `number` 类型
357
+ * - 枚举成员的值不能重复
358
+ * - 枚举成员的值必须全部为双向映射或非双向映射
359
+ *
360
+ * @param enumeration 待检查值
361
+ * @returns [是否为有效的枚举, 是否为双向枚举]
362
+ * @example
363
+ * ```ts
364
+ * enum A { X, Y }
365
+ * TypeUtil.isEnumeration(A); // [true, true]
366
+ * ```
367
+ */
368
+ static isEnumeration(enumeration) {
369
+ if (typeof enumeration !== "object" || enumeration === null) return [false, false];
370
+ const keys = Object.keys(enumeration);
371
+ if (keys.length === 0) return [false, false];
372
+ const originalKeys = [];
373
+ const numericKeys = [];
374
+ for (const key of keys) if (/^\d+$/.test(key)) numericKeys.push(key);
375
+ else originalKeys.push(key);
376
+ if (originalKeys.length === 0) return [false, false];
377
+ let valueType = null;
378
+ const values = [];
379
+ for (const key of originalKeys) {
380
+ const value = enumeration[key];
381
+ const type = typeof value;
382
+ if (type !== "string" && type !== "number") return [false, false];
383
+ if (valueType === null) valueType = type;
384
+ else if (type !== valueType) return [false, false];
385
+ values.push(value);
386
+ }
387
+ if (new Set(values).size !== values.length) return [false, false];
388
+ let isBidirectional = false;
389
+ if (numericKeys.length > 0) {
390
+ if (numericKeys.length !== originalKeys.length) return [false, false];
391
+ const reverseMappedNames = /* @__PURE__ */ new Set();
392
+ for (const numKey of numericKeys) {
393
+ const reverseValue = enumeration[numKey];
394
+ if (typeof reverseValue !== "string") return [false, false];
395
+ if (!originalKeys.includes(reverseValue)) return [false, false];
396
+ reverseMappedNames.add(reverseValue);
397
+ }
398
+ if (reverseMappedNames.size !== originalKeys.length) return [false, false];
399
+ isBidirectional = true;
400
+ }
401
+ return [true, isBidirectional];
402
+ }
403
+ /**
404
+ * 检查 value 是否为 Class
405
+ *
406
+ * @param value 待检查值
407
+ * @returns 是否为 Class
408
+ * @example
409
+ * ```ts
410
+ * class A {}
411
+ * TypeUtil.isClass(A); // true
412
+ * TypeUtil.isClass(() => {}); // false
413
+ * ```
414
+ */
415
+ static isClass(value) {
416
+ return this.isFunction(value) && !this.isAsyncFunction(value) && Function.prototype.toString.call(value).startsWith("class ") && this.isConstructable(value) && value.prototype !== void 0;
417
+ }
418
+ /**
419
+ * 检查 value 是否为数组
420
+ *
421
+ * @param value 待检查值
422
+ * @returns 是否为数组
423
+ * @example
424
+ * ```ts
425
+ * TypeUtil.isArray([]); // true
426
+ * ```
427
+ */
428
+ static isArray(value) {
429
+ return Array.isArray(value);
430
+ }
431
+ /**
432
+ * 检查 value 是否为 TypedArray
433
+ *
434
+ * @param value 待检查值
435
+ * @returns 是否为 TypedArray
436
+ * @example
437
+ * ```ts
438
+ * TypeUtil.isTypedArray(new Int8Array()); // true
439
+ * ```
440
+ */
441
+ static isTypedArray(value) {
442
+ return typeof value === "object" && value !== null && this.TYPED_ARRAY_TAGS.has(this.getPrototypeString(value));
443
+ }
444
+ /**
445
+ * 检查 value 是否为 Map
446
+ * @param value 待检查值
447
+ * @returns 是否为 Map
448
+ * @example
449
+ * ```ts
450
+ * TypeUtil.isMap(new Map()); // true
451
+ * ```
452
+ */
453
+ static isMap(value) {
454
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.MAP;
455
+ }
456
+ /**
457
+ * 检查 value 是否为 WeakMap
458
+ * @param value 待检查值
459
+ * @returns 是否为 WeakMap
460
+ * @example
461
+ * ```ts
462
+ * TypeUtil.isWeakMap(new WeakMap()); // true
463
+ * ```
464
+ */
465
+ static isWeakMap(value) {
466
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.WEAK_MAP;
467
+ }
468
+ /**
469
+ * 检查 value 是否为 Set
470
+ * @param value 待检查值
471
+ * @returns 是否为 Set
472
+ * @example
473
+ * ```ts
474
+ * TypeUtil.isSet(new Set()); // true
475
+ * ```
476
+ */
477
+ static isSet(value) {
478
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.SET;
479
+ }
480
+ /**
481
+ * 检查 value 是否为 WeakSet
482
+ * @param value 待检查值
483
+ * @returns 是否为 WeakSet
484
+ * @example
485
+ * ```ts
486
+ * TypeUtil.isWeakSet(new WeakSet()); // true
487
+ * ```
488
+ */
489
+ static isWeakSet(value) {
490
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.WEAK_SET;
491
+ }
492
+ /**
493
+ * 检查 value 是否为 Blob
494
+ * @param value 待检查值
495
+ * @returns 是否为 Blob
496
+ * @example
497
+ * ```ts
498
+ * TypeUtil.isBlob(new Blob(["a"])); // true
499
+ * ```
500
+ */
501
+ static isBlob(value) {
502
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.BLOB;
503
+ }
504
+ /**
505
+ * 检查 value 是否为 File
506
+ * @param value 待检查值
507
+ * @returns 是否为 File
508
+ * @example
509
+ * ```ts
510
+ * TypeUtil.isFile(new File(["a"], "a.txt")); // true
511
+ * ```
512
+ */
513
+ static isFile(value) {
514
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.FILE;
515
+ }
516
+ /**
517
+ * 检查 value 是否为 ReadableStream
518
+ * - Uses `Object.prototype.toString` where supported (modern browsers, Node.js ≥18).
519
+ * - Falls back to duck-typing in older environments.
520
+ * - Resistant to basic forgery, but not 100% secure in all polyfill scenarios.
521
+ * - ⚠️ Note: In older Node.js (<18) or with non-compliant polyfills, this may return false positives or negatives.
522
+ *
523
+ * @param value 待检查值
524
+ * @returns 是否为 ReadableStream
525
+ * @example
526
+ * ```ts
527
+ * TypeUtil.isReadableStream(new ReadableStream()); // true
528
+ * ```
529
+ */
530
+ static isReadableStream(value) {
531
+ if (this.getPrototypeString(value) === this.PROTOTYPE_TAGS.READABLE_STREAM) return true;
532
+ return this.isObject(value) && this.isFunction(value["getReader"]) && this.isFunction(value["pipeThrough"]);
533
+ }
534
+ /**
535
+ * 检查 value 是否为 Window
536
+ * @param value 待检查值
537
+ * @returns 是否为 Window
538
+ * @example
539
+ * ```ts
540
+ * TypeUtil.isWindow(window); // true
541
+ * ```
542
+ */
543
+ static isWindow(value) {
544
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.WINDOW;
545
+ }
546
+ /**
547
+ * 检查 value 是否为 HTMLIFrameElement
548
+ * @param value 待检查值
549
+ * @returns 是否为 HTMLIFrameElement
550
+ * @example
551
+ * ```ts
552
+ * TypeUtil.isIframe(document.createElement("iframe")); // true
553
+ * ```
554
+ */
555
+ static isIframe(value) {
556
+ if (typeof window === "undefined") return false;
557
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.IFRAME;
558
+ }
559
+ /**
560
+ * 检查 value 是否为 Date 对象
561
+ *
562
+ * @param value 待检查值
563
+ * @param invalidCheck 是否要求日期有效(非 Invalid Date)。默认 true
564
+ * - true: 仅当是有效 Date 对象时返回 true(排除 new Date('invalid'))
565
+ * - false: 只要 [[Prototype]] 是 Date 即返回 true(包含 Invalid Date)
566
+ * @returns 是否为 Date 对象,根据 invalidCheck 返回不同语义的 Date 判定
567
+ *
568
+ * @example
569
+ * ```ts
570
+ * TypeUtil.isDate(new Date()); // true
571
+ * TypeUtil.isDate(new Date('invalid')); // false
572
+ * TypeUtil.isDate(new Date('invalid'), false); // true
573
+ * TypeUtil.isDate(null); // false
574
+ * TypeUtil.isDate({}); // false
575
+ * ```
576
+ */
577
+ static isDate(value, invalidCheck = true) {
578
+ if (!value || typeof value !== "object") return false;
579
+ if (this.getPrototypeString(value) !== this.PROTOTYPE_TAGS.DATE) return false;
580
+ if (!invalidCheck) return true;
581
+ try {
582
+ const time = value.getTime();
583
+ return typeof time === "number" && !Number.isNaN(time);
584
+ } catch {
585
+ return false;
586
+ }
587
+ }
588
+ /**
589
+ * 检查 value 是否为 Error 对象
590
+ * @param value 待检查值
591
+ * @returns 是否为 Error
592
+ * @example
593
+ * ```ts
594
+ * TypeUtil.isError(new Error("x")); // true
595
+ * ```
596
+ */
597
+ static isError(value) {
598
+ return value instanceof Error || this.getPrototypeString(value) === this.PROTOTYPE_TAGS.ERROR;
599
+ }
600
+ /**
601
+ * 检查 value 是否为 RegExp
602
+ * @param value 待检查值
603
+ * @returns 是否为 RegExp
604
+ * @example
605
+ * ```ts
606
+ * TypeUtil.isRegExp(/a/); // true
607
+ * ```
608
+ */
609
+ static isRegExp(value) {
610
+ if (typeof value !== "object" || value === null) return false;
611
+ try {
612
+ const regex = value;
613
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.REG_EXP && this.isString(regex.source) && this.isString(regex.flags) && this.isBoolean(regex.global) && this.isFunction(regex.test);
614
+ } catch (error) {
615
+ return false;
616
+ }
617
+ }
618
+ /**
619
+ * 检查 value 是否为 WebSocket
620
+ * @param value 待检查值
621
+ * @returns 是否为 WebSocket
622
+ * @example
623
+ * ```ts
624
+ * TypeUtil.isWebSocket(new WebSocket("wss://echo.websocket.events")); // true
625
+ * ```
626
+ */
627
+ static isWebSocket(value) {
628
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.WEB_SOCKET;
629
+ }
630
+ /**
631
+ * 检查 value 是否为 URLSearchParams
632
+ * @param value 待检查值
633
+ * @returns 是否为 URLSearchParams
634
+ * @example
635
+ * ```ts
636
+ * TypeUtil.isURLSearchParams(new URLSearchParams("a=1")); // true
637
+ * ```
638
+ */
639
+ static isURLSearchParams(value) {
640
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.URL_SEARCH_PARAMS;
641
+ }
642
+ /**
643
+ * 检查 value 是否为 AbortSignal
644
+ * @param value 待检查值
645
+ * @returns 是否为 AbortSignal
646
+ * @example
647
+ * ```ts
648
+ * TypeUtil.isAbortSignal(new AbortController().signal); // true
649
+ * ```
650
+ */
651
+ static isAbortSignal(value) {
652
+ return this.getPrototypeString(value) === this.PROTOTYPE_TAGS.ABORT_SIGNAL;
653
+ }
654
+ /**
655
+ * 检查 value 是否为可迭代对象 (Iterable)
656
+ * @param value 待检查值
657
+ * @returns 是否为 Iterable
658
+ * @example
659
+ * ```ts
660
+ * TypeUtil.isIterable([1, 2]); // true
661
+ * ```
662
+ */
663
+ static isIterable(value) {
664
+ return !!value && typeof value[Symbol.iterator] === "function";
665
+ }
666
+ /**
667
+ * 检查 value 是否为 Falsy 值 (false, 0, "", null, undefined, NaN)
668
+ * @param value 待检查值
669
+ * @returns 是否为 Falsy
670
+ * @example
671
+ * ```ts
672
+ * TypeUtil.isFalsy(0); // true
673
+ * ```
674
+ */
675
+ static isFalsy(value) {
676
+ if (this.isNaN(value) || this.isNull(value) || this.isUndefined(value)) return true;
677
+ return value === false || value === 0 || value === 0n || value === "";
678
+ }
679
+ /**
680
+ * 检查 value 是否为 FalsyLike 值
681
+ * - 包含字符串形式的 `"null"`、`"undefined"`、`"false"`、`"0"` 等
682
+ *
683
+ * @param value 待检查值
684
+ * @returns 是否为 FalsyLike
685
+ * @example
686
+ * ```ts
687
+ * TypeUtil.isFalsyLike("false"); // true
688
+ * TypeUtil.isFalsyLike("hello"); // false
689
+ * ```
690
+ */
691
+ static isFalsyLike(value) {
692
+ if (this.isFalsy(value)) return true;
693
+ return typeof value === "string" && (value === "null" || value === "undefined" || value === "NaN" || value === "false" || value === "0" || value === "-0" || value === "0n");
694
+ }
695
+ };
696
+ _defineProperty(TypeUtil, "PROTOTYPE_TAGS", {
697
+ STRING: "[object String]",
698
+ NUMBER: "[object Number]",
699
+ BOOLEAN: "[object Boolean]",
700
+ BIGINT: "[object BigInt]",
701
+ SYMBOL: "[object Symbol]",
702
+ UNDEFINED: "[object Undefined]",
703
+ NULL: "[object Null]",
704
+ OBJECT: "[object Object]",
705
+ FUNCTION: "[object Function]",
706
+ GENERATOR_FUNCTION: "[object GeneratorFunction]",
707
+ ASYNC_FUNCTION: "[object AsyncFunction]",
708
+ ASYNC_GENERATOR_FUNCTION: "[object AsyncGeneratorFunction]",
709
+ PROMISE: "[object Promise]",
710
+ MAP: "[object Map]",
711
+ SET: "[object Set]",
712
+ WEAK_MAP: "[object WeakMap]",
713
+ WEAK_SET: "[object WeakSet]",
714
+ BLOB: "[object Blob]",
715
+ FILE: "[object File]",
716
+ READABLE_STREAM: "[object ReadableStream]",
717
+ GLOBAL: "[object global]",
718
+ WINDOW: "[object Window]",
719
+ IFRAME: "[object HTMLIFrameElement]",
720
+ DATE: "[object Date]",
721
+ ERROR: "[object Error]",
722
+ REG_EXP: "[object RegExp]",
723
+ WEB_SOCKET: "[object WebSocket]",
724
+ URL_SEARCH_PARAMS: "[object URLSearchParams]",
725
+ ABORT_SIGNAL: "[object AbortSignal]"
726
+ });
727
+ _defineProperty(TypeUtil, "TYPED_ARRAY_TAGS", new Set([
728
+ "[object Int8Array]",
729
+ "[object Uint8Array]",
730
+ "[object Uint8ClampedArray]",
731
+ "[object Int16Array]",
732
+ "[object Uint16Array]",
733
+ "[object Int32Array]",
734
+ "[object Uint32Array]",
735
+ "[object Float32Array]",
736
+ "[object Float64Array]",
737
+ "[object BigInt64Array]",
738
+ "[object BigUint64Array]"
739
+ ]));
740
+ /**
741
+ * 字符串工具类
742
+ */
743
+ var StringUtil = class {
744
+ /**
745
+ * 从字符串中提取数字字符串
746
+ * - 移除非数字字符,保留符号和小数点
747
+ *
748
+ * @param input 待处理字符串
749
+ * @returns 提取出的数字字符串
750
+ * @example
751
+ * ```ts
752
+ * StringUtil.toNumber("$1,234.56"); // "1234.56"
753
+ * StringUtil.toNumber("abc-123"); // "-123"
754
+ * ```
755
+ */
756
+ static toNumber(input) {
757
+ if (!TypeUtil.isString(input, true)) return "0";
758
+ const cleaned = input.replace(/[^0-9.-]/g, "");
759
+ if (!cleaned) return "0";
760
+ let isDecimal = false;
761
+ let signCount = 0;
762
+ let firstIndex = -1;
763
+ const stringList = cleaned.split("").map((s, i) => {
764
+ if (s === ".") {
765
+ if (isDecimal) return "";
766
+ isDecimal = true;
767
+ return ".";
768
+ }
769
+ if (s === "-") {
770
+ firstIndex === -1 && signCount++;
771
+ return "";
772
+ }
773
+ firstIndex === -1 && (firstIndex = i);
774
+ return s;
775
+ });
776
+ const sign = signCount % 2 === 1 ? "-" : "";
777
+ if (firstIndex === -1) return sign + "0";
778
+ let result = stringList.join("");
779
+ if (result.startsWith(".")) result = "0" + result;
780
+ if (result.endsWith(".")) result = result.slice(0, -1);
781
+ return sign + result;
782
+ }
783
+ static toLowerCase(input) {
784
+ if (!TypeUtil.isString(input, true)) return "";
785
+ return input.toLowerCase();
786
+ }
787
+ static toUpperCase(input) {
788
+ if (!TypeUtil.isString(input, true)) return "";
789
+ return input.toUpperCase();
790
+ }
791
+ /**
792
+ * 字符串首字母大小写
793
+ * - 包含非西欧字母字符时,不处理
794
+ * - 纯字母且全大写时,不处理
795
+ * - 纯字母且非全大写时,首字母小写,其余保留
796
+ * - 纯字母且非全大写时,首字母大写,其余保留
797
+ *
798
+ * @param input 待处理字符串
799
+ * @param caseType 大小写类型
800
+ * @returns 处理后的字符串
801
+ * @example
802
+ * ```ts
803
+ * StringUtil.toInitialCase("Hello", "lower"); // "hello"
804
+ * StringUtil.toInitialCase("hello", "upper"); // "Hello"
805
+ * ```
806
+ */
807
+ static toInitialCase(input, caseType) {
808
+ if (!TypeUtil.isString(input, true)) return "";
809
+ return input.replace(/\S+/g, (word) => {
810
+ if (/[^a-zA-Z\u00C0-\u017F]/.test(word)) return word;
811
+ if (word === word.toLocaleUpperCase()) return word;
812
+ if (caseType === "lower" && word[0]) return word[0].toLocaleLowerCase() + word.slice(1);
813
+ if (caseType === "upper" && word[0]) return word[0].toLocaleUpperCase() + word.slice(1);
814
+ return word;
815
+ });
816
+ }
817
+ /**
818
+ * 将路径转换为 POSIX 风格
819
+ * - 统一使用正斜杠 (/)
820
+ * - 可选移除 Windows 盘符 (如 C:)
821
+ * - 可选移除开头的斜杠
822
+ * - 规范化连续斜杠为单个斜杠
823
+ *
824
+ * @param input 待处理字符串
825
+ * @param removeLeadingSlash 是否移除开头斜杠,默认为 `false`。如果移除了盘符,路径通常会以 / 开头,此参数可控制是否保留该 /
826
+ * @returns 转换后的路径,如果输入无效则返回空字符串
827
+ *
828
+ * @example
829
+ * ```ts
830
+ * StringUtil.toPosix("C:\\Windows\\System32"); // 默认: "/Windows/System32" (移除了 C: 并标准化)
831
+ *
832
+ * StringUtil.toPosix("C:\\Windows\\System32", true); // 移除开头斜杠: "Windows/System32"
833
+ *
834
+ * StringUtil.toPosix("\\\\server\\share\\file.txt"); // UNC 路径: "/server/share/file.txt"
835
+ *
836
+ * StringUtil.toPosix("folder\\subfolder\\file.txt"); // 相对路径: "folder/subfolder/file.txt"
837
+ * ```
838
+ */
839
+ static toPosix(input, removeLeadingSlash = false) {
840
+ if (!TypeUtil.isString(input, true)) return "";
841
+ let normalized = input.replace(/^[A-Za-z]:([\\/])?/, (_, separator) => {
842
+ return separator ? "/" : "";
843
+ });
844
+ normalized = normalized.replace(/\\/g, "/");
845
+ normalized = normalized.replace(/\/+/g, "/");
846
+ if (removeLeadingSlash && normalized.startsWith("/")) normalized = normalized.substring(1);
847
+ return normalized;
848
+ }
849
+ static toJson(input, fallback) {
850
+ if (!TypeUtil.isString(input, true)) return fallback;
851
+ try {
852
+ return JSON.parse(input);
853
+ } catch (error) {
854
+ return fallback;
855
+ }
856
+ }
857
+ static toValues(input, valueType = "number", splitSymbol = ",") {
858
+ if (!TypeUtil.isString(input, true)) return [];
859
+ try {
860
+ const values = input.split(splitSymbol);
861
+ if (valueType === "number") return values.map((d) => Number(d));
862
+ return values;
863
+ } catch (error) {
864
+ return [];
865
+ }
866
+ }
867
+ /**
868
+ * 从字符串中裁切掉所有的前缀和后缀字符
869
+ *
870
+ * @param input 待处理字符串
871
+ * @param charsToTrim 裁切字符,默认为 `" "`
872
+ * @returns 裁切后的字符串
873
+ * @example
874
+ * ```ts
875
+ * StringUtil.trim(" hello "); // "hello"
876
+ * StringUtil.trim("__hello__", "_"); // "hello"
877
+ * ```
878
+ */
879
+ static trim(input, charsToTrim = " ") {
880
+ if (!TypeUtil.isString(input, true)) return "";
881
+ const toTrim = charsToTrim.replace(/[\W]{1}/g, "\\$&");
882
+ const regex = new RegExp(`^[${toTrim}]+|[${toTrim}]+$`, "g");
883
+ return input.replace(regex, "");
884
+ }
885
+ /**
886
+ * 截取字符串
887
+ * - 支持自定义省略符,不会截断在汉字中间(因为JS字符串本身按字符处理)
888
+ *
889
+ * @param input 待处理字符串
890
+ * @param maxLength 最大长度 (包含省略符)
891
+ * @param ellipsis 省略符,默认为 `...`
892
+ * @returns 截取后的字符串
893
+ * @example
894
+ * ```ts
895
+ * StringUtil.truncate("hello world", 8); // "hello..."
896
+ * ```
897
+ */
898
+ static truncate(input, maxLength, ellipsis = "...") {
899
+ if (!TypeUtil.isString(input, true)) return "";
900
+ const codePoints = Array.from(input);
901
+ if (!TypeUtil.isInteger(maxLength) || maxLength < 0) return input;
902
+ if (codePoints.length <= maxLength) return input;
903
+ const availableLength = maxLength - ellipsis.length;
904
+ if (availableLength <= 0) return "";
905
+ return codePoints.slice(0, availableLength).join("") + ellipsis;
906
+ }
907
+ /**
908
+ * 字符串模板替换
909
+ * - 使用对象的属性值替换字符串中的 {{key}} 模板
910
+ *
911
+ * @param input 待处理字符串
912
+ * @param template 模板对象
913
+ * @param regex 模板匹配正则 (默认: `\{\{(.+?)\}\}`)
914
+ * @returns 替换后的字符串
915
+ * @example
916
+ * ```ts
917
+ * StringUtil.template("Hello {{name}}", { name: "World" }); // "Hello World"
918
+ * ```
919
+ */
920
+ static template(input, template, regex = /\{\{(.+?)\}\}/g) {
921
+ if (!TypeUtil.isString(input, true)) return "";
922
+ regex.lastIndex = 0;
923
+ let result = "";
924
+ let from = 0;
925
+ let match;
926
+ while (match = regex.exec(input)) {
927
+ const replacement = template[match[1]];
928
+ const valueToInsert = replacement === null || replacement === void 0 ? match[0] : replacement;
929
+ result += input.slice(from, match.index) + valueToInsert;
930
+ from = regex.lastIndex;
931
+ }
932
+ return result + input.slice(from);
933
+ }
934
+ /**
935
+ * 字符串替换
936
+ * - 替换第一个匹配项
937
+ *
938
+ * @param input 待处理字符串
939
+ * @param search 匹配项
940
+ * @param replacement 替换项
941
+ * @returns 替换后的字符串
942
+ * @example
943
+ * ```ts
944
+ * StringUtil.replace("hello world", "world", "context"); // "hello context"
945
+ * ```
946
+ */
947
+ static replace(input, search, replacement) {
948
+ if (!TypeUtil.isString(input, true)) return "";
949
+ return input.replace(search, replacement);
950
+ }
951
+ };
952
+ //#endregion
953
+ //#region ../utils/dist/index.js
954
+ /**
955
+ * 数组工具类
956
+ */
957
+ var ArrayUtil = class {
958
+ static cast(candidate, checkEmpty = true) {
959
+ if (checkEmpty && (TypeUtil.isUndefined(candidate) || TypeUtil.isNull(candidate))) return [];
960
+ return TypeUtil.isArray(candidate) ? [...candidate] : [candidate];
961
+ }
962
+ static first(initialList, fallback) {
963
+ if (!TypeUtil.isArray(initialList) || initialList.length === 0) return fallback;
964
+ return initialList[0];
965
+ }
966
+ static last(initialList, fallback) {
967
+ if (!TypeUtil.isArray(initialList) || initialList.length === 0) return fallback;
968
+ return initialList[initialList.length - 1];
969
+ }
970
+ /**
971
+ * 数组竞选
972
+ * - 返回在匹配函数的比较条件中获胜的最终项目,适用于更复杂的最小值/最大值计算
973
+ *
974
+ * @param initialList 数组
975
+ * @param match 匹配函数
976
+ * @returns 获胜的元素,如果数组为空或参数无效则返回 `null`
977
+ * @example
978
+ * ```ts
979
+ * const list = [1, 10, 5];
980
+ * ArrayUtil.compete(list, (a, b) => (a > b ? a : b)); // 10
981
+ * ArrayUtil.compete(list, (a, b) => (a < b ? a : b)); // 1
982
+ * ```
983
+ */
984
+ static compete(initialList, match) {
985
+ if (!TypeUtil.isArray(initialList) || initialList.length === 0 || !TypeUtil.isFunction(match)) return null;
986
+ return initialList.reduce(match);
987
+ }
988
+ /**
989
+ * 统计数组的项目出现次数
990
+ * - 通过给定的标识符匹配函数,返回一个对象,其中键是回调函数返回的 key 值,每个值是一个整数,表示该 key 出现的次数
991
+ *
992
+ * @param initialList 初始数组
993
+ * @param match 匹配函数
994
+ * @returns 统计对象
995
+ * @example
996
+ * ```ts
997
+ * const list = ["a", "b", "a", "c"];
998
+ * ArrayUtil.count(list, (x) => x); // { a: 2, b: 1, c: 1 }
999
+ *
1000
+ * const users = [{ id: 1, group: "A" }, { id: 2, group: "B" }, { id: 3, group: "A" }];
1001
+ * ArrayUtil.count(users, (u) => u.group); // { A: 2, B: 1 }
1002
+ * ```
1003
+ */
1004
+ static count(initialList, match) {
1005
+ if (!TypeUtil.isArray(initialList) || !TypeUtil.isFunction(match)) return {};
1006
+ return initialList.reduce((prev, curr, index) => {
1007
+ const id = match(curr, index).toString();
1008
+ prev[id] = (prev[id] ?? 0) + 1;
1009
+ return prev;
1010
+ }, {});
1011
+ }
1012
+ /**
1013
+ * 获取数组差集
1014
+ * - 返回在 `initialList` 中存在,但在 `diffList` 中不存在的元素
1015
+ *
1016
+ * @param initialList 初始数组
1017
+ * @param diffList 对比数组
1018
+ * @param match 匹配函数
1019
+ * @returns 差集数组
1020
+ * @example
1021
+ * ```ts
1022
+ * ArrayUtil.difference([1, 2, 3], [2, 3, 4]); // [1]
1023
+ * ArrayUtil.difference([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id); // [{ id: 1 }]
1024
+ * ```
1025
+ */
1026
+ static difference(initialList, diffList, match) {
1027
+ if (!TypeUtil.isArray(initialList) && !TypeUtil.isArray(diffList)) return [];
1028
+ if (!TypeUtil.isArray(initialList) || !initialList.length) return [];
1029
+ if (!TypeUtil.isArray(diffList) || !diffList.length) return [...initialList];
1030
+ if (!TypeUtil.isFunction(match)) {
1031
+ const arraySet = new Set(diffList);
1032
+ return Array.from(new Set(initialList.filter((item) => !arraySet.has(item))));
1033
+ }
1034
+ const map = /* @__PURE__ */ new Map();
1035
+ diffList.forEach((item, index) => {
1036
+ map.set(match(item, index), true);
1037
+ });
1038
+ return initialList.filter((item, index) => !map.get(match(item, index)));
1039
+ }
1040
+ static intersection(initialList, diffList, match) {
1041
+ if (!TypeUtil.isArray(initialList) || !TypeUtil.isArray(diffList)) return [];
1042
+ if (!initialList.length || !diffList.length) return [];
1043
+ if (!TypeUtil.isFunction(match)) {
1044
+ const diffSet = new Set(diffList);
1045
+ return initialList.filter((item) => diffSet.has(item));
1046
+ }
1047
+ const diffKeys = new Set(diffList.map((item, index) => match(item, index)));
1048
+ return initialList.filter((item, index) => diffKeys.has(match(item, index)));
1049
+ }
1050
+ static merge(initialList, mergeList, match) {
1051
+ if (!TypeUtil.isArray(initialList)) return [];
1052
+ if (!TypeUtil.isArray(mergeList)) return [...initialList];
1053
+ if (!TypeUtil.isFunction(match)) return Array.from(new Set([...initialList, ...mergeList]));
1054
+ const keys = /* @__PURE__ */ new Map();
1055
+ mergeList.forEach((item, index) => {
1056
+ keys.set(match(item, index), item);
1057
+ });
1058
+ return initialList.map((prevItem, index) => {
1059
+ const key = match(prevItem, index);
1060
+ return keys.has(key) ? keys.get(key) : prevItem;
1061
+ });
1062
+ }
1063
+ static pick(initialList, filter, mapper) {
1064
+ if (!TypeUtil.isArray(initialList)) return [];
1065
+ if (!TypeUtil.isFunction(filter)) return [...initialList];
1066
+ const hasMapper = TypeUtil.isFunction(mapper);
1067
+ return initialList.reduce((prev, curr, index) => {
1068
+ if (!filter(curr, index)) return prev;
1069
+ if (hasMapper) prev.push(mapper(curr, index));
1070
+ else prev.push(curr);
1071
+ return prev;
1072
+ }, []);
1073
+ }
1074
+ static replace(initialList, newItem, match) {
1075
+ if (!TypeUtil.isArray(initialList) || !initialList.length) return [];
1076
+ if (!TypeUtil.isFunction(match)) return [...initialList];
1077
+ for (let i = 0; i < initialList.length; i++) {
1078
+ const item = initialList[i];
1079
+ if (match(item, i)) return [
1080
+ ...initialList.slice(0, i),
1081
+ newItem,
1082
+ ...initialList.slice(i + 1, initialList.length)
1083
+ ];
1084
+ }
1085
+ return [...initialList];
1086
+ }
1087
+ /**
1088
+ * 数组项替换并移动
1089
+ * - 在给定的数组中,替换并移动符合匹配函数结果的项目
1090
+ * - 只替换和移动第一个匹配项
1091
+ * - 未匹配时,根据 `position` 在指定位置插入 `newItem`
1092
+ *
1093
+ * @param initialList 初始数组
1094
+ * @param newItem 替换项
1095
+ * @param match 匹配函数
1096
+ * @param position 移动位置,可选 `start` | `end` | 索引位置, 默认为 `end`
1097
+ * @returns
1098
+ * @example
1099
+ * ```ts
1100
+ * ArrayUtil.replaceMove([1, 2, 3, 4], 5, (n) => n === 2, 0); // [5, 1, 3, 4]
1101
+ * ArrayUtil.replaceMove([1, 2, 3, 4], 5, (n) => n === 2, 2); // [1, 3, 5, 4]
1102
+ * ArrayUtil.replaceMove([1, 2, 3, 4], 5, (n) => n === 2, "start"); // [5, 1, 3, 4]
1103
+ * ArrayUtil.replaceMove([1, 2, 3, 4], 5, (n) => n === 2); // [1, 3, 4, 5]
1104
+ * ```
1105
+ */
1106
+ static replaceMove(initialList, newItem, match, position) {
1107
+ if (!TypeUtil.isArray(initialList)) return [];
1108
+ if (!initialList.length) return [newItem];
1109
+ if (!TypeUtil.isFunction(match)) return [...initialList];
1110
+ const result = [...initialList];
1111
+ const matchIndex = initialList.findIndex(match);
1112
+ if (matchIndex !== -1) result.splice(matchIndex, 1);
1113
+ if (position === "start") result.unshift(newItem);
1114
+ else if (position === 0 || TypeUtil.isPositiveInteger(position, false)) result.splice(Math.min(position, result.length), 0, newItem);
1115
+ else result.push(newItem);
1116
+ return result;
1117
+ }
1118
+ /**
1119
+ * 数组切分
1120
+ * - 将数组以指定的长度切分后,组合在高维数组中
1121
+ *
1122
+ * @param initialList 初始数组
1123
+ * @param size 分割尺寸,默认 `10`
1124
+ * @returns 切分后的二维数组
1125
+ * @example
1126
+ * ```ts
1127
+ * ArrayUtil.split([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
1128
+ * ```
1129
+ */
1130
+ static split(initialList, size = 10) {
1131
+ if (!TypeUtil.isArray(initialList)) return [];
1132
+ if (!TypeUtil.isPositiveInteger(size, false)) return [];
1133
+ const count = Math.ceil(initialList.length / size);
1134
+ return Array.from({ length: count }).fill(null).map((_c, i) => {
1135
+ return initialList.slice(i * size, i * size + size);
1136
+ });
1137
+ }
1138
+ /**
1139
+ * 数组分组过滤
1140
+ * - 给定一个数组和一个条件,返回一个由两个数组组成的元组,其中第一个数组包含所有满足条件的项,第二个数组包含所有不满足条件的项
1141
+ *
1142
+ * @param initialList 初始数组
1143
+ * @param match 条件匹配函数
1144
+ * @returns [满足条件的项[], 不满足条件的项[]]
1145
+ * @example
1146
+ * ```ts
1147
+ * ArrayUtil.fork([1, 2, 3, 4], (n) => n % 2 === 0); // [[2, 4], [1, 3]]
1148
+ * ```
1149
+ */
1150
+ static fork(initialList, match) {
1151
+ const forked = [[], []];
1152
+ if (TypeUtil.isArray(initialList)) initialList.forEach((item, index) => {
1153
+ forked[match(item, index) ? 0 : 1].push(item);
1154
+ });
1155
+ return forked;
1156
+ }
1157
+ /**
1158
+ * 数组解压
1159
+ * - `ArrayUtil.zip` 的反向操作
1160
+ *
1161
+ * @param arrayList 压缩后的数组
1162
+ * @returns 解压后的二维数组
1163
+ * @example
1164
+ * ```ts
1165
+ * ArrayUtil.unzip([[1, "a"], [2, "b"]]); // [[1, 2], ["a", "b"]]
1166
+ * ```
1167
+ */
1168
+ static unzip(arrayList) {
1169
+ if (!TypeUtil.isArray(arrayList) || !arrayList.length) return [];
1170
+ const out = new Array(arrayList.reduce((max, arr) => Math.max(max, arr.length), 0));
1171
+ let index = 0;
1172
+ const get = (array) => array[index];
1173
+ for (; index < out.length; index++) out[index] = Array.from(arrayList, get);
1174
+ return out;
1175
+ }
1176
+ static zip(...arrays) {
1177
+ return this.unzip(arrays);
1178
+ }
1179
+ static zipToObject(keys, values) {
1180
+ const result = {};
1181
+ if (!TypeUtil.isArray(keys) || !keys.length) return result;
1182
+ const getValue = TypeUtil.isFunction(values) ? values : TypeUtil.isArray(values) ? (_k, i) => values[i] : (_k, _i) => values;
1183
+ return keys.reduce((acc, key, idx) => {
1184
+ acc[key] = getValue(key, idx);
1185
+ return acc;
1186
+ }, result);
1187
+ }
1188
+ };
1189
+ var _DateTimeUtil;
1190
+ /**
1191
+ * 日期工具类
1192
+ */
1193
+ var DateTimeUtil = class {
1194
+ /**
1195
+ * 获取当前时区信息
1196
+ *
1197
+ * @returns 时区信息对象 (UTC偏移和时区名称)
1198
+ * @example
1199
+ * ```ts
1200
+ * DateTimeUtil.getTimeZone(); // { UTC: "UTC+8", timeZone: "Asia/Shanghai" }
1201
+ * ```
1202
+ */
1203
+ static getTimeZone() {
1204
+ const hour = 0 - (/* @__PURE__ */ new Date()).getTimezoneOffset() / this.MINUTE_PER_HOUR;
1205
+ return {
1206
+ UTC: "UTC" + (hour >= 0 ? "+" + hour : hour),
1207
+ timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
1208
+ };
1209
+ }
1210
+ };
1211
+ _DateTimeUtil = DateTimeUtil;
1212
+ _defineProperty(DateTimeUtil, "MILLISECONDS_PER_SECOND", 1e3);
1213
+ _defineProperty(DateTimeUtil, "SECOND_PER_MINUTE", 60);
1214
+ _defineProperty(DateTimeUtil, "MINUTE_PER_HOUR", 60);
1215
+ _defineProperty(DateTimeUtil, "SECOND_PER_HOUR", _DateTimeUtil.SECOND_PER_MINUTE ** 2);
1216
+ _defineProperty(DateTimeUtil, "HOUR_PER_DAY", 24);
1217
+ _defineProperty(DateTimeUtil, "SECOND_PER_DAY", _DateTimeUtil.SECOND_PER_HOUR * _DateTimeUtil.HOUR_PER_DAY);
1218
+ _defineProperty(DateTimeUtil, "DAY_PER_WEEK", 7);
1219
+ _defineProperty(DateTimeUtil, "DAY_PER_MONTH", 30);
1220
+ _defineProperty(DateTimeUtil, "DAY_PER_YEAR", 365);
1221
+ _defineProperty(DateTimeUtil, "MONTH_PER_YEAR", 12);
1222
+ _defineProperty(DateTimeUtil, "WEEK_PER_YEAR", 52);
1223
+ _defineProperty(DateTimeUtil, "WEEK_PER_MONTH", 4);
1224
+ _defineProperty(DateTimeUtil, "FORMAT", {
1225
+ ISO_DATE: "yyyy-MM-dd",
1226
+ ISO_TIME: "HH:mm:ss",
1227
+ ISO_DATE_TIME: "yyyy-MM-dd HH:mm:ss",
1228
+ ISO_DATE_TIME_MS: "yyyy-MM-dd HH:mm:ss.SSS",
1229
+ ISO_DATETIME_TZ: "yyyy-MM-dd'T'HH:mm:ssXXX",
1230
+ ISO_DATETIME_TZ_MS: "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
1231
+ US_DATE: "MM/dd/yyyy",
1232
+ US_DATE_TIME: "MM/dd/yyyy HH:mm:ss",
1233
+ US_DATE_SHORT_YEAR: "MM/dd/yy",
1234
+ EU_DATE: "dd/MM/yyyy",
1235
+ EU_DATE_TIME: "dd/MM/yyyy HH:mm:ss",
1236
+ CN_DATE: "yyyy年MM月dd日",
1237
+ CN_DATE_TIME: "yyyy年MM月dd日 HH时mm分ss秒",
1238
+ CN_DATE_WEEKDAY: "yyyy年MM月dd日 EEE",
1239
+ CN_WEEKDAY_FULL: "EEEE",
1240
+ SHORT_DATE: "yy-MM-dd",
1241
+ SHORT_DATE_SLASH: "yy/MM/dd",
1242
+ MONTH_DAY: "MM-dd",
1243
+ MONTH_DAY_CN: "MM月dd日",
1244
+ DATE_WITH_WEEKDAY_SHORT: "yyyy-MM-dd (EEE)",
1245
+ DATE_WITH_WEEKDAY_FULL: "yyyy-MM-dd (EEEE)",
1246
+ TIME_24: "HH:mm:ss",
1247
+ TIME_24_NO_SEC: "HH:mm",
1248
+ TIME_12: "hh:mm:ss a",
1249
+ TIME_12_NO_SEC: "hh:mm a",
1250
+ TIMESTAMP: "yyyyMMddHHmmss",
1251
+ TIMESTAMP_MS: "yyyyMMddHHmmssSSS",
1252
+ RFC2822: "EEE, dd MMM yyyy HH:mm:ss xxx",
1253
+ READABLE_DATE: "MMM dd, yyyy",
1254
+ READABLE_DATE_TIME: "MMM dd, yyyy HH:mm",
1255
+ COMPACT_DATETIME: "yyyyMMdd_HHmmss"
1256
+ });
1257
+ /**
1258
+ * 环境检查工具类
1259
+ */
1260
+ var EnvUtil = class {
1261
+ /**
1262
+ * 检测是否处于浏览器环境
1263
+ *
1264
+ * @returns 是否为浏览器环境
1265
+ * @example
1266
+ * ```ts
1267
+ * EnvUtil.isBrowser(); // true: 浏览器, false: Node.js
1268
+ * ```
1269
+ */
1270
+ static isBrowser() {
1271
+ return this._isBrowser;
1272
+ }
1273
+ /**
1274
+ * 检测是否处于 Web Worker 环境
1275
+ *
1276
+ * @returns 是否为 Web Worker 环境
1277
+ * @example
1278
+ * ```ts
1279
+ * EnvUtil.isWebWorker(); // true: Worker, false: 主线程/Node.js
1280
+ * ```
1281
+ */
1282
+ static isWebWorker() {
1283
+ return this._isWebWorker;
1284
+ }
1285
+ /**
1286
+ * 检测是否处于 React Native 环境
1287
+ *
1288
+ * @returns 是否为 React Native 环境
1289
+ * @example
1290
+ * ```ts
1291
+ * EnvUtil.isReactNative(); // true: React Native, false: Web/Node.js
1292
+ * ```
1293
+ */
1294
+ static isReactNative() {
1295
+ return this._isReactNative;
1296
+ }
1297
+ /**
1298
+ * 检查是否在 iframe 环境中
1299
+ *
1300
+ * @returns 是否在 iframe 中
1301
+ * @example
1302
+ * ```ts
1303
+ * EnvUtil.isIframe(); // true: 当前页面在 iframe 中
1304
+ * ```
1305
+ */
1306
+ static isIframe() {
1307
+ if (typeof window === "undefined") return false;
1308
+ try {
1309
+ return window.top !== window.self;
1310
+ } catch (error) {
1311
+ if (error.name === "SecurityError") return true;
1312
+ return false;
1313
+ }
1314
+ }
1315
+ /**
1316
+ * 检测当前设备是否为桌面设备
1317
+ *
1318
+ * @param minWidth - 桌面设备最小宽度(默认 1200px)
1319
+ * @param minScreenSize - 桌面设备最小屏幕尺寸(默认 10英寸)
1320
+ * @param dpi - 标准 DPI 基准(默认 160)
1321
+ * @returns 是否为桌面设备
1322
+ * @example
1323
+ * ```ts
1324
+ * // 假设 window.innerWidth = 1920
1325
+ * EnvUtil.isDesktop(); // true
1326
+ *
1327
+ * // 自定义阈值
1328
+ * EnvUtil.isDesktop(1440, 13); // 更严格的桌面检测
1329
+ * ```
1330
+ */
1331
+ static isDesktop(minWidth = 1200, minScreenSize = 10, dpi = 160) {
1332
+ if (typeof window === "undefined" || !TypeUtil.isPositiveInteger(minWidth) || !TypeUtil.isPositiveInteger(minScreenSize)) return false;
1333
+ if (window.innerWidth < minWidth) return false;
1334
+ try {
1335
+ const widthPx = window.screen.width;
1336
+ const heightPx = window.screen.height;
1337
+ const DPI = dpi * (window.devicePixelRatio || 1);
1338
+ const widthInch = widthPx / DPI;
1339
+ const heightInch = heightPx / DPI;
1340
+ return Math.sqrt(widthInch ** 2 + heightInch ** 2) >= minScreenSize;
1341
+ } catch {
1342
+ return true;
1343
+ }
1344
+ }
1345
+ /**
1346
+ * 检测当前设备是否为 Windows 桌面设备
1347
+ *
1348
+ * @param minWidth - 桌面设备最小宽度(默认 1200px)
1349
+ * @param minScreenSize - 桌面设备最小屏幕尺寸(默认 10英寸)
1350
+ * @param dpi - 标准 DPI 基准(默认 160)
1351
+ * @returns 是否为 Windows 桌面设备
1352
+ * @example
1353
+ * ```ts
1354
+ * // UA contains Windows
1355
+ * EnvUtil.isWindowsDesktop(); // true
1356
+ * ```
1357
+ */
1358
+ static isWindowsDesktop(minWidth = 1200, minScreenSize = 10, dpi = 160) {
1359
+ if (typeof navigator === "undefined" || !navigator.userAgent) return false;
1360
+ return /Windows/i.test(navigator.userAgent) && this.isDesktop(minWidth, minScreenSize, dpi);
1361
+ }
1362
+ /**
1363
+ * 检测当前设备是否为 macOS 桌面设备
1364
+ *
1365
+ * @param minWidth - 桌面设备最小宽度(默认 1200px)
1366
+ * @param minScreenSize - 桌面设备最小屏幕尺寸(默认 10英寸)
1367
+ * @param dpi - 标准 DPI 基准(默认 160)
1368
+ * @returns 是否为 macOS 桌面设备
1369
+ * @example
1370
+ * ```ts
1371
+ * // UA contains Macintosh
1372
+ * EnvUtil.isMacOSDesktop(); // true
1373
+ * ```
1374
+ */
1375
+ static isMacOSDesktop(minWidth = 1200, minScreenSize = 10, dpi = 160) {
1376
+ if (typeof navigator === "undefined" || !navigator.userAgent) return false;
1377
+ return /Macintosh/i.test(navigator.userAgent) && this.isDesktop(minWidth, minScreenSize, dpi);
1378
+ }
1379
+ /**
1380
+ * 检测当前设备是否为移动设备
1381
+ *
1382
+ * @param maxWidth - 移动设备最大宽度(默认 768px)
1383
+ * @param dpi - 标准 DPI 基准(默认 160)
1384
+ * @returns 是否为移动设备
1385
+ * @example
1386
+ * ```ts
1387
+ * // 假设 window.innerWidth = 500
1388
+ * EnvUtil.isMobile(); // true
1389
+ * ```
1390
+ */
1391
+ static isMobile(maxWidth = 768, dpi = 160) {
1392
+ if (typeof window === "undefined" || !TypeUtil.isPositiveInteger(maxWidth)) return false;
1393
+ if (window.innerWidth >= maxWidth) return false;
1394
+ try {
1395
+ const widthPx = window.screen.width;
1396
+ const heightPx = window.screen.height;
1397
+ const DPI = dpi * (window.devicePixelRatio || 1);
1398
+ const widthInch = widthPx / DPI;
1399
+ const heightInch = heightPx / DPI;
1400
+ return Math.sqrt(widthInch ** 2 + heightInch ** 2) < 7;
1401
+ } catch {
1402
+ return true;
1403
+ }
1404
+ }
1405
+ /**
1406
+ * 检测当前设备是否为IOS移动设备
1407
+ *
1408
+ * @param maxWidth - 移动设备最大宽度(默认 768px)
1409
+ * @param dpi - 标准 DPI 基准(默认 160)
1410
+ * @returns 是否为 iOS 移动设备 (iPhone/iPod)
1411
+ * @example
1412
+ * ```ts
1413
+ * // UA contains iPhone
1414
+ * EnvUtil.isIOSMobile(); // true
1415
+ * ```
1416
+ */
1417
+ static isIOSMobile(maxWidth = 768, dpi = 160) {
1418
+ if (typeof navigator === "undefined" || !navigator.userAgent) return false;
1419
+ return /iPhone|iPad|iPod/i.test(navigator.userAgent) && this.isMobile(maxWidth, dpi);
1420
+ }
1421
+ /**
1422
+ * 检测当前设备是否为平板
1423
+ *
1424
+ * @param minWidth - 平板最小宽度(默认 768px)
1425
+ * @param maxWidth - 平板最大宽度(默认 1200px)
1426
+ * @param dpi - 标准 DPI 基准(默认 160)
1427
+ * @returns 是否为平板设备
1428
+ * @example
1429
+ * ```ts
1430
+ * // 假设 window.innerWidth = 1000
1431
+ * EnvUtil.isTablet(); // true
1432
+ * ```
1433
+ */
1434
+ static isTablet(minWidth = 768, maxWidth = 1200, dpi = 160) {
1435
+ if (typeof window === "undefined" || !TypeUtil.isPositiveInteger(minWidth) || !TypeUtil.isPositiveInteger(maxWidth)) return false;
1436
+ const width = window.innerWidth;
1437
+ const isWithinWidthRange = width >= minWidth && width <= maxWidth;
1438
+ try {
1439
+ const widthPx = window.screen.width;
1440
+ const heightPx = window.screen.height;
1441
+ const DPI = dpi * (window.devicePixelRatio || 1);
1442
+ const widthInch = widthPx / DPI;
1443
+ const heightInch = heightPx / DPI;
1444
+ const screenInches = Math.sqrt(widthInch ** 2 + heightInch ** 2);
1445
+ return isWithinWidthRange || screenInches >= 7;
1446
+ } catch {
1447
+ return isWithinWidthRange;
1448
+ }
1449
+ }
1450
+ };
1451
+ _defineProperty(EnvUtil, "_isBrowser", typeof window !== "undefined" && TypeUtil.isFunction(window?.document?.createElement));
1452
+ _defineProperty(EnvUtil, "_isWebWorker", typeof window === "undefined" && typeof self !== "undefined" && "importScripts" in self);
1453
+ _defineProperty(EnvUtil, "_isReactNative", typeof navigator !== "undefined" && navigator.product === "ReactNative");
1454
+ /**
1455
+ * MIME 工具类
1456
+ */
1457
+ var MimeUtil = class {};
1458
+ _defineProperty(MimeUtil, "MIME", {
1459
+ /** 普通文本文件 */
1460
+ TEXT: "text/plain",
1461
+ /** 超文本标记语言文档 */
1462
+ HTML: "text/html",
1463
+ /** 层叠样式表文件 */
1464
+ CSS: "text/css",
1465
+ /** 逗号分隔值文件(表格数据) */
1466
+ CSV: "text/csv",
1467
+ /** 制表符分隔值文件 */
1468
+ TSV: "text/tab-separated-values",
1469
+ /** XML 文档 */
1470
+ XML: "text/xml",
1471
+ /** XHTML 文档(XML 严格格式的 HTML) */
1472
+ XHTML: "application/xhtml+xml",
1473
+ /** JavaScript 文件 */
1474
+ JS: "text/javascript",
1475
+ /** TypeScript 文件 */
1476
+ TS: "text/typescript",
1477
+ /** Python 文件 */
1478
+ PY: "text/x-python",
1479
+ /** Shell 脚本 (.sh) */
1480
+ SH: "text/x-sh",
1481
+ /** C 语言源文件 */
1482
+ C: "text/x-c",
1483
+ /** C++ 源文件 */
1484
+ CPP: "text/x-c++",
1485
+ /** C# 源文件 */
1486
+ CSHARP: "text/x-csharp",
1487
+ /** Java 源文件 */
1488
+ JAVA: "text/x-java",
1489
+ /** Go 源文件 */
1490
+ GO: "text/x-go",
1491
+ /** Rust 源文件 */
1492
+ RUST: "text/x-rust",
1493
+ /** PHP 文件 */
1494
+ PHP: "text/x-php",
1495
+ /** Ruby 文件 */
1496
+ RUBY: "text/x-ruby",
1497
+ /** Swift 源文件 */
1498
+ SWIFT: "text/x-swift",
1499
+ /** YAML 文档 */
1500
+ YAML: "text/vnd.yaml",
1501
+ /** TOML 文档 */
1502
+ TOML: "text/x-toml",
1503
+ /** SQL 脚本 */
1504
+ SQL: "text/x-sql",
1505
+ /** Markdown 格式文档 */
1506
+ MARKDOWN: "text/markdown",
1507
+ /** 富文本格式文档(.rtf) */
1508
+ RTF: "application/rtf",
1509
+ /** iCalendar 日历格式(.ics) */
1510
+ CALENDAR: "text/calendar",
1511
+ /** JPEG 图像(.jpg/.jpeg) */
1512
+ JPEG: "image/jpeg",
1513
+ /** PNG 图像(无损压缩,支持透明) */
1514
+ PNG: "image/png",
1515
+ /** GIF 图像(支持动画) */
1516
+ GIF: "image/gif",
1517
+ /** Windows 位图(.bmp) */
1518
+ BMP: "image/bmp",
1519
+ /** SVG 向量图形(.svg) */
1520
+ SVG: "image/svg+xml",
1521
+ /** APNG 动态图像(.apng) */
1522
+ APNG: "image/apng",
1523
+ /** AVIF 图像(高效压缩) */
1524
+ AVIF: "image/avif",
1525
+ /** 图标文件格式(.ico) */
1526
+ ICO: "image/vnd.microsoft.icon",
1527
+ /** WebP 图像(高效压缩) */
1528
+ WEBP: "image/webp",
1529
+ /** TIFF 图像(.tif/.tiff) */
1530
+ TIFF: "image/tiff",
1531
+ /** HEIC 图像(高效编码) */
1532
+ HEIC: "image/heic",
1533
+ /** Adobe Photoshop 文件(.psd) */
1534
+ PSD: "image/vnd.adobe.photoshop",
1535
+ /** MP3 音频(.mp3) */
1536
+ MP3: "audio/mpeg",
1537
+ /** AAC 音频(.aac) */
1538
+ AAC: "audio/aac",
1539
+ /** MIDI 音乐文件(.mid/.midi) */
1540
+ MIDI: "audio/midi",
1541
+ /** OGG 音频(.oga) */
1542
+ OGG_AUDIO: "audio/ogg",
1543
+ /** Opus 音频(.opus) */
1544
+ OPUS: "audio/opus",
1545
+ /** WAV 音频(.wav) */
1546
+ WAV: "audio/wav",
1547
+ /** RealAudio 音频(.ra/.ram) */
1548
+ REAL_AUDIO: "audio/x-pn-realaudio",
1549
+ /** MP4 视频(.mp4) */
1550
+ MP4: "video/mp4",
1551
+ /** MPEG 视频(.mpeg/.mpg) */
1552
+ MPEG: "video/mpeg",
1553
+ /** OGG 视频(.ogv) */
1554
+ OGG_VIDEO: "video/ogg",
1555
+ /** AVI 视频(.avi) */
1556
+ AVI: "video/x-msvideo",
1557
+ /** 3GPP 视频(.3gp) */
1558
+ THREE_GPP: "video/3gpp",
1559
+ /** 3GPP2 视频(.3g2) */
1560
+ THREE_GPP2: "video/3gpp2",
1561
+ /** WebM 视频(.webm) */
1562
+ WEBM: "video/webm",
1563
+ /** PDF 文档 */
1564
+ PDF: "application/pdf",
1565
+ /** Word 97-2003 文档(.doc) */
1566
+ DOC: "application/msword",
1567
+ /** Word 2007+ 文档(.docx) */
1568
+ DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
1569
+ /** Excel 2007+ 工作簿(.xlsx) */
1570
+ XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1571
+ /** 启用宏的Excel工作簿(.xlsm) */
1572
+ XLSM: "application/vnd.ms-excel.sheet.macroEnabled.12",
1573
+ /** Excel模板文件(.xltx) */
1574
+ XLTX: "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
1575
+ /** PowerPoint 2007+ 演示文稿(.pptx) */
1576
+ PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
1577
+ /** PowerPoint 97-2003 演示文稿(.ppt) */
1578
+ PPT: "application/vnd.ms-powerpoint",
1579
+ /** OpenDocument 文本文档(.odt) */
1580
+ ODT: "application/vnd.oasis.opendocument.text",
1581
+ /** OpenDocument 表格文档(.ods) */
1582
+ ODS: "application/vnd.oasis.opendocument.spreadsheet",
1583
+ /** OpenDocument 演示文稿(.odp) */
1584
+ ODP: "application/vnd.oasis.opendocument.presentation",
1585
+ /** EPUB 电子书(.epub) */
1586
+ EPUB: "application/epub+zip",
1587
+ /** Kindle 电子书(.azw) */
1588
+ AZW: "application/vnd.amazon.ebook",
1589
+ /** ZIP 压缩文件(.zip) */
1590
+ ZIP: "application/zip",
1591
+ /** GZIP 压缩文件(.gz) */
1592
+ GZIP: "application/gzip",
1593
+ /** GZIP 压缩文件(旧格式) */
1594
+ X_GZIP: "application/x-gzip",
1595
+ /** TAR 归档文件(.tar) */
1596
+ TAR: "application/x-tar",
1597
+ /** BZip 归档(.bz) */
1598
+ BZIP: "application/x-bzip",
1599
+ /** BZip2 归档(.bz2) */
1600
+ BZIP2: "application/x-bzip2",
1601
+ /** 7-Zip 压缩文件(.7z) */
1602
+ SEVEN_Z: "application/x-7z-compressed",
1603
+ /** RAR 压缩文件(.rar) */
1604
+ RAR: "application/vnd.rar",
1605
+ /** 通用二进制数据(默认类型) */
1606
+ OCTET_STREAM: "application/octet-stream",
1607
+ /** JSON 数据格式(.json) */
1608
+ JSON: "application/json",
1609
+ /** JSON-LD 格式(.jsonld) */
1610
+ LD_JSON: "application/ld+json",
1611
+ /** Java 归档文件(.jar) */
1612
+ JAR: "application/java-archive",
1613
+ /** WebAssembly 二进制指令格式(.wasm) */
1614
+ WASM: "application/wasm",
1615
+ /** MS 嵌入式 OpenType 字体(.eot) */
1616
+ EOT: "application/vnd.ms-fontobject",
1617
+ /** OpenType 字体(.otf) */
1618
+ OTF: "font/otf",
1619
+ /** WOFF 字体(.woff) */
1620
+ WOFF: "font/woff",
1621
+ /** WOFF2 字体(.woff2) */
1622
+ WOFF2: "font/woff2",
1623
+ /** TrueType 字体(.ttf) */
1624
+ TTF: "font/ttf",
1625
+ /** Excel 97-2003 工作簿(.xls) */
1626
+ XLS: "application/vnd.ms-excel",
1627
+ /** Microsoft XPS 文档(.xps) */
1628
+ XPS: "application/vnd.ms-xpsdocument",
1629
+ /** Word 启用宏文档(.docm) */
1630
+ DOCM: "application/vnd.ms-word.document.macroEnabled.12"
1631
+ });
1632
+ /**
1633
+ * 对象工具类
1634
+ */
1635
+ var ObjectUtil = class {
1636
+ static keys(value) {
1637
+ return Object.keys(value);
1638
+ }
1639
+ static values(value) {
1640
+ return Object.values(value);
1641
+ }
1642
+ static entries(value) {
1643
+ return Object.entries(value);
1644
+ }
1645
+ /**
1646
+ * 映射对象条目
1647
+ * - 将对象的键值对映射为新的键值对
1648
+ *
1649
+ * @param plainObject 对象
1650
+ * @param toEntry 映射函数
1651
+ * @returns 映射后的新对象
1652
+ * @example
1653
+ * ```ts
1654
+ * const obj = { a: 1, b: 2 };
1655
+ *
1656
+ * ObjectUtil.entriesMap(obj, (k, v) => [k, v * 2]); // { a: 2, b: 4 }
1657
+ *
1658
+ * ObjectUtil.entriesMap(obj, (k, v) => [`prefix_${String(k)}`, `${v}x`]); // { prefix_a: "1x", prefix_b: "2x" }
1659
+ * ```
1660
+ */
1661
+ static entriesMap(plainObject, toEntry) {
1662
+ const defaultResult = {};
1663
+ if (!TypeUtil.isObject(plainObject)) return defaultResult;
1664
+ return this.entries(plainObject).reduce((acc, [key, value]) => {
1665
+ const [newKey, newValue] = toEntry(key, value);
1666
+ acc[newKey] = newValue;
1667
+ return acc;
1668
+ }, defaultResult);
1669
+ }
1670
+ static pick(obj, keys) {
1671
+ const result = {};
1672
+ if (!TypeUtil.isObject(obj)) return result;
1673
+ if (!TypeUtil.isArray(keys)) return obj;
1674
+ return keys.reduce((acc, key) => {
1675
+ if (key in obj) acc[key] = obj[key];
1676
+ return acc;
1677
+ }, result);
1678
+ }
1679
+ static omit(obj, keys) {
1680
+ const result = {};
1681
+ if (!TypeUtil.isObject(obj)) return result;
1682
+ if (!TypeUtil.isArray(keys)) return obj;
1683
+ const keysToOmit = new Set(keys);
1684
+ return Object.keys(obj).reduce((acc, key) => {
1685
+ if (!keysToOmit.has(key)) acc[key] = obj[key];
1686
+ return acc;
1687
+ }, result);
1688
+ }
1689
+ static invert(obj) {
1690
+ const result = {};
1691
+ if (!TypeUtil.isObject(obj)) return result;
1692
+ for (const [k, v] of this.entries(obj)) if (TypeUtil.isString(v) || TypeUtil.isNumber(v) || TypeUtil.isSymbol(v)) result[v] = k;
1693
+ return result;
1694
+ }
1695
+ static crush(obj) {
1696
+ if (!obj) return {};
1697
+ function crushReducer(crushed, value, path) {
1698
+ if (TypeUtil.isObject(value) || TypeUtil.isArray(value)) for (const [prop, propValue] of Object.entries(value)) crushReducer(crushed, propValue, path ? `${path}.${prop}` : prop);
1699
+ else crushed[path] = value;
1700
+ return crushed;
1701
+ }
1702
+ return crushReducer({}, obj, "");
1703
+ }
1704
+ static enumKeys(enumeration) {
1705
+ const [isEnum, isBidirectionalEnum] = TypeUtil.isEnumeration(enumeration);
1706
+ if (!isEnum) throw Error("function [enumKeys] expected parameter to be a enum, and requires at least one member");
1707
+ const keys = this.keys(enumeration);
1708
+ if (isBidirectionalEnum) return keys.splice(keys.length / 2, keys.length / 2);
1709
+ return keys;
1710
+ }
1711
+ static enumValues(enumeration) {
1712
+ const [isEnum, isBidirectionalEnum] = TypeUtil.isEnumeration(enumeration);
1713
+ if (!isEnum) throw Error("function [enumValues] expected parameter to be a enum, and requires at least one member");
1714
+ const values = this.values(enumeration);
1715
+ if (isBidirectionalEnum) return values.splice(values.length / 2, values.length / 2);
1716
+ return values;
1717
+ }
1718
+ static enumEntries(enumeration) {
1719
+ const [isEnum, isBidirectionalEnum] = TypeUtil.isEnumeration(enumeration);
1720
+ if (!isEnum) throw Error("function [enumEntries] expected parameter to be a enum, and requires at least one member");
1721
+ const entries = this.entries(enumeration);
1722
+ if (isBidirectionalEnum) return entries.splice(entries.length / 2, entries.length / 2);
1723
+ return entries;
1724
+ }
1725
+ };
1726
+ /**
1727
+ * 主题工具类
1728
+ */
1729
+ var ThemeUtil = class {};
1730
+ _defineProperty(ThemeUtil, "THEME", {
1731
+ LIGHT: "light",
1732
+ DARK: "dark"
1733
+ });
1734
+ _defineProperty(ThemeUtil, "THEME_MODE", {
1735
+ LIGHT: "light",
1736
+ DARK: "dark",
1737
+ SYSTEM: "system"
1738
+ });
1739
+ /**
1740
+ * 验证工具类
1741
+ */
1742
+ var ValidateUtil = class {
1743
+ /**
1744
+ * 验证是否为手机号码
1745
+ * @example
1746
+ * ```ts
1747
+ * ValidateUtil.isPhone("13800138000"); // true
1748
+ * ```
1749
+ */
1750
+ static isPhone(input) {
1751
+ return this._phone.test(input.toString());
1752
+ }
1753
+ /**
1754
+ * 验证是否为固定电话
1755
+ * @example
1756
+ * ```ts
1757
+ * ValidateUtil.isTelephone("010-12345678"); // true
1758
+ * ```
1759
+ */
1760
+ static isTelephone(input) {
1761
+ return this._telephone.test(input.toString());
1762
+ }
1763
+ /**
1764
+ * 验证是否为移动设备识别码
1765
+ * @example
1766
+ * ```ts
1767
+ * ValidateUtil.isIMEI("490154203237518"); // true
1768
+ * ```
1769
+ */
1770
+ static isIMEI(input) {
1771
+ return this._IMEI.test(input.toString());
1772
+ }
1773
+ /**
1774
+ * 验证是否为电子邮箱
1775
+ * @example
1776
+ * ```ts
1777
+ * ValidateUtil.isEmail("dev@example.com"); // true
1778
+ * ```
1779
+ */
1780
+ static isEmail(input) {
1781
+ return this._email.test(input.toString());
1782
+ }
1783
+ /**
1784
+ * 验证是否为 http(s) 链接
1785
+ * @example
1786
+ * ```ts
1787
+ * ValidateUtil.isHttpLink("https://example.com/path"); // true
1788
+ * ```
1789
+ */
1790
+ static isHttpLink(input) {
1791
+ return this._link.test(input.toString());
1792
+ }
1793
+ /**
1794
+ * 验证是否为端口号链接
1795
+ * @example
1796
+ * ```ts
1797
+ * ValidateUtil.isPortLink("http://example.com:8080"); // true
1798
+ * ```
1799
+ */
1800
+ static isPortLink(input) {
1801
+ return this._portLink.test(input.toString());
1802
+ }
1803
+ /**
1804
+ * 验证是否为迅雷链接
1805
+ * @example
1806
+ * ```ts
1807
+ * ValidateUtil.isThunderLink("thunder://QUFodHRwOi8vZXhhbXBsZS5jb20vZmlsZQ=="); // true
1808
+ * ```
1809
+ */
1810
+ static isThunderLink(input) {
1811
+ return this._thunderLink.test(input.toString());
1812
+ }
1813
+ /**
1814
+ * 验证是否为统一社会信用代码
1815
+ * @example
1816
+ * ```ts
1817
+ * ValidateUtil.isUSCC("91350100M000100Y43"); // true
1818
+ * ```
1819
+ */
1820
+ static isUSCC(input) {
1821
+ return this._uscc.test(input.toString());
1822
+ }
1823
+ /**
1824
+ * 验证是否为统一社会信用代码 - 15位/18位/20位数字/字母
1825
+ * @example
1826
+ * ```ts
1827
+ * ValidateUtil.isUSCCS("91350100M000100Y43"); // true
1828
+ * ```
1829
+ */
1830
+ static isUSCCS(input) {
1831
+ return this._usccs.test(input.toString());
1832
+ }
1833
+ /**
1834
+ * 验证是否为 Windows 系统文件夹路径
1835
+ * @example
1836
+ * ```ts
1837
+ * ValidateUtil.isDirPathWindows("C:\\Users\\pawover\\"); // true
1838
+ * ```
1839
+ */
1840
+ static isDirPathWindows(input) {
1841
+ return this._dirPathWindows.test(input.toString());
1842
+ }
1843
+ /**
1844
+ * 验证是否为 Windows 系统文件路径
1845
+ * @example
1846
+ * ```ts
1847
+ * ValidateUtil.isFilePathWindows("C:\\Users\\pawover\\a.txt"); // true
1848
+ * ```
1849
+ */
1850
+ static isFilePathWindows(input) {
1851
+ return this._filePathWindows.test(input.toString());
1852
+ }
1853
+ /**
1854
+ * 验证是否为 Linux 系统文件夹路径
1855
+ * @example
1856
+ * ```ts
1857
+ * ValidateUtil.isDirPathLinux("/usr/local/"); // true
1858
+ * ```
1859
+ */
1860
+ static isDirPathLinux(input) {
1861
+ return this._dirPathLinux.test(input.toString());
1862
+ }
1863
+ /**
1864
+ * 验证是否为 Linux 系统文件路径
1865
+ * @example
1866
+ * ```ts
1867
+ * ValidateUtil.isFilePathLinux("/usr/local/bin/node"); // true
1868
+ * ```
1869
+ */
1870
+ static isFilePathLinux(input) {
1871
+ return this._filePathLinux.test(input.toString());
1872
+ }
1873
+ /**
1874
+ * 验证是否为新能源车牌号
1875
+ * @example
1876
+ * ```ts
1877
+ * ValidateUtil.isEVCarNumber("粤AD12345"); // true
1878
+ * ```
1879
+ */
1880
+ static isEVCarNumber(input) {
1881
+ return this._EVCarNumber.test(input.toString());
1882
+ }
1883
+ /**
1884
+ * 验证是否为燃油车车牌号
1885
+ * @example
1886
+ * ```ts
1887
+ * ValidateUtil.isGVCarNumber("粤B12345"); // true
1888
+ * ```
1889
+ */
1890
+ static isGVCarNumber(input) {
1891
+ return this._GVCarNumber.test(input.toString());
1892
+ }
1893
+ /**
1894
+ * 验证是否为中文姓名
1895
+ * @example
1896
+ * ```ts
1897
+ * ValidateUtil.isChineseName("张三"); // true
1898
+ * ```
1899
+ */
1900
+ static isChineseName(input) {
1901
+ return this._chineseName.test(input.toString());
1902
+ }
1903
+ /**
1904
+ * 验证是否为中国身份证号
1905
+ * @example
1906
+ * ```ts
1907
+ * ValidateUtil.isChineseID("11010519491231002X"); // true
1908
+ * ```
1909
+ */
1910
+ static isChineseID(input) {
1911
+ return this._chineseId.test(input.toString());
1912
+ }
1913
+ /**
1914
+ * 验证是否为中国省份
1915
+ * @example
1916
+ * ```ts
1917
+ * ValidateUtil.isChineseProvince("浙江"); // true
1918
+ * ```
1919
+ */
1920
+ static isChineseProvince(input) {
1921
+ return this._chineseProvince.test(input.toString());
1922
+ }
1923
+ /**
1924
+ * 验证是否为中华民族
1925
+ * @example
1926
+ * ```ts
1927
+ * ValidateUtil.isChineseNation("汉族"); // true
1928
+ * ```
1929
+ */
1930
+ static isChineseNation(input) {
1931
+ return this._chineseNation.test(input.toString());
1932
+ }
1933
+ /**
1934
+ * 验证是否只包含字母
1935
+ * @example
1936
+ * ```ts
1937
+ * ValidateUtil.isLetter("abcDEF"); // true
1938
+ * ```
1939
+ */
1940
+ static isLetter(input) {
1941
+ return this._letter.test(input.toString());
1942
+ }
1943
+ /**
1944
+ * 验证是否只包含小写字母
1945
+ * @example
1946
+ * ```ts
1947
+ * ValidateUtil.isLetterLowercase("abc"); // true
1948
+ * ```
1949
+ */
1950
+ static isLetterLowercase(input) {
1951
+ return this._letterLowercase.test(input.toString());
1952
+ }
1953
+ /**
1954
+ * 验证是否只包含大写字母
1955
+ * @example
1956
+ * ```ts
1957
+ * ValidateUtil.isLetterUppercase("ABC"); // true
1958
+ * ```
1959
+ */
1960
+ static isLetterUppercase(input) {
1961
+ return this._letterUppercase.test(input.toString());
1962
+ }
1963
+ /**
1964
+ * 验证是否不包含字母
1965
+ * @example
1966
+ * ```ts
1967
+ * ValidateUtil.isLetterOmit("123_-"); // true
1968
+ * ```
1969
+ */
1970
+ static isLetterOmit(input) {
1971
+ return this._letterOmit.test(input.toString());
1972
+ }
1973
+ /**
1974
+ * 验证是否为数字和字母组合
1975
+ * @example
1976
+ * ```ts
1977
+ * ValidateUtil.isLetterAndNumber("A1B2"); // true
1978
+ * ```
1979
+ */
1980
+ static isLetterAndNumber(input) {
1981
+ return this._LetterAndNumber.test(input.toString());
1982
+ }
1983
+ /**
1984
+ * 验证是否为有符号浮点数
1985
+ * @example
1986
+ * ```ts
1987
+ * ValidateUtil.isSignedFloat("-12.34"); // true
1988
+ * ```
1989
+ */
1990
+ static isSignedFloat(input) {
1991
+ return this._signedFloat.test(input.toString());
1992
+ }
1993
+ /**
1994
+ * 验证是否为无符号浮点数
1995
+ * @example
1996
+ * ```ts
1997
+ * ValidateUtil.isUnsignedFloat("12.34"); // true
1998
+ * ```
1999
+ */
2000
+ static isUnsignedFloat(input) {
2001
+ return this._unsignedFloat.test(input.toString());
2002
+ }
2003
+ /**
2004
+ * 验证是否为有符号整数
2005
+ * @example
2006
+ * ```ts
2007
+ * ValidateUtil.isSignedInteger("-12"); // true
2008
+ * ```
2009
+ */
2010
+ static isSignedInteger(input) {
2011
+ return this._signedInteger.test(input.toString());
2012
+ }
2013
+ /**
2014
+ * 验证是否为无符号整数
2015
+ * @example
2016
+ * ```ts
2017
+ * ValidateUtil.isUnsignedInteger("12"); // true
2018
+ * ```
2019
+ */
2020
+ static isUnsignedInteger(input) {
2021
+ return this._unsignedInteger.test(input.toString());
2022
+ }
2023
+ /**
2024
+ * 验证是否包含空格
2025
+ * @example
2026
+ * ```ts
2027
+ * ValidateUtil.isSpaceInclude("a b"); // true
2028
+ * ```
2029
+ */
2030
+ static isSpaceInclude(input) {
2031
+ return this._spaceInclude.test(input.toString());
2032
+ }
2033
+ /**
2034
+ * 验证是否以空格开头
2035
+ * @example
2036
+ * ```ts
2037
+ * ValidateUtil.isSpaceStart(" abc"); // true
2038
+ * ```
2039
+ */
2040
+ static isSpaceStart(input) {
2041
+ return this._spaceStart.test(input.toString());
2042
+ }
2043
+ /**
2044
+ * 验证是否以空格结尾
2045
+ * @example
2046
+ * ```ts
2047
+ * ValidateUtil.isSpaceEnd("abc "); // true
2048
+ * ```
2049
+ */
2050
+ static isSpaceEnd(input) {
2051
+ return this._spaceEnd.test(input.toString());
2052
+ }
2053
+ /**
2054
+ * 验证是否以空格开头或结尾
2055
+ * @example
2056
+ * ```ts
2057
+ * ValidateUtil.isSpaceStartOrEnd(" abc"); // true
2058
+ * ```
2059
+ */
2060
+ static isSpaceStartOrEnd(input) {
2061
+ return this.isSpaceStart(input) || this.isSpaceEnd(input);
2062
+ }
2063
+ };
2064
+ _defineProperty(ValidateUtil, "_phone", /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/);
2065
+ _defineProperty(ValidateUtil, "_telephone", /^(((0\d{2,3})-)?((\d{7,8})|(400\d{7})|(800\d{7}))(-(\d{1,4}))?)$/);
2066
+ _defineProperty(ValidateUtil, "_IMEI", /^\d{15,17}$/);
2067
+ _defineProperty(ValidateUtil, "_email", /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-z\-0-9]+\.)+[a-z]{2,}))$/i);
2068
+ _defineProperty(ValidateUtil, "_link", /^(https?:\/\/)?(([\w-]+(\.[\w-]+)*\.[a-z]{2,6})|((\d{1,3}\.){3}\d{1,3}))(:\d+)?(\/\S*)?$/i);
2069
+ _defineProperty(ValidateUtil, "_portLink", /^(https?:\/\/)?[\w-]+(\.[\w-]+)+:\d{1,5}\/?$/i);
2070
+ _defineProperty(ValidateUtil, "_thunderLink", /^thunderx?:\/\/[a-zA-Z\d]+=$/i);
2071
+ _defineProperty(ValidateUtil, "_uscc", /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/);
2072
+ _defineProperty(ValidateUtil, "_usccs", /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/);
2073
+ _defineProperty(ValidateUtil, "_dirPathWindows", /^[a-z]:\\(?:\w+\\?)*$/i);
2074
+ _defineProperty(ValidateUtil, "_filePathWindows", /^[a-z]:\\(?:\w+\\)*\w+\.\w+$/i);
2075
+ _defineProperty(ValidateUtil, "_dirPathLinux", /^\/(?:[^\\/\s]+\/)*$/);
2076
+ _defineProperty(ValidateUtil, "_filePathLinux", /^(\/$|\/(?:[^\\/\s]+\/)*[^\\/\s]+$)/);
2077
+ _defineProperty(ValidateUtil, "_EVCarNumber", /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](([DF]((?![IO])[a-zA-Z0-9](?![IO]))\d{4})|(\d{5}[DF]))$/);
2078
+ _defineProperty(ValidateUtil, "_GVCarNumber", /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/);
2079
+ _defineProperty(ValidateUtil, "_chineseName", /^[一-龢][一·-龢]*$/);
2080
+ _defineProperty(ValidateUtil, "_chineseId", /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))([\dX])$/i);
2081
+ _defineProperty(ValidateUtil, "_chineseProvince", /^安徽|澳门|北京|重庆|福建|甘肃|广东|广西|贵州|海南|河北|河南|黑龙江|湖北|湖南|吉林|江苏|江西|辽宁|内蒙古|宁夏|青海|山东|山西|陕西|上海|四川|台湾|天津|西藏|香港|新疆|云南|浙江$/);
2082
+ _defineProperty(ValidateUtil, "_chineseNation", /^汉族|蒙古族|回族|藏族|维吾尔族|苗族|彝族|壮族|布依族|朝鲜族|满族|侗族|瑶族|白族|土家族|哈尼族|哈萨克族|傣族|黎族|傈僳族|佤族|畲族|高山族|拉祜族|水族|东乡族|纳西族|景颇族|柯尔克孜族|土族|达斡尔族|仫佬族|羌族|布朗族|撒拉族|毛南族|仡佬族|锡伯族|阿昌族|普米族|塔吉克族|怒族|乌孜别克族|俄罗斯族|鄂温克族|德昂族|保安族|裕固族|京族|塔塔尔族|独龙族|鄂伦春族|赫哲族|门巴族|珞巴族|基诺族|其它未识别民族|外国人入中国籍$/);
2083
+ _defineProperty(ValidateUtil, "_letter", /^[a-z]+$/i);
2084
+ _defineProperty(ValidateUtil, "_letterLowercase", /^[a-z]+$/);
2085
+ _defineProperty(ValidateUtil, "_letterUppercase", /^[A-Z]+$/);
2086
+ _defineProperty(ValidateUtil, "_letterOmit", /^[^A-Z]*$/i);
2087
+ _defineProperty(ValidateUtil, "_LetterAndNumber", /^[A-Z0-9]+$/i);
2088
+ _defineProperty(ValidateUtil, "_signedFloat", /^[+-]?(\d+(\.\d+)?|\.\d+)$/);
2089
+ _defineProperty(ValidateUtil, "_unsignedFloat", /^\+?(\d+(\.\d+)?|\.\d+)$/);
2090
+ _defineProperty(ValidateUtil, "_signedInteger", /^[+-]?\d+$/);
2091
+ _defineProperty(ValidateUtil, "_unsignedInteger", /^\+?\d+$/);
2092
+ _defineProperty(ValidateUtil, "_spaceInclude", /\s/);
2093
+ _defineProperty(ValidateUtil, "_spaceStart", /^\s/);
2094
+ _defineProperty(ValidateUtil, "_spaceEnd", /\s$/);
2095
+ //#endregion
2096
+ //#region src/react/useMount.ts
2097
+ /**
2098
+ * 在组件初始化时执行的 Hook
2099
+ * - 即使在严格模式(React StrictMode)也只执行一次
2100
+ * - 自动使用最新版 effect 函数
2101
+ *
2102
+ * @param effect 副作用函数(必须为同步函数;若为异步函数,清理逻辑需自行处理)
2103
+ * @example
2104
+ * useMount(() => {
2105
+ * console.log('组件挂载');
2106
+ * return () => console.log('组件卸载');
2107
+ * });
2108
+ *
2109
+ * useMount(async () => {
2110
+ * const data = await fetchData();
2111
+ * // 清理逻辑需通过 ref/AbortController 自行管理
2112
+ * // ❌ 不要 return cleanupFn(async 函数返回 Promise,无法作为清理函数)
2113
+ * });
2114
+ */
2115
+ function useMount(effect) {
2116
+ const isMountedRef = useRef(false);
2117
+ const effectRef = useLatest(effect);
2118
+ useEffect(() => {
2119
+ if (!TypeUtil.isFunction(effectRef.current)) {
2120
+ console.error(`hook [useMount] Expected parameter to be a function, but got ${typeof effectRef.current}. This effect will not execute.`);
2121
+ return;
2122
+ }
2123
+ if (isMountedRef.current) return;
2124
+ isMountedRef.current = true;
2125
+ const cleanup = effectRef.current?.();
2126
+ return TypeUtil.isFunction(cleanup) && !TypeUtil.isPromise(cleanup) ? cleanup : void 0;
2127
+ }, [effectRef]);
2128
+ }
2129
+ //#endregion
2130
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/_internal/globalThis.mjs
2131
+ const globalThis_ = typeof globalThis === "object" && globalThis || typeof window === "object" && window || typeof self === "object" && self || typeof global === "object" && global || (function() {
2132
+ return this;
2133
+ })() || Function("return this")();
2134
+ //#endregion
2135
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/function/noop.mjs
2136
+ /**
2137
+ * A no-operation function that does nothing.
2138
+ * This can be used as a placeholder or default function.
2139
+ *
2140
+ * @example
2141
+ * noop(); // Does nothing
2142
+ *
2143
+ * @returns {void} This function does not return anything.
2144
+ */
2145
+ function noop() {}
2146
+ //#endregion
2147
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isPrimitive.mjs
2148
+ /**
2149
+ * Checks whether a value is a JavaScript primitive.
2150
+ * JavaScript primitives include null, undefined, strings, numbers, booleans, symbols, and bigints.
2151
+ *
2152
+ * @param {unknown} value The value to check.
2153
+ * @returns {value is
2154
+ * null
2155
+ * | undefined
2156
+ * | string
2157
+ * | number
2158
+ * | boolean
2159
+ * | symbol
2160
+ * | bigint} Returns true if `value` is a primitive, false otherwise.
2161
+ *
2162
+ * @example
2163
+ * isPrimitive(null); // true
2164
+ * isPrimitive(undefined); // true
2165
+ * isPrimitive('123'); // true
2166
+ * isPrimitive(false); // true
2167
+ * isPrimitive(true); // true
2168
+ * isPrimitive(Symbol('a')); // true
2169
+ * isPrimitive(123n); // true
2170
+ * isPrimitive({}); // false
2171
+ * isPrimitive(new Date()); // false
2172
+ * isPrimitive(new Map()); // false
2173
+ * isPrimitive(new Set()); // false
2174
+ * isPrimitive([1, 2, 3]); // false
2175
+ */
2176
+ function isPrimitive(value) {
2177
+ return value == null || typeof value !== "object" && typeof value !== "function";
2178
+ }
2179
+ //#endregion
2180
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isTypedArray.mjs
2181
+ /**
2182
+ * Checks if a value is a TypedArray.
2183
+ * @param {unknown} x The value to check.
2184
+ * @returns {x is
2185
+ * Uint8Array
2186
+ * | Uint8ClampedArray
2187
+ * | Uint16Array
2188
+ * | Uint32Array
2189
+ * | BigUint64Array
2190
+ * | Int8Array
2191
+ * | Int16Array
2192
+ * | Int32Array
2193
+ * | BigInt64Array
2194
+ * | Float32Array
2195
+ * | Float64Array} Returns true if `x` is a TypedArray, false otherwise.
2196
+ *
2197
+ * @example
2198
+ * const arr = new Uint8Array([1, 2, 3]);
2199
+ * isTypedArray(arr); // true
2200
+ *
2201
+ * const regularArray = [1, 2, 3];
2202
+ * isTypedArray(regularArray); // false
2203
+ *
2204
+ * const buffer = new ArrayBuffer(16);
2205
+ * isTypedArray(buffer); // false
2206
+ */
2207
+ function isTypedArray(x) {
2208
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
2209
+ }
2210
+ //#endregion
2211
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/object/clone.mjs
2212
+ /**
2213
+ * Creates a shallow clone of the given object.
2214
+ *
2215
+ * @template T - The type of the object.
2216
+ * @param {T} obj - The object to clone.
2217
+ * @returns {T} - A shallow clone of the given object.
2218
+ *
2219
+ * @example
2220
+ * // Clone a primitive values
2221
+ * const num = 29;
2222
+ * const clonedNum = clone(num);
2223
+ * console.log(clonedNum); // 29
2224
+ * console.log(clonedNum === num); // true
2225
+ *
2226
+ * @example
2227
+ * // Clone an array
2228
+ * const arr = [1, 2, 3];
2229
+ * const clonedArr = clone(arr);
2230
+ * console.log(clonedArr); // [1, 2, 3]
2231
+ * console.log(clonedArr === arr); // false
2232
+ *
2233
+ * @example
2234
+ * // Clone an object
2235
+ * const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] };
2236
+ * const clonedObj = clone(obj);
2237
+ * console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] }
2238
+ * console.log(clonedObj === obj); // false
2239
+ */
2240
+ function clone(obj) {
2241
+ if (isPrimitive(obj)) return obj;
2242
+ if (Array.isArray(obj) || isTypedArray(obj) || obj instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && obj instanceof SharedArrayBuffer) return obj.slice(0);
2243
+ const prototype = Object.getPrototypeOf(obj);
2244
+ if (prototype == null) return Object.assign(Object.create(prototype), obj);
2245
+ const Constructor = prototype.constructor;
2246
+ if (obj instanceof Date || obj instanceof Map || obj instanceof Set) return new Constructor(obj);
2247
+ if (obj instanceof RegExp) {
2248
+ const newRegExp = new Constructor(obj);
2249
+ newRegExp.lastIndex = obj.lastIndex;
2250
+ return newRegExp;
2251
+ }
2252
+ if (obj instanceof DataView) return new Constructor(obj.buffer.slice(0));
2253
+ if (obj instanceof Error) {
2254
+ let newError;
2255
+ if (obj instanceof AggregateError) newError = new Constructor(obj.errors, obj.message, { cause: obj.cause });
2256
+ else newError = new Constructor(obj.message, { cause: obj.cause });
2257
+ newError.stack = obj.stack;
2258
+ Object.assign(newError, obj);
2259
+ return newError;
2260
+ }
2261
+ if (typeof File !== "undefined" && obj instanceof File) return new Constructor([obj], obj.name, {
2262
+ type: obj.type,
2263
+ lastModified: obj.lastModified
2264
+ });
2265
+ if (typeof obj === "object") return Object.assign(Object.create(prototype), obj);
2266
+ return obj;
2267
+ }
2268
+ //#endregion
2269
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isBuffer.mjs
2270
+ /**
2271
+ * Checks if the given value is a Buffer instance.
2272
+ *
2273
+ * This function tests whether the provided value is an instance of Buffer.
2274
+ * It returns `true` if the value is a Buffer, and `false` otherwise.
2275
+ *
2276
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Buffer`.
2277
+ *
2278
+ * @param {unknown} x - The value to check if it is a Buffer.
2279
+ * @returns {boolean} Returns `true` if `x` is a Buffer, else `false`.
2280
+ *
2281
+ * @example
2282
+ * const buffer = Buffer.from("test");
2283
+ * console.log(isBuffer(buffer)); // true
2284
+ *
2285
+ * const notBuffer = "not a buffer";
2286
+ * console.log(isBuffer(notBuffer)); // false
2287
+ */
2288
+ function isBuffer(x) {
2289
+ return typeof globalThis_.Buffer !== "undefined" && globalThis_.Buffer.isBuffer(x);
2290
+ }
2291
+ //#endregion
2292
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/compat/_internal/getSymbols.mjs
2293
+ function getSymbols(object) {
2294
+ return Object.getOwnPropertySymbols(object).filter((symbol) => Object.prototype.propertyIsEnumerable.call(object, symbol));
2295
+ }
2296
+ //#endregion
2297
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/compat/_internal/getTag.mjs
2298
+ /**
2299
+ * Gets the `toStringTag` of `value`.
2300
+ *
2301
+ * @private
2302
+ * @param {T} value The value to query.
2303
+ * @returns {string} Returns the `Object.prototype.toString.call` result.
2304
+ */
2305
+ function getTag(value) {
2306
+ if (value == null) return value === void 0 ? "[object Undefined]" : "[object Null]";
2307
+ return Object.prototype.toString.call(value);
2308
+ }
2309
+ //#endregion
2310
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/compat/_internal/tags.mjs
2311
+ const regexpTag = "[object RegExp]";
2312
+ const stringTag = "[object String]";
2313
+ const numberTag = "[object Number]";
2314
+ const booleanTag = "[object Boolean]";
2315
+ const symbolTag = "[object Symbol]";
2316
+ const dateTag = "[object Date]";
2317
+ const mapTag = "[object Map]";
2318
+ const setTag = "[object Set]";
2319
+ const arrayTag = "[object Array]";
2320
+ const functionTag = "[object Function]";
2321
+ const arrayBufferTag = "[object ArrayBuffer]";
2322
+ const objectTag = "[object Object]";
2323
+ const errorTag = "[object Error]";
2324
+ const dataViewTag = "[object DataView]";
2325
+ const uint8ArrayTag = "[object Uint8Array]";
2326
+ const uint8ClampedArrayTag = "[object Uint8ClampedArray]";
2327
+ const uint16ArrayTag = "[object Uint16Array]";
2328
+ const uint32ArrayTag = "[object Uint32Array]";
2329
+ const bigUint64ArrayTag = "[object BigUint64Array]";
2330
+ const int8ArrayTag = "[object Int8Array]";
2331
+ const int16ArrayTag = "[object Int16Array]";
2332
+ const int32ArrayTag = "[object Int32Array]";
2333
+ const bigInt64ArrayTag = "[object BigInt64Array]";
2334
+ const float32ArrayTag = "[object Float32Array]";
2335
+ const float64ArrayTag = "[object Float64Array]";
2336
+ //#endregion
2337
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
2338
+ /**
2339
+ * Checks if a given value is a plain object.
2340
+ *
2341
+ * @param {object} value - The value to check.
2342
+ * @returns {value is Record<PropertyKey, any>} - True if the value is a plain object, otherwise false.
2343
+ *
2344
+ * @example
2345
+ * ```typescript
2346
+ * // ✅👇 True
2347
+ *
2348
+ * isPlainObject({ }); // ✅
2349
+ * isPlainObject({ key: 'value' }); // ✅
2350
+ * isPlainObject({ key: new Date() }); // ✅
2351
+ * isPlainObject(new Object()); // ✅
2352
+ * isPlainObject(Object.create(null)); // ✅
2353
+ * isPlainObject({ nested: { key: true} }); // ✅
2354
+ * isPlainObject(new Proxy({}, {})); // ✅
2355
+ * isPlainObject({ [Symbol('tag')]: 'A' }); // ✅
2356
+ *
2357
+ * // ✅👇 (cross-realms, node context, workers, ...)
2358
+ * const runInNewContext = await import('node:vm').then(
2359
+ * (mod) => mod.runInNewContext
2360
+ * );
2361
+ * isPlainObject(runInNewContext('({})')); // ✅
2362
+ *
2363
+ * // ❌👇 False
2364
+ *
2365
+ * class Test { };
2366
+ * isPlainObject(new Test()) // ❌
2367
+ * isPlainObject(10); // ❌
2368
+ * isPlainObject(null); // ❌
2369
+ * isPlainObject('hello'); // ❌
2370
+ * isPlainObject([]); // ❌
2371
+ * isPlainObject(new Date()); // ❌
2372
+ * isPlainObject(new Uint8Array([1])); // ❌
2373
+ * isPlainObject(Buffer.from('ABC')); // ❌
2374
+ * isPlainObject(Promise.resolve({})); // ❌
2375
+ * isPlainObject(Object.create({})); // ❌
2376
+ * isPlainObject(new (class Cls {})); // ❌
2377
+ * isPlainObject(globalThis); // ❌,
2378
+ * ```
2379
+ */
2380
+ function isPlainObject(value) {
2381
+ if (!value || typeof value !== "object") return false;
2382
+ const proto = Object.getPrototypeOf(value);
2383
+ if (!(proto === null || proto === Object.prototype || Object.getPrototypeOf(proto) === null)) return false;
2384
+ return Object.prototype.toString.call(value) === "[object Object]";
2385
+ }
2386
+ //#endregion
2387
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/_internal/isEqualsSameValueZero.mjs
2388
+ /**
2389
+ * Performs a `SameValueZero` comparison between two values to determine if they are equivalent.
2390
+ *
2391
+ * @param {any} value - The value to compare.
2392
+ * @param {any} other - The other value to compare.
2393
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2394
+ *
2395
+ * @example
2396
+ * eq(1, 1); // true
2397
+ * eq(0, -0); // true
2398
+ * eq(NaN, NaN); // true
2399
+ * eq('a', Object('a')); // false
2400
+ */
2401
+ function isEqualsSameValueZero(value, other) {
2402
+ return value === other || Number.isNaN(value) && Number.isNaN(other);
2403
+ }
2404
+ //#endregion
2405
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isEqualWith.mjs
2406
+ /**
2407
+ * Compares two values for equality using a custom comparison function.
2408
+ *
2409
+ * The custom function allows for fine-tuned control over the comparison process. If it returns a boolean, that result determines the equality. If it returns undefined, the function falls back to the default equality comparison.
2410
+ *
2411
+ * This function also uses the custom equality function to compare values inside objects,
2412
+ * arrays, maps, sets, and other complex structures, ensuring a deep comparison.
2413
+ *
2414
+ * This approach provides flexibility in handling complex comparisons while maintaining efficient default behavior for simpler cases.
2415
+ *
2416
+ * The custom comparison function can take up to six parameters:
2417
+ * - `x`: The value from the first object `a`.
2418
+ * - `y`: The value from the second object `b`.
2419
+ * - `property`: The property key used to get `x` and `y`.
2420
+ * - `xParent`: The parent of the first value `x`.
2421
+ * - `yParent`: The parent of the second value `y`.
2422
+ * - `stack`: An internal stack (Map) to handle circular references.
2423
+ *
2424
+ * @param {unknown} a - The first value to compare.
2425
+ * @param {unknown} b - The second value to compare.
2426
+ * @param {(x: any, y: any, property?: PropertyKey, xParent?: any, yParent?: any, stack?: Map<any, any>) => boolean | void} areValuesEqual - A function to customize the comparison.
2427
+ * If it returns a boolean, that result will be used. If it returns undefined,
2428
+ * the default equality comparison will be used.
2429
+ * @returns {boolean} `true` if the values are equal according to the customizer, otherwise `false`.
2430
+ *
2431
+ * @example
2432
+ * const customizer = (a, b) => {
2433
+ * if (typeof a === 'string' && typeof b === 'string') {
2434
+ * return a.toLowerCase() === b.toLowerCase();
2435
+ * }
2436
+ * };
2437
+ * isEqualWith('Hello', 'hello', customizer); // true
2438
+ * isEqualWith({ a: 'Hello' }, { a: 'hello' }, customizer); // true
2439
+ * isEqualWith([1, 2, 3], [1, 2, 3], customizer); // true
2440
+ */
2441
+ function isEqualWith(a, b, areValuesEqual) {
2442
+ return isEqualWithImpl(a, b, void 0, void 0, void 0, void 0, areValuesEqual);
2443
+ }
2444
+ function isEqualWithImpl(a, b, property, aParent, bParent, stack, areValuesEqual) {
2445
+ const result = areValuesEqual(a, b, property, aParent, bParent, stack);
2446
+ if (result !== void 0) return result;
2447
+ if (typeof a === typeof b) switch (typeof a) {
2448
+ case "bigint":
2449
+ case "string":
2450
+ case "boolean":
2451
+ case "symbol":
2452
+ case "undefined": return a === b;
2453
+ case "number": return a === b || Object.is(a, b);
2454
+ case "function": return a === b;
2455
+ case "object": return areObjectsEqual(a, b, stack, areValuesEqual);
2456
+ }
2457
+ return areObjectsEqual(a, b, stack, areValuesEqual);
2458
+ }
2459
+ function areObjectsEqual(a, b, stack, areValuesEqual) {
2460
+ if (Object.is(a, b)) return true;
2461
+ let aTag = getTag(a);
2462
+ let bTag = getTag(b);
2463
+ if (aTag === "[object Arguments]") aTag = objectTag;
2464
+ if (bTag === "[object Arguments]") bTag = objectTag;
2465
+ if (aTag !== bTag) return false;
2466
+ switch (aTag) {
2467
+ case stringTag: return a.toString() === b.toString();
2468
+ case numberTag: return isEqualsSameValueZero(a.valueOf(), b.valueOf());
2469
+ case booleanTag:
2470
+ case dateTag:
2471
+ case symbolTag: return Object.is(a.valueOf(), b.valueOf());
2472
+ case regexpTag: return a.source === b.source && a.flags === b.flags;
2473
+ case functionTag: return a === b;
2474
+ }
2475
+ stack = stack ?? /* @__PURE__ */ new Map();
2476
+ const aStack = stack.get(a);
2477
+ const bStack = stack.get(b);
2478
+ if (aStack != null && bStack != null) return aStack === b;
2479
+ stack.set(a, b);
2480
+ stack.set(b, a);
2481
+ try {
2482
+ switch (aTag) {
2483
+ case mapTag:
2484
+ if (a.size !== b.size) return false;
2485
+ for (const [key, value] of a.entries()) if (!b.has(key) || !isEqualWithImpl(value, b.get(key), key, a, b, stack, areValuesEqual)) return false;
2486
+ return true;
2487
+ case setTag: {
2488
+ if (a.size !== b.size) return false;
2489
+ const aValues = Array.from(a.values());
2490
+ const bValues = Array.from(b.values());
2491
+ for (let i = 0; i < aValues.length; i++) {
2492
+ const aValue = aValues[i];
2493
+ const index = bValues.findIndex((bValue) => {
2494
+ return isEqualWithImpl(aValue, bValue, void 0, a, b, stack, areValuesEqual);
2495
+ });
2496
+ if (index === -1) return false;
2497
+ bValues.splice(index, 1);
2498
+ }
2499
+ return true;
2500
+ }
2501
+ case arrayTag:
2502
+ case uint8ArrayTag:
2503
+ case uint8ClampedArrayTag:
2504
+ case uint16ArrayTag:
2505
+ case uint32ArrayTag:
2506
+ case bigUint64ArrayTag:
2507
+ case int8ArrayTag:
2508
+ case int16ArrayTag:
2509
+ case int32ArrayTag:
2510
+ case bigInt64ArrayTag:
2511
+ case float32ArrayTag:
2512
+ case float64ArrayTag:
2513
+ if (isBuffer(a) !== isBuffer(b)) return false;
2514
+ if (a.length !== b.length) return false;
2515
+ for (let i = 0; i < a.length; i++) if (!isEqualWithImpl(a[i], b[i], i, a, b, stack, areValuesEqual)) return false;
2516
+ return true;
2517
+ case arrayBufferTag:
2518
+ if (a.byteLength !== b.byteLength) return false;
2519
+ return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
2520
+ case dataViewTag:
2521
+ if (a.byteLength !== b.byteLength || a.byteOffset !== b.byteOffset) return false;
2522
+ return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
2523
+ case errorTag: return a.name === b.name && a.message === b.message;
2524
+ case objectTag: {
2525
+ if (!(areObjectsEqual(a.constructor, b.constructor, stack, areValuesEqual) || isPlainObject(a) && isPlainObject(b))) return false;
2526
+ const aKeys = [...Object.keys(a), ...getSymbols(a)];
2527
+ const bKeys = [...Object.keys(b), ...getSymbols(b)];
2528
+ if (aKeys.length !== bKeys.length) return false;
2529
+ for (let i = 0; i < aKeys.length; i++) {
2530
+ const propKey = aKeys[i];
2531
+ const aProp = a[propKey];
2532
+ if (!Object.hasOwn(b, propKey)) return false;
2533
+ const bProp = b[propKey];
2534
+ if (!isEqualWithImpl(aProp, bProp, propKey, a, b, stack, areValuesEqual)) return false;
2535
+ }
2536
+ return true;
2537
+ }
2538
+ default: return false;
2539
+ }
2540
+ } finally {
2541
+ stack.delete(a);
2542
+ stack.delete(b);
2543
+ }
2544
+ }
2545
+ //#endregion
2546
+ //#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isEqual.mjs
2547
+ /**
2548
+ * Checks if two values are equal, including support for `Date`, `RegExp`, and deep object comparison.
2549
+ *
2550
+ * @param {unknown} a - The first value to compare.
2551
+ * @param {unknown} b - The second value to compare.
2552
+ * @returns {boolean} `true` if the values are equal, otherwise `false`.
2553
+ *
2554
+ * @example
2555
+ * isEqual(1, 1); // true
2556
+ * isEqual({ a: 1 }, { a: 1 }); // true
2557
+ * isEqual(/abc/g, /abc/g); // true
2558
+ * isEqual(new Date('2020-01-01'), new Date('2020-01-01')); // true
2559
+ * isEqual([1, 2, 3], [1, 2, 3]); // true
2560
+ */
2561
+ function isEqual(a, b) {
2562
+ return isEqualWith(a, b, noop);
2563
+ }
2564
+ //#endregion
2565
+ //#region src/react/useResponsive.ts
2566
+ /** 屏幕响应断点 token 配置 */
2567
+ const BREAK_POINT_TOKEN = {
2568
+ XS: 480,
2569
+ XSMax: 575,
2570
+ XSMin: 480,
2571
+ SM: 576,
2572
+ SMMax: 767,
2573
+ SMMin: 576,
2574
+ MD: 768,
2575
+ MDMax: 991,
2576
+ MDMin: 768,
2577
+ LG: 992,
2578
+ LGMax: 1199,
2579
+ LGMin: 992,
2580
+ XL: 1200,
2581
+ XLMax: 1599,
2582
+ XLMin: 1200,
2583
+ XXL: 1600,
2584
+ XXLMax: 1919,
2585
+ XXLMin: 1600,
2586
+ XXXL: 1920,
2587
+ XXXLMin: 1920
2588
+ };
2589
+ const SUBSCRIBER_SET = /* @__PURE__ */ new Set();
2590
+ const BREAK_POINTS = [
2591
+ "xxxl",
2592
+ "xxl",
2593
+ "xl",
2594
+ "lg",
2595
+ "md",
2596
+ "sm",
2597
+ "xs"
2598
+ ];
2599
+ const DEFAULT_VALUES = Object.freeze(ArrayUtil.zipToObject(BREAK_POINTS, false));
2600
+ let responsiveValues = { ...DEFAULT_VALUES };
2601
+ let responsiveTokens = clone(BREAK_POINT_TOKEN);
2602
+ function useResponsive(options) {
2603
+ const { breakPointTokens = {} } = options || {};
2604
+ const tokens = useMemo(() => Object.assign(BREAK_POINT_TOKEN, breakPointTokens), [breakPointTokens]);
2605
+ const [responsive, setResponsive] = useState(() => calculateResponsive(tokens));
2606
+ const current = ObjectUtil.keys(DEFAULT_VALUES).find((key) => responsive[key] === true) || "xs";
2607
+ useLayoutEffect(() => {
2608
+ responsiveTokens = tokens;
2609
+ window.addEventListener("resize", resizeListener);
2610
+ const subscriber = () => {
2611
+ setResponsive(responsiveValues);
2612
+ };
2613
+ SUBSCRIBER_SET.add(subscriber);
2614
+ return () => {
2615
+ SUBSCRIBER_SET.delete(subscriber);
2616
+ if (!SUBSCRIBER_SET.size) window.removeEventListener("resize", resizeListener);
2617
+ };
2618
+ }, [tokens]);
2619
+ return {
2620
+ responsive,
2621
+ current,
2622
+ breakPointTokens: tokens
2623
+ };
2624
+ }
2625
+ function resizeListener() {
2626
+ const newValues = calculateResponsive(responsiveTokens);
2627
+ if (!isEqual(responsiveValues, newValues)) {
2628
+ responsiveValues = newValues;
2629
+ for (const subscriber of SUBSCRIBER_SET) subscriber();
2630
+ }
2631
+ }
2632
+ function calculateResponsive(tokens) {
2633
+ const config = ArrayUtil.zipToObject(BREAK_POINTS, BREAK_POINTS.map((t) => tokens[StringUtil.toUpperCase(t)]));
2634
+ return ObjectUtil.entriesMap(DEFAULT_VALUES, (key) => [key, window.innerWidth >= config[key]]);
2635
+ }
2636
+ //#endregion
2637
+ //#region src/react/useUnmount.ts
2638
+ /**
2639
+ * 在组件卸载时执行的 Hook
2640
+ *
2641
+ * @param effect 副作用函数
2642
+ */
2643
+ function useUnmount(effect) {
2644
+ const effectRef = useLatest(effect);
2645
+ useEffect(() => () => {
2646
+ if (!TypeUtil.isFunction(effectRef.current)) {
2647
+ console.error(`hook [useUnmount] Expected parameter to be a function, but got ${typeof effectRef.current}. This effect will not execute.`);
2648
+ return;
2649
+ }
2650
+ effectRef.current?.();
2651
+ }, [effectRef]);
2652
+ }
2653
+ //#endregion
2654
+ //#region src/react/useTitle.ts
2655
+ /**
2656
+ * 设置页面标题
2657
+ * - 轻量级,适用于无路由库时设置页面标题
2658
+ * - 多个 `useTitle` 实例会互相干扰,需在顶层组件使用
2659
+ * - 无法处理 `document.title` 固有的竞态问题
2660
+ *
2661
+ * @param title 页面标题
2662
+ * @param options 配置选项
2663
+ */
2664
+ function useTitle(title, options) {
2665
+ const titleRef = useRef(EnvUtil.isBrowser() ? document.title : "");
2666
+ useEffect(() => {
2667
+ if (!TypeUtil.isString(title)) {
2668
+ console.error(`hook [useTitle] Expected parameter to be a string, but got ${typeof title}. This effect will not execute.`);
2669
+ return;
2670
+ }
2671
+ if (EnvUtil.isBrowser()) document.title = title;
2672
+ }, [title]);
2673
+ useUnmount(() => {
2674
+ if (EnvUtil.isBrowser() && options?.isRestoreOnUnmount) document.title = titleRef.current;
2675
+ });
2676
+ }
2677
+ //#endregion
2678
+ export { BREAK_POINT_TOKEN, useLatest, useMount, useResponsive, useTitle, useUnmount };