@windrun-huaiin/third-ui 30.0.0 → 31.0.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 (122) hide show
  1. package/README.md +109 -143
  2. package/dist/ai/ai-prompt-textarea.js +5 -5
  3. package/dist/ai/ai-prompt-textarea.mjs +5 -5
  4. package/dist/clerk/clerk-auth-appearance.d.ts +13 -0
  5. package/dist/clerk/clerk-auth-appearance.js +19 -0
  6. package/dist/clerk/clerk-auth-appearance.mjs +15 -0
  7. package/dist/clerk/clerk-auth-modal-appearance.d.ts +12 -0
  8. package/dist/clerk/clerk-auth-modal-appearance.js +17 -0
  9. package/dist/clerk/clerk-auth-modal-appearance.mjs +14 -0
  10. package/dist/clerk/clerk-page-context-generator.js +3 -3
  11. package/dist/clerk/clerk-page-context-generator.mjs +3 -3
  12. package/dist/clerk/clerk-page-generator.js +4 -4
  13. package/dist/clerk/clerk-page-generator.mjs +4 -4
  14. package/dist/clerk/clerk-user-client.js +2 -1
  15. package/dist/clerk/clerk-user-client.mjs +2 -1
  16. package/dist/clerk/fingerprint/fingerprint-client.d.ts +10 -10
  17. package/dist/clerk/fingerprint/fingerprint-client.js +20 -20
  18. package/dist/clerk/fingerprint/fingerprint-client.mjs +20 -20
  19. package/dist/clerk/fingerprint/fingerprint-provider.d.ts +3 -3
  20. package/dist/clerk/fingerprint/fingerprint-provider.js +8 -8
  21. package/dist/clerk/fingerprint/fingerprint-provider.mjs +8 -8
  22. package/dist/clerk/fingerprint/fingerprint-server.d.ts +12 -12
  23. package/dist/clerk/fingerprint/fingerprint-server.js +17 -17
  24. package/dist/clerk/fingerprint/fingerprint-server.mjs +17 -17
  25. package/dist/clerk/fingerprint/fingerprint-shared.d.ts +3 -3
  26. package/dist/clerk/fingerprint/fingerprint-shared.js +10 -10
  27. package/dist/clerk/fingerprint/fingerprint-shared.mjs +10 -10
  28. package/dist/clerk/fingerprint/types.d.ts +0 -1
  29. package/dist/clerk/fingerprint/use-fingerprint.js +7 -7
  30. package/dist/clerk/fingerprint/use-fingerprint.mjs +7 -7
  31. package/dist/clerk/signin-with-fingerprint-client.d.ts +2 -2
  32. package/dist/clerk/signin-with-fingerprint-client.js +7 -6
  33. package/dist/clerk/signin-with-fingerprint-client.mjs +7 -6
  34. package/dist/clerk/signup-button-with-fingerprint-client.js +6 -4
  35. package/dist/clerk/signup-button-with-fingerprint-client.mjs +6 -4
  36. package/dist/clerk/signup-with-fingerprint-client.d.ts +2 -2
  37. package/dist/clerk/signup-with-fingerprint-client.js +7 -6
  38. package/dist/clerk/signup-with-fingerprint-client.mjs +7 -6
  39. package/dist/fuma/fuma-page-genarator.d.ts +2 -6
  40. package/dist/fuma/fuma-page-genarator.js +3 -2
  41. package/dist/fuma/fuma-page-genarator.mjs +3 -2
  42. package/dist/fuma/heavy/mermaid.js +1 -1
  43. package/dist/fuma/heavy/mermaid.mjs +1 -1
  44. package/dist/fuma/site-x.js +0 -1
  45. package/dist/fuma/site-x.mjs +0 -1
  46. package/dist/main/404-page.d.ts +12 -0
  47. package/dist/main/404-page.js +66 -0
  48. package/dist/main/404-page.mjs +64 -0
  49. package/dist/main/anime/anime-404-page.d.ts +14 -0
  50. package/dist/main/anime/anime-404-page.js +197 -0
  51. package/dist/main/anime/anime-404-page.mjs +195 -0
  52. package/dist/main/anime/anime-not-found-page.d.ts +7 -0
  53. package/dist/main/anime/anime-not-found-page.js +142 -0
  54. package/dist/main/anime/anime-not-found-page.mjs +140 -0
  55. package/dist/main/anime/index.d.ts +1 -0
  56. package/dist/main/anime/index.js +2 -0
  57. package/dist/main/anime/index.mjs +1 -0
  58. package/dist/main/calendar/calendar-date-range-input.js +1 -1
  59. package/dist/main/calendar/calendar-date-range-input.mjs +1 -1
  60. package/dist/main/credit/types.d.ts +8 -8
  61. package/dist/main/index.d.ts +1 -0
  62. package/dist/main/index.js +2 -0
  63. package/dist/main/index.mjs +1 -0
  64. package/dist/main/money-price/index.d.ts +1 -1
  65. package/dist/main/money-price/money-price-button.js +10 -10
  66. package/dist/main/money-price/money-price-button.mjs +10 -10
  67. package/dist/main/money-price/money-price-config-util.d.ts +30 -30
  68. package/dist/main/money-price/money-price-config-util.js +48 -48
  69. package/dist/main/money-price/money-price-config-util.mjs +48 -48
  70. package/dist/main/money-price/money-price-interactive.js +30 -18
  71. package/dist/main/money-price/money-price-interactive.mjs +30 -18
  72. package/dist/main/money-price/money-price-types.d.ts +7 -1
  73. package/dist/main/money-price/money-price-types.js +2 -2
  74. package/dist/main/money-price/money-price-types.mjs +2 -2
  75. package/dist/main/money-price/server.d.ts +1 -1
  76. package/dist/main/motion/creative-left-panel.d.ts +7 -0
  77. package/dist/main/motion/creative-left-panel.js +11 -0
  78. package/dist/main/motion/creative-left-panel.mjs +9 -0
  79. package/dist/main/motion/creative-right-panel.d.ts +7 -0
  80. package/dist/main/motion/creative-right-panel.js +11 -0
  81. package/dist/main/motion/creative-right-panel.mjs +9 -0
  82. package/dist/main/pill-select/x-pill-select.js +2 -2
  83. package/dist/main/pill-select/x-pill-select.mjs +2 -2
  84. package/dist/main/server.d.ts +1 -1
  85. package/dist/main/snake-loading-frame.js +1 -0
  86. package/dist/main/snake-loading-frame.mjs +1 -0
  87. package/package.json +13 -7
  88. package/src/ai/ai-prompt-textarea.tsx +6 -6
  89. package/src/clerk/clerk-auth-appearance.ts +16 -0
  90. package/src/clerk/clerk-page-context-generator.tsx +3 -5
  91. package/src/clerk/clerk-page-generator.tsx +9 -8
  92. package/src/clerk/clerk-user-client.tsx +14 -5
  93. package/src/clerk/fingerprint/fingerprint-client.ts +20 -20
  94. package/src/clerk/fingerprint/fingerprint-provider.tsx +11 -11
  95. package/src/clerk/fingerprint/fingerprint-server.ts +17 -17
  96. package/src/clerk/fingerprint/fingerprint-shared.ts +10 -10
  97. package/src/clerk/fingerprint/types.ts +0 -1
  98. package/src/clerk/fingerprint/use-fingerprint.ts +7 -7
  99. package/src/clerk/signin-with-fingerprint-client.tsx +7 -7
  100. package/src/clerk/signup-button-with-fingerprint-client.tsx +7 -5
  101. package/src/clerk/signup-with-fingerprint-client.tsx +7 -7
  102. package/src/fuma/base/custom-home-layout.tsx +4 -4
  103. package/src/fuma/fuma-page-genarator.tsx +2 -22
  104. package/src/fuma/heavy/mermaid.tsx +1 -1
  105. package/src/fuma/site-x.tsx +0 -1
  106. package/src/main/404-page.tsx +162 -0
  107. package/src/main/anime/anime-404-page.tsx +344 -0
  108. package/src/main/anime/index.ts +1 -0
  109. package/src/main/calendar/calendar-date-range-input.tsx +1 -1
  110. package/src/main/credit/types.ts +8 -8
  111. package/src/main/gallery/gallery-mobile-swiper.tsx +0 -1
  112. package/src/main/gallery/gallery-server.tsx +2 -2
  113. package/src/main/index.ts +1 -0
  114. package/src/main/money-price/index.ts +2 -0
  115. package/src/main/money-price/money-price-button.tsx +10 -10
  116. package/src/main/money-price/money-price-config-util.ts +49 -49
  117. package/src/main/money-price/money-price-interactive.tsx +40 -20
  118. package/src/main/money-price/money-price-types.ts +21 -14
  119. package/src/main/money-price/server.ts +2 -0
  120. package/src/main/pill-select/x-pill-select.tsx +2 -2
  121. package/src/main/server.ts +3 -1
  122. package/src/styles/third-ui.css +8 -0
