@base-web-kits/base-tools-ts 1.3.5 → 1.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -70,6 +70,7 @@ __export(index_exports, {
70
70
  BigNumber: () => import_bignumber.default,
71
71
  EventBus: () => EventBus,
72
72
  Mutex: () => Mutex,
73
+ SSEParser: () => SSEParser,
73
74
  Semaphore: () => Semaphore,
74
75
  TimeoutError: () => TimeoutError,
75
76
  after: () => after,
@@ -390,282 +391,126 @@ var EventBus = class {
390
391
  };
391
392
  var EventBus_default = new EventBus();
392
393
 
393
- // src/ts/day/index.ts
394
- var import_dayjs = __toESM(require("dayjs"), 1);
395
- var import_customParseFormat = __toESM(require("dayjs/plugin/customParseFormat.js"), 1);
396
- var import_utc = __toESM(require("dayjs/plugin/utc.js"), 1);
397
- var import_timezone = __toESM(require("dayjs/plugin/timezone.js"), 1);
398
- var import_relativeTime = __toESM(require("dayjs/plugin/relativeTime.js"), 1);
399
- var import_advancedFormat = __toESM(require("dayjs/plugin/advancedFormat.js"), 1);
400
- var import_zh_cn = require("dayjs/locale/zh-cn.js");
401
-
402
- // src/ts/number/big.ts
403
- var import_bignumber = __toESM(require("bignumber.js"), 1);
404
- function big(x) {
405
- return x instanceof import_bignumber.default ? x : new import_bignumber.default(x);
406
- }
407
- function mathPlus(...rest2) {
408
- let acc = big(rest2[0]);
409
- for (const x of rest2.slice(1)) acc = acc.plus(big(x));
410
- return acc.toNumber();
411
- }
412
- function mathMinus(...rest2) {
413
- let acc = big(rest2[0]);
414
- for (const x of rest2.slice(1)) acc = acc.minus(big(x));
415
- return acc.toNumber();
416
- }
417
- function mathTimes(...rest2) {
418
- let acc = big(rest2[0]);
419
- for (const x of rest2.slice(1)) acc = acc.times(big(x));
420
- return acc.toNumber();
421
- }
422
- function mathDiv(...rest2) {
423
- let acc = big(rest2[0]);
424
- for (const x of rest2.slice(1)) acc = acc.div(big(x));
425
- return acc.toNumber();
426
- }
427
- function mathPow(x, y) {
428
- return big(x).pow(big(y)).toNumber();
429
- }
430
- function mathRound(x, dp = 0, rm = import_bignumber.default.ROUND_HALF_UP) {
431
- return big(x).decimalPlaces(dp, rm).toNumber();
432
- }
433
- function mathFixed(x, dp = 2, rm = import_bignumber.default.ROUND_HALF_UP) {
434
- return big(x).toFixed(dp, rm);
435
- }
436
- function mathCompare(a, b) {
437
- return big(a).comparedTo(big(b));
438
- }
439
- function mathEqual(a, b) {
440
- return big(a).isEqualTo(big(b));
441
- }
442
- function mathGreaterThan(a, b) {
443
- return big(a).isGreaterThan(big(b));
444
- }
445
- function mathGreaterThanOrEqual(a, b) {
446
- return big(a).isGreaterThanOrEqualTo(big(b));
447
- }
448
- function mathLessThan(a, b) {
449
- return big(a).isLessThan(big(b));
450
- }
451
- function mathLessThanOrEqual(a, b) {
452
- return big(a).isLessThanOrEqualTo(big(b));
453
- }
454
-
455
- // src/ts/number/format.ts
456
- function zeroPad(n, len = 2) {
457
- return String(n).padStart(len, "0");
458
- }
459
- function withUnit(num, unit = "") {
460
- if (num === null || num === void 0 || num === "") return "";
461
- if (typeof num === "number") return `${num}${unit}`;
462
- const str = String(num).trim();
463
- if (str === "") return "";
464
- return isNaN(+str) ? str : `${str}${unit}`;
465
- }
466
- function withUnitPx(num) {
467
- return withUnit(num, "px");
468
- }
469
- function withDistance(m) {
470
- const n = Number(m != null ? m : 0);
471
- if (!Number.isFinite(n)) return "0m";
472
- return n >= 1e3 ? `${+(n / 1e3).toFixed(2)}km` : `${+n.toFixed(2)}m`;
473
- }
474
- function toThousandth(str) {
475
- const v = String(str != null ? str : "").trim();
476
- if (v === "") return "";
477
- let sign = "";
478
- let num = v;
479
- if (num[0] === "-" || num[0] === "+") {
480
- sign = num[0];
481
- num = num.slice(1);
482
- }
483
- const [intPart, decPart] = num.split(".");
484
- const groupedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
485
- return decPart !== void 0 && decPart !== "" ? `${sign}${groupedInt}.${decPart}` : `${sign}${groupedInt}`;
486
- }
487
- function toChineseNum(num) {
488
- const numInt = Math.trunc(+num);
489
- if (numInt === 0) return "\u96F6";
490
- const digit = ["\u96F6", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
491
- const unit = ["", "\u5341", "\u767E", "\u5343"];
492
- const bigUnit = ["", "\u4E07", "\u4EBF", "\u5146"];
493
- const section4 = (n2) => {
494
- let str = "", zeroFlag = false;
495
- for (let i = 0; i < 4; i++) {
496
- const d = n2 % 10;
497
- n2 = Math.floor(n2 / 10);
498
- if (d === 0) {
499
- zeroFlag = true;
500
- continue;
501
- }
502
- if (zeroFlag) str = digit[0] + str;
503
- str = digit[d] + unit[i] + str;
504
- zeroFlag = false;
505
- }
506
- return str;
507
- };
508
- let res = "";
509
- let sectionIndex = 0;
510
- let n = Math.abs(numInt);
511
- while (n > 0) {
512
- const seg = n % 1e4;
513
- n = Math.floor(n / 1e4);
514
- if (seg) {
515
- const segStr = section4(seg);
516
- res = segStr + (sectionIndex ? bigUnit[sectionIndex] : "") + res;
517
- } else if (res && !res.startsWith("\u96F6")) {
518
- res = `\u96F6${res}`;
519
- }
520
- sectionIndex++;
521
- }
522
- res = res.replace(/^一十/, "\u5341");
523
- return numInt < 0 ? `\u8D1F${res}` : res;
524
- }
525
- function toChineseCurrency(amount, opts = {}) {
526
- var _a, _b, _c;
527
- const dp = (_a = opts.precision) != null ? _a : 2;
528
- const rm = (_b = opts.rm) != null ? _b : import_bignumber.default.ROUND_HALF_UP;
529
- const yuan = (_c = opts.yuanChar) != null ? _c : "\u5143";
530
- if (amount === null || amount === void 0) return "";
531
- const bn = new import_bignumber.default(amount);
532
- if (!bn.isFinite()) return "";
533
- const s = bn.toFixed(dp, rm);
534
- const sign = s.startsWith("-") ? "\u8D1F" : "";
535
- const [intStr, decStr = ""] = s.replace(/^-/, "").split(".");
536
- const digit = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
537
- const unit = ["", "\u62FE", "\u4F70", "\u4EDF"];
538
- const bigUnit = ["", "\u4E07", "\u4EBF", "\u5146"];
539
- const smallUnit = ["\u89D2", "\u5206", "\u5398"];
540
- const section4 = (n) => {
541
- let str = "";
542
- let zeroFlag = false;
543
- for (let i = 0; i < 4; i++) {
544
- const d = n.mod(10).toNumber();
545
- n = n.idiv(10);
546
- if (d === 0) {
547
- zeroFlag = true;
548
- continue;
549
- }
550
- if (zeroFlag) str = digit[0] + str;
551
- str = digit[d] + unit[i] + str;
552
- zeroFlag = false;
553
- }
554
- return str.replace(/零+$/g, "");
555
- };
556
- const intNum = new import_bignumber.default(intStr);
557
- let res = "";
558
- if (intNum.isZero()) {
559
- res = digit[0];
560
- } else {
561
- let n = intNum.abs();
562
- let sectionIndex = 0;
563
- while (n.gt(0)) {
564
- const seg = n.mod(1e4);
565
- n = n.idiv(1e4);
566
- if (seg.gt(0)) {
567
- const segStr = section4(seg);
568
- const needZero = res && !res.startsWith(digit[0]) && (seg.lt(1e3) || seg.mod(1e3).isZero());
569
- const bu = sectionIndex ? bigUnit[sectionIndex] : "";
570
- res = segStr + bu + (needZero ? digit[0] : "") + res;
571
- } else if (res && !res.startsWith(digit[0])) {
572
- res = digit[0] + res;
573
- }
574
- sectionIndex++;
575
- }
576
- res = res.replace(/^壹拾/, "\u62FE");
577
- }
578
- let frac = "";
579
- for (let i = 0; i < Math.min(3, dp); i++) {
580
- const ch = decStr[i] || "0";
581
- const d = ch.charCodeAt(0) - 48;
582
- if (d > 0) frac += digit[d] + smallUnit[i];
583
- }
584
- return frac ? `${sign}${res}${yuan}${frac}` : `${sign}${res}${yuan}\u6574`;
585
- }
586
-
587
- // src/ts/number/random.ts
588
- function randomBoolean() {
589
- return Math.random() < 0.5;
590
- }
591
-
592
- // src/ts/day/index.ts
593
- import_dayjs.default.extend(import_customParseFormat.default);
594
- import_dayjs.default.extend(import_utc.default);
595
- import_dayjs.default.extend(import_timezone.default);
596
- import_dayjs.default.extend(import_relativeTime.default);
597
- import_dayjs.default.extend(import_advancedFormat.default);
598
- import_dayjs.default.locale("zh-cn");
599
- function toDayjs(t, fmt) {
600
- if (t === null || t === void 0) return (0, import_dayjs.default)();
601
- if (typeof t === "number") {
602
- const s = String(Math.trunc(t));
603
- return (0, import_dayjs.default)(s.length === 10 ? t * 1e3 : t, fmt);
604
- }
605
- if (typeof t === "string") {
606
- const s = t.trim();
607
- if (/^\d{10}$/.test(s)) return (0, import_dayjs.default)(Number(s) * 1e3, fmt);
608
- if (/^\d{13}$/.test(s)) return (0, import_dayjs.default)(Number(s), fmt);
609
- if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return (0, import_dayjs.default)(s, fmt || "YYYY-MM-DD");
610
- if (/^\d{4}\/\d{2}\/\d{2}$/.test(s)) return (0, import_dayjs.default)(s, fmt || "YYYY/MM/DD");
611
- if (/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/.test(s))
612
- return (0, import_dayjs.default)(s, fmt || "YYYY-MM-DD HH:mm:ss");
613
- if (/^\d{4}\/\d{2}\/\d{2}\s+\d{2}:\d{2}:\d{2}$/.test(s))
614
- return (0, import_dayjs.default)(s, fmt || "YYYY/MM/DD HH:mm:ss");
615
- return (0, import_dayjs.default)(s, fmt);
616
- }
617
- return (0, import_dayjs.default)(t, fmt);
618
- }
619
- function getDateRangeBefore(offset, fmt = "YYYY-MM-DD") {
620
- const now = toDayjs(Date.now());
621
- const n = Math.max(0, Math.trunc(offset));
622
- const hasTime = /H|h|m|s|S|A|a|x|X/.test(fmt);
623
- const startDay = now.add(-n, "day");
624
- const endDay = now;
625
- const start = (hasTime ? startDay.startOf("day") : startDay).format(fmt);
626
- const end = (hasTime ? endDay.endOf("day") : endDay).format(fmt);
627
- return [start, end];
628
- }
629
- function getDateRangeAfter(offset, fmt = "YYYY-MM-DD") {
630
- const now = toDayjs(Date.now());
631
- const n = Math.max(0, Math.trunc(offset));
632
- const hasTime = /H|h|m|s|S|A|a|x|X/.test(fmt);
633
- const startDay = now;
634
- const endDay = now.add(n, "day");
635
- const start = (hasTime ? startDay.startOf("day") : startDay).format(fmt);
636
- const end = (hasTime ? endDay.endOf("day") : endDay).format(fmt);
637
- return [start, end];
638
- }
639
- function getCountdownParts(diff) {
640
- if (diff <= 0) return { d: "00", h: "00", m: "00", s: "00", ms: "000" };
641
- const d = Math.floor(diff / (1e3 * 60 * 60 * 24));
642
- const h = Math.floor(diff / (1e3 * 60 * 60) % 24);
643
- const m = Math.floor(diff / (1e3 * 60) % 60);
644
- const s = Math.floor(diff / 1e3 % 60);
645
- const ms = diff % 1e3;
646
- return {
647
- d: zeroPad(d),
648
- h: zeroPad(h),
649
- m: zeroPad(m),
650
- s: zeroPad(s),
651
- ms: zeroPad(ms, 3)
652
- };
653
- }
654
- function getAgeByBirthdate(birthdate) {
655
- const birth = toDayjs(birthdate, "YYYY-MM-DD");
656
- const now = toDayjs(Date.now());
657
- const totalMonths = (now.year() - birth.year()) * 12 + (now.month() - birth.month());
658
- const adjustedMonths = now.date() < birth.date() ? totalMonths - 1 : totalMonths;
659
- if (adjustedMonths >= 12) {
660
- let age = Math.floor(adjustedMonths / 12);
661
- const birthdayThisYear = birth.add(age, "year");
662
- if (now.isBefore(birthdayThisYear)) {
663
- age--;
394
+ // src/ts/buffer/PolyfillTextDecoder.ts
395
+ var PolyfillTextDecoder = class {
396
+ constructor() {
397
+ __publicField(this, "leftOver", new Uint8Array(0));
398
+ }
399
+ decode(input, options) {
400
+ var _a;
401
+ const stream = (_a = options == null ? void 0 : options.stream) != null ? _a : false;
402
+ let bytes;
403
+ if (!input) {
404
+ bytes = new Uint8Array(0);
405
+ } else if (input instanceof ArrayBuffer) {
406
+ bytes = new Uint8Array(input);
407
+ } else {
408
+ bytes = input;
664
409
  }
665
- return { age, type: "year" };
410
+ if (this.leftOver.length > 0) {
411
+ const merged = new Uint8Array(this.leftOver.length + bytes.length);
412
+ merged.set(this.leftOver);
413
+ merged.set(bytes, this.leftOver.length);
414
+ bytes = merged;
415
+ this.leftOver = new Uint8Array(0);
416
+ }
417
+ const len = bytes.length;
418
+ if (len === 0) return "";
419
+ const parts = [];
420
+ let i = 0;
421
+ const replacement = "\uFFFD";
422
+ const isContinuationByte = (b) => (b & 192) === 128;
423
+ while (i < len) {
424
+ const byte1 = bytes[i];
425
+ if (byte1 < 128) {
426
+ parts.push(String.fromCharCode(byte1));
427
+ i += 1;
428
+ } else if (byte1 >= 194 && byte1 < 224) {
429
+ if (i + 1 >= len) {
430
+ if (stream) {
431
+ this.leftOver = bytes.slice(i);
432
+ break;
433
+ }
434
+ parts.push(replacement);
435
+ break;
436
+ }
437
+ const byte2 = bytes[i + 1];
438
+ if (!isContinuationByte(byte2)) {
439
+ parts.push(replacement);
440
+ i += 1;
441
+ continue;
442
+ }
443
+ parts.push(String.fromCharCode((byte1 & 31) << 6 | byte2 & 63));
444
+ i += 2;
445
+ } else if (byte1 >= 224 && byte1 < 240) {
446
+ if (i + 2 >= len) {
447
+ if (stream) {
448
+ this.leftOver = bytes.slice(i);
449
+ break;
450
+ }
451
+ parts.push(replacement);
452
+ break;
453
+ }
454
+ const byte2 = bytes[i + 1];
455
+ const byte3 = bytes[i + 2];
456
+ if (!isContinuationByte(byte2) || !isContinuationByte(byte3)) {
457
+ parts.push(replacement);
458
+ i += 1;
459
+ continue;
460
+ }
461
+ if (byte1 === 224 && byte2 < 160) {
462
+ parts.push(replacement);
463
+ i += 3;
464
+ continue;
465
+ }
466
+ if (byte1 === 237 && byte2 >= 160) {
467
+ parts.push(replacement);
468
+ i += 3;
469
+ continue;
470
+ }
471
+ const codeUnit = (byte1 & 15) << 12 | (byte2 & 63) << 6 | byte3 & 63;
472
+ parts.push(String.fromCharCode(codeUnit));
473
+ i += 3;
474
+ } else if (byte1 >= 240 && byte1 <= 244) {
475
+ if (i + 3 >= len) {
476
+ if (stream) {
477
+ this.leftOver = bytes.slice(i);
478
+ break;
479
+ }
480
+ parts.push(replacement);
481
+ break;
482
+ }
483
+ const byte2 = bytes[i + 1];
484
+ const byte3 = bytes[i + 2];
485
+ const byte4 = bytes[i + 3];
486
+ if (!isContinuationByte(byte2) || !isContinuationByte(byte3) || !isContinuationByte(byte4)) {
487
+ parts.push(replacement);
488
+ i += 1;
489
+ continue;
490
+ }
491
+ if (byte1 === 240 && byte2 < 144) {
492
+ parts.push(replacement);
493
+ i += 4;
494
+ continue;
495
+ }
496
+ if (byte1 === 244 && byte2 >= 144) {
497
+ parts.push(replacement);
498
+ i += 4;
499
+ continue;
500
+ }
501
+ const codepoint = (byte1 & 7) << 18 | (byte2 & 63) << 12 | (byte3 & 63) << 6 | byte4 & 63;
502
+ const offset = codepoint - 65536;
503
+ parts.push(String.fromCharCode(55296 + (offset >> 10), 56320 + (offset & 1023)));
504
+ i += 4;
505
+ } else {
506
+ parts.push(replacement);
507
+ i += 1;
508
+ }
509
+ }
510
+ return parts.join("");
666
511
  }
667
- return { age: adjustedMonths, type: "month" };
668
- }
512
+ };
513
+ var PolyfillTextDecoder_default = PolyfillTextDecoder;
669
514
 
670
515
  // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/array/at.mjs
671
516
  function at(arr, indices) {
@@ -3032,116 +2877,528 @@ function trimEnd(str, chars) {
3032
2877
  if (chars === void 0) {
3033
2878
  return str.trimEnd();
3034
2879
  }
3035
- let endIndex = str.length;
3036
- switch (typeof chars) {
3037
- case "string": {
3038
- if (chars.length !== 1) {
3039
- throw new Error(`The 'chars' parameter should be a single character string.`);
3040
- }
3041
- while (endIndex > 0 && str[endIndex - 1] === chars) {
3042
- endIndex--;
2880
+ let endIndex = str.length;
2881
+ switch (typeof chars) {
2882
+ case "string": {
2883
+ if (chars.length !== 1) {
2884
+ throw new Error(`The 'chars' parameter should be a single character string.`);
2885
+ }
2886
+ while (endIndex > 0 && str[endIndex - 1] === chars) {
2887
+ endIndex--;
2888
+ }
2889
+ break;
2890
+ }
2891
+ case "object": {
2892
+ while (endIndex > 0 && chars.includes(str[endIndex - 1])) {
2893
+ endIndex--;
2894
+ }
2895
+ }
2896
+ }
2897
+ return str.substring(0, endIndex);
2898
+ }
2899
+
2900
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/trimStart.mjs
2901
+ function trimStart(str, chars) {
2902
+ if (chars === void 0) {
2903
+ return str.trimStart();
2904
+ }
2905
+ let startIndex = 0;
2906
+ switch (typeof chars) {
2907
+ case "string": {
2908
+ while (startIndex < str.length && str[startIndex] === chars) {
2909
+ startIndex++;
2910
+ }
2911
+ break;
2912
+ }
2913
+ case "object": {
2914
+ while (startIndex < str.length && chars.includes(str[startIndex])) {
2915
+ startIndex++;
2916
+ }
2917
+ }
2918
+ }
2919
+ return str.substring(startIndex);
2920
+ }
2921
+
2922
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/trim.mjs
2923
+ function trim(str, chars) {
2924
+ if (chars === void 0) {
2925
+ return str.trim();
2926
+ }
2927
+ return trimStart(trimEnd(str, chars), chars);
2928
+ }
2929
+
2930
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/unescape.mjs
2931
+ var htmlUnescapes = {
2932
+ "&amp;": "&",
2933
+ "&lt;": "<",
2934
+ "&gt;": ">",
2935
+ "&quot;": '"',
2936
+ "&#39;": "'"
2937
+ };
2938
+ function unescape2(str) {
2939
+ return str.replace(/&(?:amp|lt|gt|quot|#(0+)?39);/g, (match) => htmlUnescapes[match] || "'");
2940
+ }
2941
+
2942
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/upperCase.mjs
2943
+ function upperCase(str) {
2944
+ const words$1 = words(str);
2945
+ let result = "";
2946
+ for (let i = 0; i < words$1.length; i++) {
2947
+ result += words$1[i].toUpperCase();
2948
+ if (i < words$1.length - 1) {
2949
+ result += " ";
2950
+ }
2951
+ }
2952
+ return result;
2953
+ }
2954
+
2955
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/upperFirst.mjs
2956
+ function upperFirst(str) {
2957
+ return str.substring(0, 1).toUpperCase() + str.substring(1);
2958
+ }
2959
+
2960
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/attempt.mjs
2961
+ function attempt(func) {
2962
+ try {
2963
+ return [null, func()];
2964
+ } catch (error) {
2965
+ return [error, null];
2966
+ }
2967
+ }
2968
+
2969
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/attemptAsync.mjs
2970
+ function attemptAsync(func) {
2971
+ return __async(this, null, function* () {
2972
+ try {
2973
+ const result = yield func();
2974
+ return [null, result];
2975
+ } catch (error) {
2976
+ return [error, null];
2977
+ }
2978
+ });
2979
+ }
2980
+
2981
+ // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/invariant.mjs
2982
+ function invariant(condition, message) {
2983
+ if (condition) {
2984
+ return;
2985
+ }
2986
+ if (typeof message === "string") {
2987
+ throw new Error(message);
2988
+ }
2989
+ throw message;
2990
+ }
2991
+
2992
+ // src/ts/buffer/SSEParser.ts
2993
+ var SSEParser = class {
2994
+ constructor(onMessage) {
2995
+ __publicField(this, "buffer", "");
2996
+ __publicField(this, "onMessage");
2997
+ __publicField(this, "decoder");
2998
+ __publicField(this, "eventDataLines", []);
2999
+ __publicField(this, "eventType");
3000
+ __publicField(this, "eventId");
3001
+ __publicField(this, "eventRetry");
3002
+ this.onMessage = onMessage;
3003
+ this.decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8") : new PolyfillTextDecoder_default();
3004
+ }
3005
+ /**
3006
+ * 接收流式数据
3007
+ * @param buffer ArrayBuffer
3008
+ */
3009
+ receive(buffer) {
3010
+ const text = this.decoder.decode(new Uint8Array(buffer), { stream: true });
3011
+ this.appendText(text);
3012
+ }
3013
+ /**
3014
+ * 刷新解码器残留数据并处理尾部未换行的内容
3015
+ */
3016
+ flush() {
3017
+ const tail2 = this.decoder.decode(void 0, { stream: false });
3018
+ if (tail2) this.appendText(tail2);
3019
+ this.flushRemainder();
3020
+ }
3021
+ /**
3022
+ * 追加文本并按行拆分处理,保留不完整尾行
3023
+ * @param text 新到达的文本片段
3024
+ */
3025
+ appendText(text) {
3026
+ this.buffer += text;
3027
+ const lines = this.buffer.split(/\r?\n/);
3028
+ this.buffer = lines.pop() || "";
3029
+ this.processLines(lines);
3030
+ }
3031
+ /**
3032
+ * 处理缓冲区中剩余的尾行内容
3033
+ */
3034
+ flushRemainder() {
3035
+ if (!this.buffer.trim()) {
3036
+ this.buffer = "";
3037
+ return;
3038
+ }
3039
+ const rest2 = this.buffer;
3040
+ this.buffer = "";
3041
+ this.processLines([rest2, ""]);
3042
+ }
3043
+ /**
3044
+ * 解析每行 SSE 数据并触发回调
3045
+ * @param lines 以换行切分后的行内容
3046
+ */
3047
+ processLines(lines) {
3048
+ for (const line of lines) {
3049
+ if (!line.trim()) {
3050
+ this.dispatchEvent();
3051
+ continue;
3052
+ }
3053
+ if (line.startsWith(":")) continue;
3054
+ const colonIndex = line.indexOf(":");
3055
+ const field = colonIndex === -1 ? line : line.slice(0, colonIndex);
3056
+ let value = colonIndex === -1 ? "" : line.slice(colonIndex + 1);
3057
+ if (value.startsWith(" ")) value = value.slice(1);
3058
+ if (field === "data") {
3059
+ this.eventDataLines.push(value);
3060
+ continue;
3061
+ }
3062
+ if (field === "event") {
3063
+ this.eventType = value || void 0;
3064
+ continue;
3065
+ }
3066
+ if (field === "id") {
3067
+ this.eventId = value || void 0;
3068
+ continue;
3069
+ }
3070
+ if (field === "retry") {
3071
+ const retry2 = Number(value);
3072
+ this.eventRetry = Number.isFinite(retry2) ? retry2 : void 0;
3073
+ continue;
3074
+ }
3075
+ }
3076
+ }
3077
+ /**
3078
+ * 将当前缓存的一次 SSE 事件分发给回调
3079
+ * @description 以空行作为事件边界,将多行 data 合并后再解析;处理 "[DONE]" 结束标记;分发完成后会重置事件缓存
3080
+ */
3081
+ dispatchEvent() {
3082
+ if (!this.eventDataLines.length) {
3083
+ this.resetEvent();
3084
+ return;
3085
+ }
3086
+ const data = this.eventDataLines.join("\n");
3087
+ if (!data) {
3088
+ this.resetEvent();
3089
+ return;
3090
+ }
3091
+ if (data.trim() === "[DONE]") {
3092
+ this.safeOnMessage({ type: "DONE" });
3093
+ this.resetEvent();
3094
+ return;
3095
+ }
3096
+ let msg;
3097
+ try {
3098
+ const json = JSON.parse(data);
3099
+ msg = isPlainObject(json) ? json : { data: json };
3100
+ } catch (e) {
3101
+ msg = { raw: data };
3102
+ }
3103
+ if (this.eventType && msg.event === void 0) msg.event = this.eventType;
3104
+ if (this.eventType && msg.type === void 0) msg.type = this.eventType;
3105
+ if (this.eventId && msg.id === void 0) msg.id = this.eventId;
3106
+ if (this.eventRetry !== void 0 && msg.retry === void 0) msg.retry = this.eventRetry;
3107
+ this.safeOnMessage(msg);
3108
+ this.resetEvent();
3109
+ }
3110
+ /** 安全调用 onMessage 回调,捕获并打印错误 */
3111
+ safeOnMessage(msg) {
3112
+ try {
3113
+ this.onMessage(msg);
3114
+ } catch (onMessageError) {
3115
+ console.error("SSEParser onMessage error:", onMessageError);
3116
+ }
3117
+ }
3118
+ /** 重置当前 SSE 事件的临时缓存 */
3119
+ resetEvent() {
3120
+ this.eventDataLines = [];
3121
+ this.eventType = void 0;
3122
+ this.eventId = void 0;
3123
+ this.eventRetry = void 0;
3124
+ }
3125
+ };
3126
+
3127
+ // src/ts/day/index.ts
3128
+ var import_dayjs = __toESM(require("dayjs"), 1);
3129
+ var import_customParseFormat = __toESM(require("dayjs/plugin/customParseFormat.js"), 1);
3130
+ var import_utc = __toESM(require("dayjs/plugin/utc.js"), 1);
3131
+ var import_timezone = __toESM(require("dayjs/plugin/timezone.js"), 1);
3132
+ var import_relativeTime = __toESM(require("dayjs/plugin/relativeTime.js"), 1);
3133
+ var import_advancedFormat = __toESM(require("dayjs/plugin/advancedFormat.js"), 1);
3134
+ var import_zh_cn = require("dayjs/locale/zh-cn.js");
3135
+
3136
+ // src/ts/number/big.ts
3137
+ var import_bignumber = __toESM(require("bignumber.js"), 1);
3138
+ function big(x) {
3139
+ return x instanceof import_bignumber.default ? x : new import_bignumber.default(x);
3140
+ }
3141
+ function mathPlus(...rest2) {
3142
+ let acc = big(rest2[0]);
3143
+ for (const x of rest2.slice(1)) acc = acc.plus(big(x));
3144
+ return acc.toNumber();
3145
+ }
3146
+ function mathMinus(...rest2) {
3147
+ let acc = big(rest2[0]);
3148
+ for (const x of rest2.slice(1)) acc = acc.minus(big(x));
3149
+ return acc.toNumber();
3150
+ }
3151
+ function mathTimes(...rest2) {
3152
+ let acc = big(rest2[0]);
3153
+ for (const x of rest2.slice(1)) acc = acc.times(big(x));
3154
+ return acc.toNumber();
3155
+ }
3156
+ function mathDiv(...rest2) {
3157
+ let acc = big(rest2[0]);
3158
+ for (const x of rest2.slice(1)) acc = acc.div(big(x));
3159
+ return acc.toNumber();
3160
+ }
3161
+ function mathPow(x, y) {
3162
+ return big(x).pow(big(y)).toNumber();
3163
+ }
3164
+ function mathRound(x, dp = 0, rm = import_bignumber.default.ROUND_HALF_UP) {
3165
+ return big(x).decimalPlaces(dp, rm).toNumber();
3166
+ }
3167
+ function mathFixed(x, dp = 2, rm = import_bignumber.default.ROUND_HALF_UP) {
3168
+ return big(x).toFixed(dp, rm);
3169
+ }
3170
+ function mathCompare(a, b) {
3171
+ return big(a).comparedTo(big(b));
3172
+ }
3173
+ function mathEqual(a, b) {
3174
+ return big(a).isEqualTo(big(b));
3175
+ }
3176
+ function mathGreaterThan(a, b) {
3177
+ return big(a).isGreaterThan(big(b));
3178
+ }
3179
+ function mathGreaterThanOrEqual(a, b) {
3180
+ return big(a).isGreaterThanOrEqualTo(big(b));
3181
+ }
3182
+ function mathLessThan(a, b) {
3183
+ return big(a).isLessThan(big(b));
3184
+ }
3185
+ function mathLessThanOrEqual(a, b) {
3186
+ return big(a).isLessThanOrEqualTo(big(b));
3187
+ }
3188
+
3189
+ // src/ts/number/format.ts
3190
+ function zeroPad(n, len = 2) {
3191
+ return String(n).padStart(len, "0");
3192
+ }
3193
+ function withUnit(num, unit = "") {
3194
+ if (num === null || num === void 0 || num === "") return "";
3195
+ if (typeof num === "number") return `${num}${unit}`;
3196
+ const str = String(num).trim();
3197
+ if (str === "") return "";
3198
+ return isNaN(+str) ? str : `${str}${unit}`;
3199
+ }
3200
+ function withUnitPx(num) {
3201
+ return withUnit(num, "px");
3202
+ }
3203
+ function withDistance(m) {
3204
+ const n = Number(m != null ? m : 0);
3205
+ if (!Number.isFinite(n)) return "0m";
3206
+ return n >= 1e3 ? `${+(n / 1e3).toFixed(2)}km` : `${+n.toFixed(2)}m`;
3207
+ }
3208
+ function toThousandth(str) {
3209
+ const v = String(str != null ? str : "").trim();
3210
+ if (v === "") return "";
3211
+ let sign = "";
3212
+ let num = v;
3213
+ if (num[0] === "-" || num[0] === "+") {
3214
+ sign = num[0];
3215
+ num = num.slice(1);
3216
+ }
3217
+ const [intPart, decPart] = num.split(".");
3218
+ const groupedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
3219
+ return decPart !== void 0 && decPart !== "" ? `${sign}${groupedInt}.${decPart}` : `${sign}${groupedInt}`;
3220
+ }
3221
+ function toChineseNum(num) {
3222
+ const numInt = Math.trunc(+num);
3223
+ if (numInt === 0) return "\u96F6";
3224
+ const digit = ["\u96F6", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
3225
+ const unit = ["", "\u5341", "\u767E", "\u5343"];
3226
+ const bigUnit = ["", "\u4E07", "\u4EBF", "\u5146"];
3227
+ const section4 = (n2) => {
3228
+ let str = "", zeroFlag = false;
3229
+ for (let i = 0; i < 4; i++) {
3230
+ const d = n2 % 10;
3231
+ n2 = Math.floor(n2 / 10);
3232
+ if (d === 0) {
3233
+ zeroFlag = true;
3234
+ continue;
3043
3235
  }
3044
- break;
3236
+ if (zeroFlag) str = digit[0] + str;
3237
+ str = digit[d] + unit[i] + str;
3238
+ zeroFlag = false;
3045
3239
  }
3046
- case "object": {
3047
- while (endIndex > 0 && chars.includes(str[endIndex - 1])) {
3048
- endIndex--;
3049
- }
3240
+ return str;
3241
+ };
3242
+ let res = "";
3243
+ let sectionIndex = 0;
3244
+ let n = Math.abs(numInt);
3245
+ while (n > 0) {
3246
+ const seg = n % 1e4;
3247
+ n = Math.floor(n / 1e4);
3248
+ if (seg) {
3249
+ const segStr = section4(seg);
3250
+ res = segStr + (sectionIndex ? bigUnit[sectionIndex] : "") + res;
3251
+ } else if (res && !res.startsWith("\u96F6")) {
3252
+ res = `\u96F6${res}`;
3050
3253
  }
3254
+ sectionIndex++;
3051
3255
  }
3052
- return str.substring(0, endIndex);
3256
+ res = res.replace(/^一十/, "\u5341");
3257
+ return numInt < 0 ? `\u8D1F${res}` : res;
3053
3258
  }
3054
-
3055
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/trimStart.mjs
3056
- function trimStart(str, chars) {
3057
- if (chars === void 0) {
3058
- return str.trimStart();
3059
- }
3060
- let startIndex = 0;
3061
- switch (typeof chars) {
3062
- case "string": {
3063
- while (startIndex < str.length && str[startIndex] === chars) {
3064
- startIndex++;
3259
+ function toChineseCurrency(amount, opts = {}) {
3260
+ var _a, _b, _c;
3261
+ const dp = (_a = opts.precision) != null ? _a : 2;
3262
+ const rm = (_b = opts.rm) != null ? _b : import_bignumber.default.ROUND_HALF_UP;
3263
+ const yuan = (_c = opts.yuanChar) != null ? _c : "\u5143";
3264
+ if (amount === null || amount === void 0) return "";
3265
+ const bn = new import_bignumber.default(amount);
3266
+ if (!bn.isFinite()) return "";
3267
+ const s = bn.toFixed(dp, rm);
3268
+ const sign = s.startsWith("-") ? "\u8D1F" : "";
3269
+ const [intStr, decStr = ""] = s.replace(/^-/, "").split(".");
3270
+ const digit = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
3271
+ const unit = ["", "\u62FE", "\u4F70", "\u4EDF"];
3272
+ const bigUnit = ["", "\u4E07", "\u4EBF", "\u5146"];
3273
+ const smallUnit = ["\u89D2", "\u5206", "\u5398"];
3274
+ const section4 = (n) => {
3275
+ let str = "";
3276
+ let zeroFlag = false;
3277
+ for (let i = 0; i < 4; i++) {
3278
+ const d = n.mod(10).toNumber();
3279
+ n = n.idiv(10);
3280
+ if (d === 0) {
3281
+ zeroFlag = true;
3282
+ continue;
3065
3283
  }
3066
- break;
3284
+ if (zeroFlag) str = digit[0] + str;
3285
+ str = digit[d] + unit[i] + str;
3286
+ zeroFlag = false;
3067
3287
  }
3068
- case "object": {
3069
- while (startIndex < str.length && chars.includes(str[startIndex])) {
3070
- startIndex++;
3288
+ return str.replace(/零+$/g, "");
3289
+ };
3290
+ const intNum = new import_bignumber.default(intStr);
3291
+ let res = "";
3292
+ if (intNum.isZero()) {
3293
+ res = digit[0];
3294
+ } else {
3295
+ let n = intNum.abs();
3296
+ let sectionIndex = 0;
3297
+ while (n.gt(0)) {
3298
+ const seg = n.mod(1e4);
3299
+ n = n.idiv(1e4);
3300
+ if (seg.gt(0)) {
3301
+ const segStr = section4(seg);
3302
+ const needZero = res && !res.startsWith(digit[0]) && (seg.lt(1e3) || seg.mod(1e3).isZero());
3303
+ const bu = sectionIndex ? bigUnit[sectionIndex] : "";
3304
+ res = segStr + bu + (needZero ? digit[0] : "") + res;
3305
+ } else if (res && !res.startsWith(digit[0])) {
3306
+ res = digit[0] + res;
3071
3307
  }
3308
+ sectionIndex++;
3072
3309
  }
3310
+ res = res.replace(/^壹拾/, "\u62FE");
3073
3311
  }
3074
- return str.substring(startIndex);
3075
- }
3076
-
3077
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/trim.mjs
3078
- function trim(str, chars) {
3079
- if (chars === void 0) {
3080
- return str.trim();
3312
+ let frac = "";
3313
+ for (let i = 0; i < Math.min(3, dp); i++) {
3314
+ const ch = decStr[i] || "0";
3315
+ const d = ch.charCodeAt(0) - 48;
3316
+ if (d > 0) frac += digit[d] + smallUnit[i];
3081
3317
  }
3082
- return trimStart(trimEnd(str, chars), chars);
3318
+ return frac ? `${sign}${res}${yuan}${frac}` : `${sign}${res}${yuan}\u6574`;
3083
3319
  }
3084
3320
 
3085
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/unescape.mjs
3086
- var htmlUnescapes = {
3087
- "&amp;": "&",
3088
- "&lt;": "<",
3089
- "&gt;": ">",
3090
- "&quot;": '"',
3091
- "&#39;": "'"
3092
- };
3093
- function unescape2(str) {
3094
- return str.replace(/&(?:amp|lt|gt|quot|#(0+)?39);/g, (match) => htmlUnescapes[match] || "'");
3321
+ // src/ts/number/random.ts
3322
+ function randomBoolean() {
3323
+ return Math.random() < 0.5;
3095
3324
  }
3096
3325
 
3097
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/upperCase.mjs
3098
- function upperCase(str) {
3099
- const words$1 = words(str);
3100
- let result = "";
3101
- for (let i = 0; i < words$1.length; i++) {
3102
- result += words$1[i].toUpperCase();
3103
- if (i < words$1.length - 1) {
3104
- result += " ";
3105
- }
3326
+ // src/ts/day/index.ts
3327
+ import_dayjs.default.extend(import_customParseFormat.default);
3328
+ import_dayjs.default.extend(import_utc.default);
3329
+ import_dayjs.default.extend(import_timezone.default);
3330
+ import_dayjs.default.extend(import_relativeTime.default);
3331
+ import_dayjs.default.extend(import_advancedFormat.default);
3332
+ import_dayjs.default.locale("zh-cn");
3333
+ function toDayjs(t, fmt) {
3334
+ if (t === null || t === void 0) return (0, import_dayjs.default)();
3335
+ if (typeof t === "number") {
3336
+ const s = String(Math.trunc(t));
3337
+ return (0, import_dayjs.default)(s.length === 10 ? t * 1e3 : t, fmt);
3106
3338
  }
3107
- return result;
3339
+ if (typeof t === "string") {
3340
+ const s = t.trim();
3341
+ if (/^\d{10}$/.test(s)) return (0, import_dayjs.default)(Number(s) * 1e3, fmt);
3342
+ if (/^\d{13}$/.test(s)) return (0, import_dayjs.default)(Number(s), fmt);
3343
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return (0, import_dayjs.default)(s, fmt || "YYYY-MM-DD");
3344
+ if (/^\d{4}\/\d{2}\/\d{2}$/.test(s)) return (0, import_dayjs.default)(s, fmt || "YYYY/MM/DD");
3345
+ if (/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/.test(s))
3346
+ return (0, import_dayjs.default)(s, fmt || "YYYY-MM-DD HH:mm:ss");
3347
+ if (/^\d{4}\/\d{2}\/\d{2}\s+\d{2}:\d{2}:\d{2}$/.test(s))
3348
+ return (0, import_dayjs.default)(s, fmt || "YYYY/MM/DD HH:mm:ss");
3349
+ return (0, import_dayjs.default)(s, fmt);
3350
+ }
3351
+ return (0, import_dayjs.default)(t, fmt);
3108
3352
  }
3109
-
3110
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/string/upperFirst.mjs
3111
- function upperFirst(str) {
3112
- return str.substring(0, 1).toUpperCase() + str.substring(1);
3353
+ function getDateRangeBefore(offset, fmt = "YYYY-MM-DD") {
3354
+ const now = toDayjs(Date.now());
3355
+ const n = Math.max(0, Math.trunc(offset));
3356
+ const hasTime = /H|h|m|s|S|A|a|x|X/.test(fmt);
3357
+ const startDay = now.add(-n, "day");
3358
+ const endDay = now;
3359
+ const start = (hasTime ? startDay.startOf("day") : startDay).format(fmt);
3360
+ const end = (hasTime ? endDay.endOf("day") : endDay).format(fmt);
3361
+ return [start, end];
3113
3362
  }
3114
-
3115
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/attempt.mjs
3116
- function attempt(func) {
3117
- try {
3118
- return [null, func()];
3119
- } catch (error) {
3120
- return [error, null];
3121
- }
3363
+ function getDateRangeAfter(offset, fmt = "YYYY-MM-DD") {
3364
+ const now = toDayjs(Date.now());
3365
+ const n = Math.max(0, Math.trunc(offset));
3366
+ const hasTime = /H|h|m|s|S|A|a|x|X/.test(fmt);
3367
+ const startDay = now;
3368
+ const endDay = now.add(n, "day");
3369
+ const start = (hasTime ? startDay.startOf("day") : startDay).format(fmt);
3370
+ const end = (hasTime ? endDay.endOf("day") : endDay).format(fmt);
3371
+ return [start, end];
3122
3372
  }
3123
-
3124
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/attemptAsync.mjs
3125
- function attemptAsync(func) {
3126
- return __async(this, null, function* () {
3127
- try {
3128
- const result = yield func();
3129
- return [null, result];
3130
- } catch (error) {
3131
- return [error, null];
3132
- }
3133
- });
3373
+ function getCountdownParts(diff) {
3374
+ if (diff <= 0) return { d: "00", h: "00", m: "00", s: "00", ms: "000" };
3375
+ const d = Math.floor(diff / (1e3 * 60 * 60 * 24));
3376
+ const h = Math.floor(diff / (1e3 * 60 * 60) % 24);
3377
+ const m = Math.floor(diff / (1e3 * 60) % 60);
3378
+ const s = Math.floor(diff / 1e3 % 60);
3379
+ const ms = diff % 1e3;
3380
+ return {
3381
+ d: zeroPad(d),
3382
+ h: zeroPad(h),
3383
+ m: zeroPad(m),
3384
+ s: zeroPad(s),
3385
+ ms: zeroPad(ms, 3)
3386
+ };
3134
3387
  }
3135
-
3136
- // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/util/invariant.mjs
3137
- function invariant(condition, message) {
3138
- if (condition) {
3139
- return;
3140
- }
3141
- if (typeof message === "string") {
3142
- throw new Error(message);
3388
+ function getAgeByBirthdate(birthdate) {
3389
+ const birth = toDayjs(birthdate, "YYYY-MM-DD");
3390
+ const now = toDayjs(Date.now());
3391
+ const totalMonths = (now.year() - birth.year()) * 12 + (now.month() - birth.month());
3392
+ const adjustedMonths = now.date() < birth.date() ? totalMonths - 1 : totalMonths;
3393
+ if (adjustedMonths >= 12) {
3394
+ let age = Math.floor(adjustedMonths / 12);
3395
+ const birthdayThisYear = birth.add(age, "year");
3396
+ if (now.isBefore(birthdayThisYear)) {
3397
+ age--;
3398
+ }
3399
+ return { age, type: "year" };
3143
3400
  }
3144
- throw message;
3401
+ return { age: adjustedMonths, type: "month" };
3145
3402
  }
3146
3403
 
3147
3404
  // node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.mjs
@@ -3976,6 +4233,7 @@ function isLongitude(s) {
3976
4233
  BigNumber,
3977
4234
  EventBus,
3978
4235
  Mutex,
4236
+ SSEParser,
3979
4237
  Semaphore,
3980
4238
  TimeoutError,
3981
4239
  after,