@@ -0,0 +1,7 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface AnimeNotFoundPageProps {
3
+ siteIcon: ReactNode;
4
+ homeUrl?: string;
5
+ className?: string;
6
+ }
7
+ export declare function AnimeNotFoundPage({ siteIcon, homeUrl, className, }: AnimeNotFoundPageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,142 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var lib = require('@windrun-huaiin/base-ui/lib');
6
+ var utils = require('@windrun-huaiin/lib/utils');
7
+ var animejs = require('animejs');
8
+ var react = require('motion/react');
9
+ var React = require('react');
10
+
11
+ const dust = Array.from({ length: 10 }, (_, index) => ({
12
+ id: index,
13
+ left: `${12 + index * 8}%`,
14
+ top: `${18 + (index % 5) * 13}%`,
15
+ size: 3 + (index % 3),
16
+ }));
17
+ function AnimeNotFoundPage({ siteIcon, homeUrl = process.env.NEXT_PUBLIC_BASE_URL || '/', className, }) {
18
+ const rootRef = React.useRef(null);
19
+ const timelineRef = React.useRef(null);
20
+ const shimmerRef = React.useRef(null);
21
+ const doorAnimationRef = React.useRef(null);
22
+ const lightAnimationRef = React.useRef(null);
23
+ const handleAnimationRef = React.useRef(null);
24
+ const isDoorOpenRef = React.useRef(true);
25
+ const prefersReducedMotion = react.useReducedMotion();
26
+ const doorStyle = React.useMemo(() => ({
27
+ '--not-found-theme': lib.themeSvgIconColor,
28
+ }), []);
29
+ React.useEffect(() => {
30
+ var _a, _b;
31
+ const root = rootRef.current;
32
+ if (!root || prefersReducedMotion) {
33
+ return undefined;
34
+ }
35
+ const door = root.querySelector('[data-not-found-door]');
36
+ const light = root.querySelector('[data-not-found-light]');
37
+ const plate = root.querySelector('[data-not-found-plate]');
38
+ const handle = root.querySelector('[data-not-found-handle]');
39
+ const dustNodes = Array.from(root.querySelectorAll('[data-not-found-dust]'));
40
+ if (!door || !light || !plate || !handle) {
41
+ return undefined;
42
+ }
43
+ door.style.transform = 'rotateY(-46deg) translateX(-7px)';
44
+ light.style.opacity = '0.7';
45
+ light.style.transform = 'scaleX(1.12)';
46
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
47
+ timelineRef.current = animejs.createTimeline({ loop: true })
48
+ .add(plate, {
49
+ translateY: [0, -3, 0],
50
+ scale: [1, 1.025, 1],
51
+ duration: 1400,
52
+ ease: 'inOutSine',
53
+ })
54
+ .add(plate, {
55
+ translateY: [0, -3, 0],
56
+ scale: [1, 1.025, 1],
57
+ duration: 1400,
58
+ ease: 'inOutSine',
59
+ }, '+=900')
60
+ .add(dustNodes, {
61
+ opacity: [0, 0.72, 0],
62
+ translateY: [14, -18],
63
+ translateX: (_target, index) => (index % 2 === 0 ? 10 : -10),
64
+ scale: [0.4, 1, 0.6],
65
+ duration: 1800,
66
+ delay: animejs.stagger(80),
67
+ ease: 'outSine',
68
+ }, '<+=200');
69
+ (_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
70
+ shimmerRef.current = animejs.animate(root.querySelectorAll('[data-not-found-shimmer]'), {
71
+ translateX: ['-120%', '120%'],
72
+ opacity: [0, 0.8, 0],
73
+ duration: 2400,
74
+ delay: animejs.stagger(160),
75
+ ease: 'inOutSine',
76
+ loop: true,
77
+ });
78
+ return () => {
79
+ var _a, _b, _c, _d, _e;
80
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
81
+ timelineRef.current = null;
82
+ (_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
83
+ shimmerRef.current = null;
84
+ (_c = doorAnimationRef.current) === null || _c === void 0 ? void 0 : _c.revert();
85
+ doorAnimationRef.current = null;
86
+ (_d = lightAnimationRef.current) === null || _d === void 0 ? void 0 : _d.revert();
87
+ lightAnimationRef.current = null;
88
+ (_e = handleAnimationRef.current) === null || _e === void 0 ? void 0 : _e.revert();
89
+ handleAnimationRef.current = null;
90
+ };
91
+ }, [prefersReducedMotion]);
92
+ const toggleDoor = () => {
93
+ var _a, _b, _c;
94
+ const root = rootRef.current;
95
+ if (!root) {
96
+ return;
97
+ }
98
+ const door = root.querySelector('[data-not-found-door]');
99
+ const light = root.querySelector('[data-not-found-light]');
100
+ const handle = root.querySelector('[data-not-found-handle]');
101
+ if (!door || !light || !handle) {
102
+ return;
103
+ }
104
+ const nextOpen = !isDoorOpenRef.current;
105
+ isDoorOpenRef.current = nextOpen;
106
+ (_a = doorAnimationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
107
+ (_b = lightAnimationRef.current) === null || _b === void 0 ? void 0 : _b.revert();
108
+ (_c = handleAnimationRef.current) === null || _c === void 0 ? void 0 : _c.revert();
109
+ if (prefersReducedMotion) {
110
+ door.style.transform = nextOpen ? 'rotateY(-56deg) translateX(-9px)' : 'rotateY(-2deg) translateX(0)';
111
+ light.style.opacity = nextOpen ? '0.76' : '0.2';
112
+ light.style.transform = nextOpen ? 'scaleX(1.18)' : 'scaleX(0.78)';
113
+ return;
114
+ }
115
+ doorAnimationRef.current = animejs.animate(door, {
116
+ rotateY: nextOpen ? -56 : -2,
117
+ translateX: nextOpen ? -9 : 0,
118
+ duration: 760,
119
+ ease: 'outCubic',
120
+ });
121
+ lightAnimationRef.current = animejs.animate(light, {
122
+ opacity: nextOpen ? 0.76 : 0.2,
123
+ scaleX: nextOpen ? 1.18 : 0.78,
124
+ duration: 760,
125
+ ease: 'outCubic',
126
+ });
127
+ handleAnimationRef.current = animejs.animate(handle, {
128
+ scale: [1, 1.22, 1],
129
+ rotate: nextOpen ? [0, 18, 0] : [0, -18, 0],
130
+ duration: 520,
131
+ ease: 'inOutSine',
132
+ });
133
+ };
134
+ return (jsxRuntime.jsxs("div", { ref: rootRef, className: utils.cn('relative flex min-h-dvh w-full items-center justify-center overflow-hidden px-4 py-8', className), style: doorStyle, children: [jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.75),transparent_34%),linear-gradient(180deg,rgba(250,250,250,0.96),rgba(244,244,245,0.72))] dark:bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.08),transparent_34%),linear-gradient(180deg,rgba(24,24,27,0.96),rgba(9,9,11,0.92))]" }), jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 -z-10 h-1/2 bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.05))] dark:bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.34))]" }), jsxRuntime.jsxs("div", { className: "grid w-full max-w-4xl items-center gap-4 md:grid-cols-[minmax(0,0.9fr)_minmax(280px,0.78fr)] md:gap-6", children: [jsxRuntime.jsxs("section", { className: "order-2 text-center md:order-1 md:text-left", children: [jsxRuntime.jsx("h3", { className: utils.cn('whitespace-nowrap text-[clamp(2.15rem,8vw,3.4rem)] font-black leading-none tracking-normal md:text-[clamp(2.6rem,4.5vw,4rem)] bg-linear-to-r bg-clip-text text-transparent', lib.themeButtonGradientClass), children: "Page Not Found" }), jsxRuntime.jsx("p", { className: "mx-auto mt-5 max-w-xl text-base leading-7 text-muted-foreground md:mx-0 md:text-lg", children: "The page you're looking for doesn't exist" }), jsxRuntime.jsx("a", { href: homeUrl, className: utils.cn('mt-4 inline-flex text-sm font-semibold underline underline-offset-4 transition-opacity hover:opacity-80', lib.themeIconColor, 'decoration-current'), children: "Back to Homepage" }), jsxRuntime.jsx("span", { className: utils.cn('mt-9 inline-flex size-2 rounded-full', lib.themeBgColor) })] }), jsxRuntime.jsx("section", { className: "order-1 flex justify-center md:order-2", children: jsxRuntime.jsxs("div", { className: "relative aspect-[0.78] w-full max-w-[270px] sm:max-w-[315px] md:max-w-[330px] [perspective:1200px]", children: [jsxRuntime.jsx("div", { "data-not-found-light": "", className: "absolute left-[14%] top-[7%] h-[86%] w-[72%] rounded-[28px] bg-[radial-gradient(circle_at_50%_45%,rgba(255,255,255,0.96),color-mix(in_srgb,var(--not-found-theme)_42%,transparent)_42%,transparent_72%)] opacity-25 blur-xl" }), jsxRuntime.jsx("div", { className: "absolute inset-[4%] rounded-[32px] border border-black/10 bg-neutral-950/5 shadow-2xl shadow-black/10 dark:border-white/10 dark:bg-white/5" }), jsxRuntime.jsx("div", { className: "absolute inset-[8%] rounded-[26px] bg-[linear-gradient(180deg,rgba(255,255,255,0.88),rgba(228,228,231,0.86))] shadow-[inset_0_1px_0_rgba(255,255,255,0.85)] dark:bg-[linear-gradient(180deg,rgba(39,39,42,0.92),rgba(24,24,27,0.96))]" }), jsxRuntime.jsxs("div", { "data-not-found-door": "", className: "absolute inset-[8%] origin-left rounded-[26px] border border-black/10 bg-[linear-gradient(145deg,rgba(255,255,255,0.92),rgba(212,212,216,0.9))] shadow-2xl shadow-black/20 will-change-transform dark:border-white/10 dark:bg-[linear-gradient(145deg,rgba(63,63,70,0.96),rgba(24,24,27,0.98))]", children: [jsxRuntime.jsxs("div", { className: "absolute inset-4 overflow-hidden rounded-[20px] border border-black/10 dark:border-white/10", children: [jsxRuntime.jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/3 -skew-x-12 bg-white/35 blur-md dark:bg-white/12" }), jsxRuntime.jsx("div", { className: "absolute inset-x-5 top-5 h-[30%] rounded-2xl border border-black/10 bg-white/35 dark:border-white/10 dark:bg-white/5" }), jsxRuntime.jsxs("a", { href: homeUrl, className: "absolute inset-x-5 bottom-5 flex h-[39%] flex-col items-center justify-center gap-2 rounded-2xl border border-black/10 bg-white/25 text-sm text-muted-foreground transition-opacity hover:opacity-80 dark:border-white/10 dark:bg-white/5", children: [siteIcon, jsxRuntime.jsx("span", { children: "Woops!" })] })] }), jsxRuntime.jsxs("div", { "data-not-found-plate": "", className: "absolute left-1/2 top-[18%] flex h-[88px] w-[156px] -translate-x-1/2 items-center justify-center overflow-hidden rounded-2xl border border-black/10 bg-white/86 shadow-lg shadow-black/10 dark:border-white/10 dark:bg-black/30", children: [jsxRuntime.jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/2 -skew-x-12 bg-white/60 blur-md dark:bg-white/15" }), jsxRuntime.jsx("span", { className: utils.cn('relative text-5xl font-black tabular-nums bg-linear-to-r bg-clip-text text-transparent', lib.themeButtonGradientClass), children: "404" })] }), jsxRuntime.jsx("button", { type: "button", "data-not-found-handle": "", className: "absolute right-[16%] top-1/2 z-10 size-6 rounded-full border border-black/10 bg-[var(--not-found-theme)] shadow-lg shadow-black/20 outline-none ring-offset-2 transition-transform hover:scale-110 focus-visible:ring-2 focus-visible:ring-[var(--not-found-theme)] dark:border-white/15", "aria-label": "Toggle the 404 door", onClick: toggleDoor })] }), dust.map(dot => (jsxRuntime.jsx("span", { "data-not-found-dust": "", className: "absolute rounded-full bg-[var(--not-found-theme)] opacity-0", style: {
135
+ left: dot.left,
136
+ top: dot.top,
137
+ width: dot.size,
138
+ height: dot.size,
139
+ } }, dot.id)))] }) })] })] }));
140
+ }
141
+
142
+ exports.AnimeNotFoundPage = AnimeNotFoundPage;
@@ -0,0 +1,140 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { themeSvgIconColor, themeButtonGradientClass, themeIconColor, themeBgColor } from '@windrun-huaiin/base-ui/lib';
4
+ import { cn } from '@windrun-huaiin/lib/utils';
5
+ import { createTimeline, stagger, animate } from 'animejs';
6
+ import { useReducedMotion } from 'motion/react';
7
+ import { useRef, useMemo, useEffect } from 'react';
8
+
9
+ const dust = Array.from({ length: 10 }, (_, index) => ({
10
+ id: index,
11
+ left: `${12 + index * 8}%`,
12
+ top: `${18 + (index % 5) * 13}%`,
13
+ size: 3 + (index % 3),
14
+ }));
15
+ function AnimeNotFoundPage({ siteIcon, homeUrl = process.env.NEXT_PUBLIC_BASE_URL || '/', className, }) {
16
+ const rootRef = useRef(null);
17
+ const timelineRef = useRef(null);
18
+ const shimmerRef = useRef(null);
19
+ const doorAnimationRef = useRef(null);
20
+ const lightAnimationRef = useRef(null);
21
+ const handleAnimationRef = useRef(null);
22
+ const isDoorOpenRef = useRef(true);
23
+ const prefersReducedMotion = useReducedMotion();
24
+ const doorStyle = useMemo(() => ({
25
+ '--not-found-theme': themeSvgIconColor,
26
+ }), []);
27
+ useEffect(() => {
28
+ var _a, _b;
29
+ const root = rootRef.current;
30
+ if (!root || prefersReducedMotion) {
31
+ return undefined;
32
+ }
33
+ const door = root.querySelector('[data-not-found-door]');
34
+ const light = root.querySelector('[data-not-found-light]');
35
+ const plate = root.querySelector('[data-not-found-plate]');
36
+ const handle = root.querySelector('[data-not-found-handle]');
37
+ const dustNodes = Array.from(root.querySelectorAll('[data-not-found-dust]'));
38
+ if (!door || !light || !plate || !handle) {
39
+ return undefined;
40
+ }
41
+ door.style.transform = 'rotateY(-46deg) translateX(-7px)';
42
+ light.style.opacity = '0.7';
43
+ light.style.transform = 'scaleX(1.12)';
44
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
45
+ timelineRef.current = createTimeline({ loop: true })
46
+ .add(plate, {
47
+ translateY: [0, -3, 0],
48
+ scale: [1, 1.025, 1],
49
+ duration: 1400,
50
+ ease: 'inOutSine',
51
+ })
52
+ .add(plate, {
53
+ translateY: [0, -3, 0],
54
+ scale: [1, 1.025, 1],
55
+ duration: 1400,
56
+ ease: 'inOutSine',
57
+ }, '+=900')
58
+ .add(dustNodes, {
59
+ opacity: [0, 0.72, 0],
60
+ translateY: [14, -18],
61
+ translateX: (_target, index) => (index % 2 === 0 ? 10 : -10),
62
+ scale: [0.4, 1, 0.6],
63
+ duration: 1800,
64
+ delay: stagger(80),
65
+ ease: 'outSine',
66
+ }, '<+=200');
67
+ (_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
68
+ shimmerRef.current = animate(root.querySelectorAll('[data-not-found-shimmer]'), {
69
+ translateX: ['-120%', '120%'],
70
+ opacity: [0, 0.8, 0],
71
+ duration: 2400,
72
+ delay: stagger(160),
73
+ ease: 'inOutSine',
74
+ loop: true,
75
+ });
76
+ return () => {
77
+ var _a, _b, _c, _d, _e;
78
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
79
+ timelineRef.current = null;
80
+ (_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
81
+ shimmerRef.current = null;
82
+ (_c = doorAnimationRef.current) === null || _c === void 0 ? void 0 : _c.revert();
83
+ doorAnimationRef.current = null;
84
+ (_d = lightAnimationRef.current) === null || _d === void 0 ? void 0 : _d.revert();
85
+ lightAnimationRef.current = null;
86
+ (_e = handleAnimationRef.current) === null || _e === void 0 ? void 0 : _e.revert();
87
+ handleAnimationRef.current = null;
88
+ };
89
+ }, [prefersReducedMotion]);
90
+ const toggleDoor = () => {
91
+ var _a, _b, _c;
92
+ const root = rootRef.current;
93
+ if (!root) {
94
+ return;
95
+ }
96
+ const door = root.querySelector('[data-not-found-door]');
97
+ const light = root.querySelector('[data-not-found-light]');
98
+ const handle = root.querySelector('[data-not-found-handle]');
99
+ if (!door || !light || !handle) {
100
+ return;
101
+ }
102
+ const nextOpen = !isDoorOpenRef.current;
103
+ isDoorOpenRef.current = nextOpen;
104
+ (_a = doorAnimationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
105
+ (_b = lightAnimationRef.current) === null || _b === void 0 ? void 0 : _b.revert();
106
+ (_c = handleAnimationRef.current) === null || _c === void 0 ? void 0 : _c.revert();
107
+ if (prefersReducedMotion) {
108
+ door.style.transform = nextOpen ? 'rotateY(-56deg) translateX(-9px)' : 'rotateY(-2deg) translateX(0)';
109
+ light.style.opacity = nextOpen ? '0.76' : '0.2';
110
+ light.style.transform = nextOpen ? 'scaleX(1.18)' : 'scaleX(0.78)';
111
+ return;
112
+ }
113
+ doorAnimationRef.current = animate(door, {
114
+ rotateY: nextOpen ? -56 : -2,
115
+ translateX: nextOpen ? -9 : 0,
116
+ duration: 760,
117
+ ease: 'outCubic',
118
+ });
119
+ lightAnimationRef.current = animate(light, {
120
+ opacity: nextOpen ? 0.76 : 0.2,
121
+ scaleX: nextOpen ? 1.18 : 0.78,
122
+ duration: 760,
123
+ ease: 'outCubic',
124
+ });
125
+ handleAnimationRef.current = animate(handle, {
126
+ scale: [1, 1.22, 1],
127
+ rotate: nextOpen ? [0, 18, 0] : [0, -18, 0],
128
+ duration: 520,
129
+ ease: 'inOutSine',
130
+ });
131
+ };
132
+ return (jsxs("div", { ref: rootRef, className: cn('relative flex min-h-dvh w-full items-center justify-center overflow-hidden px-4 py-8', className), style: doorStyle, children: [jsx("div", { className: "pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.75),transparent_34%),linear-gradient(180deg,rgba(250,250,250,0.96),rgba(244,244,245,0.72))] dark:bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.08),transparent_34%),linear-gradient(180deg,rgba(24,24,27,0.96),rgba(9,9,11,0.92))]" }), jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 -z-10 h-1/2 bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.05))] dark:bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.34))]" }), jsxs("div", { className: "grid w-full max-w-4xl items-center gap-4 md:grid-cols-[minmax(0,0.9fr)_minmax(280px,0.78fr)] md:gap-6", children: [jsxs("section", { className: "order-2 text-center md:order-1 md:text-left", children: [jsx("h3", { className: cn('whitespace-nowrap text-[clamp(2.15rem,8vw,3.4rem)] font-black leading-none tracking-normal md:text-[clamp(2.6rem,4.5vw,4rem)] bg-linear-to-r bg-clip-text text-transparent', themeButtonGradientClass), children: "Page Not Found" }), jsx("p", { className: "mx-auto mt-5 max-w-xl text-base leading-7 text-muted-foreground md:mx-0 md:text-lg", children: "The page you're looking for doesn't exist" }), jsx("a", { href: homeUrl, className: cn('mt-4 inline-flex text-sm font-semibold underline underline-offset-4 transition-opacity hover:opacity-80', themeIconColor, 'decoration-current'), children: "Back to Homepage" }), jsx("span", { className: cn('mt-9 inline-flex size-2 rounded-full', themeBgColor) })] }), jsx("section", { className: "order-1 flex justify-center md:order-2", children: jsxs("div", { className: "relative aspect-[0.78] w-full max-w-[270px] sm:max-w-[315px] md:max-w-[330px] [perspective:1200px]", children: [jsx("div", { "data-not-found-light": "", className: "absolute left-[14%] top-[7%] h-[86%] w-[72%] rounded-[28px] bg-[radial-gradient(circle_at_50%_45%,rgba(255,255,255,0.96),color-mix(in_srgb,var(--not-found-theme)_42%,transparent)_42%,transparent_72%)] opacity-25 blur-xl" }), jsx("div", { className: "absolute inset-[4%] rounded-[32px] border border-black/10 bg-neutral-950/5 shadow-2xl shadow-black/10 dark:border-white/10 dark:bg-white/5" }), jsx("div", { className: "absolute inset-[8%] rounded-[26px] bg-[linear-gradient(180deg,rgba(255,255,255,0.88),rgba(228,228,231,0.86))] shadow-[inset_0_1px_0_rgba(255,255,255,0.85)] dark:bg-[linear-gradient(180deg,rgba(39,39,42,0.92),rgba(24,24,27,0.96))]" }), jsxs("div", { "data-not-found-door": "", className: "absolute inset-[8%] origin-left rounded-[26px] border border-black/10 bg-[linear-gradient(145deg,rgba(255,255,255,0.92),rgba(212,212,216,0.9))] shadow-2xl shadow-black/20 will-change-transform dark:border-white/10 dark:bg-[linear-gradient(145deg,rgba(63,63,70,0.96),rgba(24,24,27,0.98))]", children: [jsxs("div", { className: "absolute inset-4 overflow-hidden rounded-[20px] border border-black/10 dark:border-white/10", children: [jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/3 -skew-x-12 bg-white/35 blur-md dark:bg-white/12" }), jsx("div", { className: "absolute inset-x-5 top-5 h-[30%] rounded-2xl border border-black/10 bg-white/35 dark:border-white/10 dark:bg-white/5" }), jsxs("a", { href: homeUrl, className: "absolute inset-x-5 bottom-5 flex h-[39%] flex-col items-center justify-center gap-2 rounded-2xl border border-black/10 bg-white/25 text-sm text-muted-foreground transition-opacity hover:opacity-80 dark:border-white/10 dark:bg-white/5", children: [siteIcon, jsx("span", { children: "Woops!" })] })] }), jsxs("div", { "data-not-found-plate": "", className: "absolute left-1/2 top-[18%] flex h-[88px] w-[156px] -translate-x-1/2 items-center justify-center overflow-hidden rounded-2xl border border-black/10 bg-white/86 shadow-lg shadow-black/10 dark:border-white/10 dark:bg-black/30", children: [jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/2 -skew-x-12 bg-white/60 blur-md dark:bg-white/15" }), jsx("span", { className: cn('relative text-5xl font-black tabular-nums bg-linear-to-r bg-clip-text text-transparent', themeButtonGradientClass), children: "404" })] }), jsx("button", { type: "button", "data-not-found-handle": "", className: "absolute right-[16%] top-1/2 z-10 size-6 rounded-full border border-black/10 bg-[var(--not-found-theme)] shadow-lg shadow-black/20 outline-none ring-offset-2 transition-transform hover:scale-110 focus-visible:ring-2 focus-visible:ring-[var(--not-found-theme)] dark:border-white/15", "aria-label": "Toggle the 404 door", onClick: toggleDoor })] }), dust.map(dot => (jsx("span", { "data-not-found-dust": "", className: "absolute rounded-full bg-[var(--not-found-theme)] opacity-0", style: {
133
+ left: dot.left,
134
+ top: dot.top,
135
+ width: dot.size,
136
+ height: dot.size,
137
+ } }, dot.id)))] }) })] })] }));
138
+ }
139
+
140
+ export { AnimeNotFoundPage };
@@ -1,2 +1,3 @@
1
1
  export { AnimeBeamFrame, type BeamFrameProps, type BeamFrameTone, } from './anime-beam-frame';
2
2
  export { AnimeSpiralLoading, type AnimeSpiralLoadingProps } from './anime-spiral-loading';
3
+ export { AnimeNotFoundPage, type AnimeNotFoundPageProps } from './anime-404-page';
@@ -3,8 +3,10 @@
3
3
 
4
4
  var animeBeamFrame = require('./anime-beam-frame.js');
5
5
  var animeSpiralLoading = require('./anime-spiral-loading.js');
6
+ var anime404Page = require('./anime-404-page.js');
6
7
 
7
8
 
8
9
 
9
10
  exports.AnimeBeamFrame = animeBeamFrame.AnimeBeamFrame;
10
11
  exports.AnimeSpiralLoading = animeSpiralLoading.AnimeSpiralLoading;
12
+ exports.AnimeNotFoundPage = anime404Page.AnimeNotFoundPage;
@@ -1,3 +1,4 @@
1
1
  "use client";
2
2
  export { AnimeBeamFrame } from './anime-beam-frame.mjs';
3
3
  export { AnimeSpiralLoading } from './anime-spiral-loading.mjs';
4
+ export { AnimeNotFoundPage } from './anime-404-page.mjs';
@@ -9,7 +9,7 @@ var utils = require('@windrun-huaiin/lib/utils');
9
9
  var usePressFeedback = require('../buttons/use-press-feedback.js');
10
10
  var randomDateRangeDialog = require('./random-date-range-dialog.js');
11
11
 
12
- const DEFAULT_PLACEHOLDER = '滑动窗口日期';
12
+ const DEFAULT_PLACEHOLDER = 'Slide pick Date';
13
13
  const DEFAULT_RANGE_DAYS = 7;
14
14
  const CLEAR_PRESS_FEEDBACK_MS = 180;
15
15
  function parseDateString(value) {
@@ -7,7 +7,7 @@ import { cn } from '@windrun-huaiin/lib/utils';
7
7
  import { usePressFeedback, resolvePressFeedbackMode } from '../buttons/use-press-feedback.mjs';
8
8
  import { RandomDateRangeDialog } from './random-date-range-dialog.mjs';
9
9
 
10
- const DEFAULT_PLACEHOLDER = '滑动窗口日期';
10
+ const DEFAULT_PLACEHOLDER = 'Slide pick Date';
11
11
  const DEFAULT_RANGE_DAYS = 7;
12
12
  const CLEAR_PRESS_FEEDBACK_MS = 180;
13
13
  function parseDateString(value) {
@@ -29,21 +29,21 @@ export interface CreditCTAConfig {
29
29
  }
30
30
  export type CreditBucketStatus = 'active' | 'expiringSoon' | 'expired';
31
31
  export interface CreditBucket {
32
- /** 业务方自定义的积分类型标识,用于映射翻译或埋点 */
32
+ /** Business-defined credit type identifier for translation mapping or analytics. */
33
33
  kind: string;
34
- /** 若提供则使用该名称,否则由组件根据 kind 使用默认翻译 */
34
+ /** Display name override; otherwise the component uses the default translation for kind. */
35
35
  label?: string;
36
- /** 当前积分余额 */
36
+ /** Current credit balance. */
37
37
  balance: number;
38
- /** 该类型积分的额度上限 */
38
+ /** Credit limit for this credit type. */
39
39
  limit: number;
40
- /** 可选状态标签,用于强调过期等状态 */
40
+ /** Optional status label for highlighting states such as expiration. */
41
41
  status?: CreditBucketStatus;
42
- /** 积分过期时间(本地时区字符串),用于组件内部推导状态 */
42
+ /** Credit expiration time as a local time string, used to derive component state. */
43
43
  expiresAt?: string;
44
- /** 进度百分比(0-100);未提供时组件按 balance/limit 计算 */
44
+ /** Progress percentage from 0 to 100; computed from balance/limit when omitted. */
45
45
  progressPercent?: number;
46
- /** 任何额外说明,如剩余天数、使用限制等 */
46
+ /** Additional details, such as remaining days or usage limits. */
47
47
  description?: string;
48
48
  }
49
49
  export interface SubscriptionInfo {
@@ -1,4 +1,5 @@
1
1
  export * from './go-to-top';
2
+ export * from './404-page';
2
3
  export * from './loading';
3
4
  export * from './nprogress-bar';
4
5
  export * from './rich-text-expert';
@@ -2,6 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var goToTop = require('./go-to-top.js');
5
+ var _404Page = require('./404-page.js');
5
6
  var loading = require('./loading.js');
6
7
  var nprogressBar = require('./nprogress-bar.js');
7
8
  var richTextExpert = require('./rich-text-expert.js');
@@ -11,6 +12,7 @@ var infoTooltip = require('./info-tooltip.js');
11
12
 
12
13
 
13
14
  exports.GoToTop = goToTop.GoToTop;
15
+ exports.NotFoundPage = _404Page.NotFoundPage;
14
16
  exports.Loading = loading.Loading;
15
17
  exports.getLoadingCycleDurationMs = loading.getLoadingCycleDurationMs;
16
18
  exports.NProgressBar = nprogressBar.NProgressBar;
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  export { GoToTop } from './go-to-top.mjs';
3
+ export { NotFoundPage } from './404-page.mjs';
3
4
  export { Loading, getLoadingCycleDurationMs } from './loading.mjs';
4
5
  export { NProgressBar } from './nprogress-bar.mjs';
5
6
  export { createRichTextRenderer, richText } from './rich-text-expert.mjs';
@@ -1,4 +1,4 @@
1
1
  export { MoneyPriceInteractive } from './money-price-interactive';
2
2
  export { MoneyPriceButton } from './money-price-button';
3
- export type { MoneyPriceConfig, MoneyPriceData, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
3
+ export type { MoneyPriceConfig, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, MoneyPriceInteractiveProps, MoneyPriceButtonProps, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
4
4
  export { UserState } from './money-price-types';
@@ -26,9 +26,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
26
26
  return billing === 'monthly' ? 2 : 4;
27
27
  return 0;
28
28
  };
29
- // OneTime 模式的按钮配置
29
+ // Button configuration for one-time mode.
30
30
  const getOnetimeButtonConfig = () => {
31
- // 匿名用户:所有卡片都显示登录按钮
31
+ // Anonymous users: show the sign-in button on every card.
32
32
  if (!isAuthenticated) {
33
33
  return {
34
34
  text: texts.getStarted,
@@ -38,11 +38,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
38
38
  };
39
39
  }
40
40
  if (subscriptionStatus === moneyPriceTypes.UserState.Anonymous) {
41
- // 已登录但状态未知 视为 FreeUser
41
+ // Signed in but status unknown: treat as FreeUser.
42
42
  console.warn('Clerk is authed OK but user is anonymous!');
43
43
  return { text: '', disabled: true, hidden: true };
44
44
  }
45
- // 登录用户:OneTime 模式下所有卡片都显示购买积分按钮
45
+ // Signed-in users: show the buy-credits button on every card in one-time mode.
46
46
  return {
47
47
  text: texts.buyCredits || texts.upgrade,
48
48
  onClick: () => onAction(planKey, billingType),
@@ -50,9 +50,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
50
50
  hidden: false
51
51
  };
52
52
  };
53
- // 订阅模式的按钮配置
53
+ // Button configuration for subscription mode.
54
54
  const getSubscriptionButtonConfig = () => {
55
- // 匿名用户
55
+ // Anonymous users.
56
56
  if (!isAuthenticated) {
57
57
  const getButtonText = () => {
58
58
  switch (planKey) {
@@ -73,7 +73,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
73
73
  hidden: false
74
74
  };
75
75
  }
76
- // 已登录用户
76
+ // Signed-in users.
77
77
  switch (subscriptionStatus) {
78
78
  case moneyPriceTypes.UserState.FreeUser: {
79
79
  if (planTier === 'F1') {
@@ -91,7 +91,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
91
91
  };
92
92
  }
93
93
  case moneyPriceTypes.UserState.ProUser: {
94
- // 不允许降级到 Free
94
+ // Do not allow downgrades to Free.
95
95
  if (planTier === 'F1') {
96
96
  return { hidden: true };
97
97
  }
@@ -169,12 +169,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
169
169
  return { hidden: true };
170
170
  }
171
171
  default:
172
- // 已登录但状态未知 视为 FreeUser
172
+ // Signed in but status unknown: treat as FreeUser.
173
173
  console.warn('Clerk is authed OK but user is anonymous!');
174
174
  return { text: '', disabled: true, hidden: true };
175
175
  }
176
176
  };
177
- // 主要的按钮配置函数
177
+ // Main button configuration function.
178
178
  const getButtonConfig = () => {
179
179
  if (billingType === 'onetime') {
180
180
  return getOnetimeButtonConfig();
@@ -24,9 +24,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
24
24
  return billing === 'monthly' ? 2 : 4;
25
25
  return 0;
26
26
  };
27
- // OneTime 模式的按钮配置
27
+ // Button configuration for one-time mode.
28
28
  const getOnetimeButtonConfig = () => {
29
- // 匿名用户:所有卡片都显示登录按钮
29
+ // Anonymous users: show the sign-in button on every card.
30
30
  if (!isAuthenticated) {
31
31
  return {
32
32
  text: texts.getStarted,
@@ -36,11 +36,11 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
36
36
  };
37
37
  }
38
38
  if (subscriptionStatus === UserState.Anonymous) {
39
- // 已登录但状态未知 视为 FreeUser
39
+ // Signed in but status unknown: treat as FreeUser.
40
40
  console.warn('Clerk is authed OK but user is anonymous!');
41
41
  return { text: '', disabled: true, hidden: true };
42
42
  }
43
- // 登录用户:OneTime 模式下所有卡片都显示购买积分按钮
43
+ // Signed-in users: show the buy-credits button on every card in one-time mode.
44
44
  return {
45
45
  text: texts.buyCredits || texts.upgrade,
46
46
  onClick: () => onAction(planKey, billingType),
@@ -48,9 +48,9 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
48
48
  hidden: false
49
49
  };
50
50
  };
51
- // 订阅模式的按钮配置
51
+ // Button configuration for subscription mode.
52
52
  const getSubscriptionButtonConfig = () => {
53
- // 匿名用户
53
+ // Anonymous users.
54
54
  if (!isAuthenticated) {
55
55
  const getButtonText = () => {
56
56
  switch (planKey) {
@@ -71,7 +71,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
71
71
  hidden: false
72
72
  };
73
73
  }
74
- // 已登录用户
74
+ // Signed-in users.
75
75
  switch (subscriptionStatus) {
76
76
  case UserState.FreeUser: {
77
77
  if (planTier === 'F1') {
@@ -89,7 +89,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
89
89
  };
90
90
  }
91
91
  case UserState.ProUser: {
92
- // 不允许降级到 Free
92
+ // Do not allow downgrades to Free.
93
93
  if (planTier === 'F1') {
94
94
  return { hidden: true };
95
95
  }
@@ -167,12 +167,12 @@ function MoneyPriceButton({ planKey, userContext, billingType, onAuth, onAction,
167
167
  return { hidden: true };
168
168
  }
169
169
  default:
170
- // 已登录但状态未知 视为 FreeUser
170
+ // Signed in but status unknown: treat as FreeUser.
171
171
  console.warn('Clerk is authed OK but user is anonymous!');
172
172
  return { text: '', disabled: true, hidden: true };
173
173
  }
174
174
  };
175
- // 主要的按钮配置函数
175
+ // Main button configuration function.
176
176
  const getButtonConfig = () => {
177
177
  if (billingType === 'onetime') {
178
178
  return getOnetimeButtonConfig();
@@ -1,52 +1,52 @@
1
1
  /**
2
2
  * Money Price Configuration
3
- * 价格组件配置文件
3
+ * Pricing component configuration.
4
4
  */
5
5
  import type { MoneyPriceConfig, PaymentProviderConfig, EnhancePricePlan } from './money-price-types';
6
6
  /**
7
- * 获取当前激活的支付供应商配置
7
+ * Get the currently active payment provider configuration.
8
8
  *
9
- * 🔒 安全设计:
10
- * - util层负责从config中提取激活的provider配置
11
- * - 只返回提取的结果,不暴露任何config结构
12
- * - 调用方(应用层)通过wrapper隐藏config对象
9
+ * Security design:
10
+ * - The utility layer extracts the active provider configuration from the config.
11
+ * - Only the extracted result is returned; the full config structure is not exposed.
12
+ * - Application-level wrappers hide the config object from callers.
13
13
  *
14
- * @param config - MoneyPriceConfig对象(由应用层提供)
15
- * @returns 当前激活的支付供应商配置
14
+ * @param config - MoneyPriceConfig object provided by the application layer.
15
+ * @returns The currently active payment provider configuration.
16
16
  */
17
17
  export declare function getActiveProviderConfigUtil(config: MoneyPriceConfig): PaymentProviderConfig;
18
18
  export declare function getProductPricing(productKey: 'F1' | 'P2' | 'U3', billingType: string, provider: string, config: MoneyPriceConfig): EnhancePricePlan;
19
19
  /**
20
- * 根据 priceId 获取对应的积分数量
20
+ * Get the credit amount for a price ID.
21
21
  *
22
- * 🔒 安全设计:
23
- * - util层负责解析config,提取所需数据
24
- * - 只返回查询结果,不暴露任何config结构
25
- * - 调用方(应用层)通过wrapper隐藏config对象
22
+ * Security design:
23
+ * - The utility layer parses the config and extracts only the required data.
24
+ * - Only the query result is returned; the full config structure is not exposed.
25
+ * - Application-level wrappers hide the config object from callers.
26
26
  *
27
- * @param priceId - 查询的价格ID
28
- * @param config - MoneyPriceConfig对象(由应用层提供)
29
- * @returns 对应的积分数量,或null
27
+ * @param priceId - Price ID to query.
28
+ * @param config - MoneyPriceConfig object provided by the application layer.
29
+ * @returns The matching credit amount, or null.
30
30
  */
31
31
  export declare function getCreditsFromPriceIdUtil(priceId: string | undefined, config: MoneyPriceConfig): number | null;
32
32
  /**
33
- * 根据查询参数获取价格配置
33
+ * Get price configuration by query parameters.
34
34
  *
35
- * 支持三种查询方式:
36
- * 1. priceId 直接查询
37
- * 2. plan + billingType 查询
38
- * 3. plan 查询
35
+ * Supported query modes:
36
+ * 1. Query directly by priceId.
37
+ * 2. Query by plan and billingType.
38
+ * 3. Query by plan.
39
39
  *
40
- * 🔒 安全设计:
41
- * - util层负责解析config,提取和匹配数据
42
- * - 只返回查询结果,不暴露任何config结构
43
- * - 调用方(应用层)通过wrapper隐藏config对象
40
+ * Security design:
41
+ * - The utility layer parses the config and extracts only matching data.
42
+ * - Only the query result is returned; the full config structure is not exposed.
43
+ * - Application-level wrappers hide the config object from callers.
44
44
  *
45
- * @param priceId - 查询的价格ID(可选)
46
- * @param plan - 查询的套餐名称如'P2''U3'(可选)
47
- * @param billingType - 查询的计费类型如'monthly''yearly'(可选)
48
- * @param config - MoneyPriceConfig对象(由应用层提供)
49
- * @returns 匹配的价格配置,包含计算好的元数据(priceNamedescriptioninterval
45
+ * @param priceId - Optional price ID to query.
46
+ * @param plan - Optional plan name, such as 'P2' or 'U3'.
47
+ * @param billingType - Optional billing type, such as 'monthly' or 'yearly'.
48
+ * @param config - MoneyPriceConfig object provided by the application layer.
49
+ * @returns The matching price config with derived metadata: priceName, description, and interval.
50
50
  */
51
51
  export declare function getPriceConfigUtil(priceId: string | undefined, plan: string | undefined, billingType: string | undefined, config: MoneyPriceConfig): (EnhancePricePlan & {
52
52
  priceName: string;