sa2kit 2.0.1 → 2.0.2

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 (264) hide show
  1. package/README.md +1 -1
  2. package/dist/CollisionBalls-BpHufX3H.d.mts +41 -0
  3. package/dist/CollisionBalls-BpHufX3H.d.ts +41 -0
  4. package/dist/ConfigService-BxK06xP6.d.mts +262 -0
  5. package/dist/ConfigService-BxK06xP6.d.ts +262 -0
  6. package/dist/UniversalFileService-BpvbZitV.d.mts +139 -0
  7. package/dist/UniversalFileService-GsP6D3Rc.d.ts +139 -0
  8. package/dist/audioDetection/index.d.mts +449 -0
  9. package/dist/audioDetection/index.d.ts +449 -0
  10. package/dist/audioDetection/index.js +1244 -0
  11. package/dist/audioDetection/index.js.map +1 -0
  12. package/dist/audioDetection/index.mjs +1227 -0
  13. package/dist/audioDetection/index.mjs.map +1 -0
  14. package/dist/auth/legacy/core/index.d.mts +42 -0
  15. package/dist/auth/legacy/core/index.d.ts +42 -0
  16. package/dist/auth/legacy/core/index.js +242 -0
  17. package/dist/auth/legacy/core/index.js.map +1 -0
  18. package/dist/auth/legacy/core/index.mjs +226 -0
  19. package/dist/auth/legacy/core/index.mjs.map +1 -0
  20. package/dist/auth/legacy/db/index.d.mts +5 -0
  21. package/dist/auth/legacy/db/index.d.ts +5 -0
  22. package/dist/auth/legacy/db/index.js +261 -0
  23. package/dist/auth/legacy/db/index.js.map +1 -0
  24. package/dist/auth/legacy/db/index.mjs +250 -0
  25. package/dist/auth/legacy/db/index.mjs.map +1 -0
  26. package/dist/auth/legacy/index.d.mts +5 -0
  27. package/dist/auth/legacy/index.d.ts +5 -0
  28. package/dist/auth/legacy/index.js +1107 -0
  29. package/dist/auth/legacy/index.js.map +1 -0
  30. package/dist/auth/legacy/index.mjs +1086 -0
  31. package/dist/auth/legacy/index.mjs.map +1 -0
  32. package/dist/auth/legacy/logic/index.d.mts +9 -0
  33. package/dist/auth/legacy/logic/index.d.ts +9 -0
  34. package/dist/auth/legacy/logic/index.js +194 -0
  35. package/dist/auth/legacy/logic/index.js.map +1 -0
  36. package/dist/auth/legacy/logic/index.mjs +187 -0
  37. package/dist/auth/legacy/logic/index.mjs.map +1 -0
  38. package/dist/auth/legacy/miniapp/index.d.mts +5 -0
  39. package/dist/auth/legacy/miniapp/index.d.ts +5 -0
  40. package/dist/auth/legacy/miniapp/index.js +506 -0
  41. package/dist/auth/legacy/miniapp/index.js.map +1 -0
  42. package/dist/auth/legacy/miniapp/index.mjs +487 -0
  43. package/dist/auth/legacy/miniapp/index.mjs.map +1 -0
  44. package/dist/auth/legacy/routes/index.d.mts +53 -0
  45. package/dist/auth/legacy/routes/index.d.ts +53 -0
  46. package/dist/auth/legacy/routes/index.js +278 -0
  47. package/dist/auth/legacy/routes/index.js.map +1 -0
  48. package/dist/auth/legacy/routes/index.mjs +271 -0
  49. package/dist/auth/legacy/routes/index.mjs.map +1 -0
  50. package/dist/auth/legacy/schema/index.d.mts +401 -0
  51. package/dist/auth/legacy/schema/index.d.ts +401 -0
  52. package/dist/auth/legacy/schema/index.js +50 -0
  53. package/dist/auth/legacy/schema/index.js.map +1 -0
  54. package/dist/auth/legacy/schema/index.mjs +44 -0
  55. package/dist/auth/legacy/schema/index.mjs.map +1 -0
  56. package/dist/auth/legacy/server/index.d.mts +13 -0
  57. package/dist/auth/legacy/server/index.d.ts +13 -0
  58. package/dist/auth/legacy/server/index.js +21 -0
  59. package/dist/auth/legacy/server/index.js.map +1 -0
  60. package/dist/auth/legacy/server/index.mjs +19 -0
  61. package/dist/auth/legacy/server/index.mjs.map +1 -0
  62. package/dist/auth/legacy/services/index.d.mts +40 -0
  63. package/dist/auth/legacy/services/index.d.ts +40 -0
  64. package/dist/auth/legacy/services/index.js +258 -0
  65. package/dist/auth/legacy/services/index.js.map +1 -0
  66. package/dist/auth/legacy/services/index.mjs +252 -0
  67. package/dist/auth/legacy/services/index.mjs.map +1 -0
  68. package/dist/auth/legacy/ui/miniapp/index.d.mts +10 -0
  69. package/dist/auth/legacy/ui/miniapp/index.d.ts +10 -0
  70. package/dist/auth/legacy/ui/miniapp/index.js +298 -0
  71. package/dist/auth/legacy/ui/miniapp/index.js.map +1 -0
  72. package/dist/auth/legacy/ui/miniapp/index.mjs +290 -0
  73. package/dist/auth/legacy/ui/miniapp/index.mjs.map +1 -0
  74. package/dist/auth/legacy/ui/web/index.d.mts +22 -0
  75. package/dist/auth/legacy/ui/web/index.d.ts +22 -0
  76. package/dist/auth/legacy/ui/web/index.js +899 -0
  77. package/dist/auth/legacy/ui/web/index.js.map +1 -0
  78. package/dist/auth/legacy/ui/web/index.mjs +889 -0
  79. package/dist/auth/legacy/ui/web/index.mjs.map +1 -0
  80. package/dist/auth/legacy/web/index.d.mts +5 -0
  81. package/dist/auth/legacy/web/index.d.ts +5 -0
  82. package/dist/auth/legacy/web/index.js +1107 -0
  83. package/dist/auth/legacy/web/index.js.map +1 -0
  84. package/dist/auth/legacy/web/index.mjs +1086 -0
  85. package/dist/auth/legacy/web/index.mjs.map +1 -0
  86. package/dist/auth/rn/index.d.mts +64 -0
  87. package/dist/auth/rn/index.d.ts +64 -0
  88. package/dist/auth/rn/index.js +765 -0
  89. package/dist/auth/rn/index.js.map +1 -0
  90. package/dist/auth/rn/index.mjs +754 -0
  91. package/dist/auth/rn/index.mjs.map +1 -0
  92. package/dist/base-api-client-ACKKt13v.d.mts +277 -0
  93. package/dist/base-api-client-ACKKt13v.d.ts +277 -0
  94. package/dist/boothVaultService-Cn4WPhjg.d.mts +83 -0
  95. package/dist/boothVaultService-Cn4WPhjg.d.ts +83 -0
  96. package/dist/business/index.d.mts +6 -0
  97. package/dist/business/index.d.ts +6 -0
  98. package/dist/business/index.js +1682 -0
  99. package/dist/business/index.js.map +1 -0
  100. package/dist/business/index.mjs +1675 -0
  101. package/dist/business/index.mjs.map +1 -0
  102. package/dist/calendar/index.d.mts +1325 -0
  103. package/dist/calendar/index.d.ts +1325 -0
  104. package/dist/calendar/index.js +5964 -0
  105. package/dist/calendar/index.js.map +1 -0
  106. package/dist/calendar/index.mjs +5878 -0
  107. package/dist/calendar/index.mjs.map +1 -0
  108. package/dist/components/index.d.mts +405 -0
  109. package/dist/components/index.d.ts +405 -0
  110. package/dist/components/index.js +2516 -0
  111. package/dist/components/index.js.map +1 -0
  112. package/dist/components/index.mjs +2396 -0
  113. package/dist/components/index.mjs.map +1 -0
  114. package/dist/drizzle-schema-BNhqj2AZ.d.mts +1114 -0
  115. package/dist/drizzle-schema-BNhqj2AZ.d.ts +1114 -0
  116. package/dist/festivalCard/index.d.mts +75 -0
  117. package/dist/festivalCard/index.d.ts +75 -0
  118. package/dist/festivalCard/index.js +1492 -0
  119. package/dist/festivalCard/index.js.map +1 -0
  120. package/dist/festivalCard/index.mjs +1475 -0
  121. package/dist/festivalCard/index.mjs.map +1 -0
  122. package/dist/festivalCard/server/index.d.mts +120 -0
  123. package/dist/festivalCard/server/index.d.ts +120 -0
  124. package/dist/festivalCard/server/index.js +272 -0
  125. package/dist/festivalCard/server/index.js.map +1 -0
  126. package/dist/festivalCard/server/index.mjs +265 -0
  127. package/dist/festivalCard/server/index.mjs.map +1 -0
  128. package/dist/festivalCardService-CZomuQ4E.d.mts +80 -0
  129. package/dist/festivalCardService-CZomuQ4E.d.ts +80 -0
  130. package/dist/index-1Ag7IBXN.d.ts +144 -0
  131. package/dist/index-DNKZ7-R_.d.mts +184 -0
  132. package/dist/index-DNKZ7-R_.d.ts +184 -0
  133. package/dist/index-DSel44Ke.d.mts +93 -0
  134. package/dist/index-DSel44Ke.d.ts +93 -0
  135. package/dist/index-DdeZSeTJ.d.mts +144 -0
  136. package/dist/index-DrPcMJPc.d.mts +250 -0
  137. package/dist/index-DrPcMJPc.d.ts +250 -0
  138. package/dist/index.d.mts +5333 -0
  139. package/dist/index.d.ts +5333 -0
  140. package/dist/index.js +18809 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/index.mjs +18533 -0
  143. package/dist/index.mjs.map +1 -0
  144. package/dist/mikuContest/ui/web/index.d.mts +2 -0
  145. package/dist/mikuContest/ui/web/index.d.ts +2 -0
  146. package/dist/mikuContest/ui/web/index.js +353 -0
  147. package/dist/mikuContest/ui/web/index.js.map +1 -0
  148. package/dist/mikuContest/ui/web/index.mjs +343 -0
  149. package/dist/mikuContest/ui/web/index.mjs.map +1 -0
  150. package/dist/mikuFireworks3D/index.d.mts +268 -0
  151. package/dist/mikuFireworks3D/index.d.ts +268 -0
  152. package/dist/mikuFireworks3D/index.js +1267 -0
  153. package/dist/mikuFireworks3D/index.js.map +1 -0
  154. package/dist/mikuFireworks3D/index.mjs +1228 -0
  155. package/dist/mikuFireworks3D/index.mjs.map +1 -0
  156. package/dist/mikuFusionGame/index.d.mts +117 -0
  157. package/dist/mikuFusionGame/index.d.ts +117 -0
  158. package/dist/mikuFusionGame/index.js +1208 -0
  159. package/dist/mikuFusionGame/index.js.map +1 -0
  160. package/dist/mikuFusionGame/index.mjs +1195 -0
  161. package/dist/mikuFusionGame/index.mjs.map +1 -0
  162. package/dist/mmd/admin/index.d.mts +487 -0
  163. package/dist/mmd/admin/index.d.ts +487 -0
  164. package/dist/mmd/admin/index.js +1058 -0
  165. package/dist/mmd/admin/index.js.map +1 -0
  166. package/dist/mmd/admin/index.mjs +1027 -0
  167. package/dist/mmd/admin/index.mjs.map +1 -0
  168. package/dist/mmd/index.d.mts +2467 -0
  169. package/dist/mmd/index.d.ts +2467 -0
  170. package/dist/mmd/index.js +10119 -0
  171. package/dist/mmd/index.js.map +1 -0
  172. package/dist/mmd/index.mjs +10028 -0
  173. package/dist/mmd/index.mjs.map +1 -0
  174. package/dist/mmd/server/index.d.mts +139 -0
  175. package/dist/mmd/server/index.d.ts +139 -0
  176. package/dist/mmd/server/index.js +424 -0
  177. package/dist/mmd/server/index.js.map +1 -0
  178. package/dist/mmd/server/index.mjs +404 -0
  179. package/dist/mmd/server/index.mjs.map +1 -0
  180. package/dist/music/index.d.mts +74 -0
  181. package/dist/music/index.d.ts +74 -0
  182. package/dist/music/index.js +830 -0
  183. package/dist/music/index.js.map +1 -0
  184. package/dist/music/index.mjs +809 -0
  185. package/dist/music/index.mjs.map +1 -0
  186. package/dist/music/server/index.d.mts +1 -0
  187. package/dist/music/server/index.d.ts +1 -0
  188. package/dist/music/server/index.js +194 -0
  189. package/dist/music/server/index.js.map +1 -0
  190. package/dist/music/server/index.mjs +182 -0
  191. package/dist/music/server/index.mjs.map +1 -0
  192. package/dist/navigation/index.d.mts +93 -0
  193. package/dist/navigation/index.d.ts +93 -0
  194. package/dist/navigation/index.js +453 -0
  195. package/dist/navigation/index.js.map +1 -0
  196. package/dist/navigation/index.mjs +443 -0
  197. package/dist/navigation/index.mjs.map +1 -0
  198. package/dist/portfolio/index.d.mts +66 -0
  199. package/dist/portfolio/index.d.ts +66 -0
  200. package/dist/portfolio/index.js +736 -0
  201. package/dist/portfolio/index.js.map +1 -0
  202. package/dist/portfolio/index.mjs +724 -0
  203. package/dist/portfolio/index.mjs.map +1 -0
  204. package/dist/qqbot/server/index.d.mts +216 -0
  205. package/dist/qqbot/server/index.d.ts +216 -0
  206. package/dist/qqbot/server/index.js +394 -0
  207. package/dist/qqbot/server/index.js.map +1 -0
  208. package/dist/qqbot/server/index.mjs +385 -0
  209. package/dist/qqbot/server/index.mjs.map +1 -0
  210. package/dist/qqbot/ui/web/index.d.mts +10 -0
  211. package/dist/qqbot/ui/web/index.d.ts +10 -0
  212. package/dist/qqbot/ui/web/index.js +105 -0
  213. package/dist/qqbot/ui/web/index.js.map +1 -0
  214. package/dist/qqbot/ui/web/index.mjs +99 -0
  215. package/dist/qqbot/ui/web/index.mjs.map +1 -0
  216. package/dist/screenReceiver/index.d.mts +86 -0
  217. package/dist/screenReceiver/index.d.ts +86 -0
  218. package/dist/screenReceiver/index.js +281 -0
  219. package/dist/screenReceiver/index.js.map +1 -0
  220. package/dist/screenReceiver/index.mjs +273 -0
  221. package/dist/screenReceiver/index.mjs.map +1 -0
  222. package/dist/testYourself/admin/index.d.mts +58 -0
  223. package/dist/testYourself/admin/index.d.ts +58 -0
  224. package/dist/testYourself/admin/index.js +1009 -0
  225. package/dist/testYourself/admin/index.js.map +1 -0
  226. package/dist/testYourself/admin/index.mjs +1002 -0
  227. package/dist/testYourself/admin/index.mjs.map +1 -0
  228. package/dist/testYourself/index.d.mts +53 -0
  229. package/dist/testYourself/index.d.ts +53 -0
  230. package/dist/testYourself/index.js +2551 -0
  231. package/dist/testYourself/index.js.map +1 -0
  232. package/dist/testYourself/index.mjs +2531 -0
  233. package/dist/testYourself/index.mjs.map +1 -0
  234. package/dist/testYourself/server/index.d.mts +1029 -0
  235. package/dist/testYourself/server/index.d.ts +1029 -0
  236. package/dist/testYourself/server/index.js +825 -0
  237. package/dist/testYourself/server/index.js.map +1 -0
  238. package/dist/testYourself/server/index.mjs +816 -0
  239. package/dist/testYourself/server/index.mjs.map +1 -0
  240. package/dist/types-BTiaMsBz.d.mts +292 -0
  241. package/dist/types-DyG3ZV9V.d.mts +270 -0
  242. package/dist/types-DyG3ZV9V.d.ts +270 -0
  243. package/dist/types-ERmJyjx8.d.ts +292 -0
  244. package/dist/types-HorDyIRv.d.mts +303 -0
  245. package/dist/types-HorDyIRv.d.ts +303 -0
  246. package/dist/vocaloidBooth/index.d.mts +64 -0
  247. package/dist/vocaloidBooth/index.d.ts +64 -0
  248. package/dist/vocaloidBooth/index.js +376 -0
  249. package/dist/vocaloidBooth/index.js.map +1 -0
  250. package/dist/vocaloidBooth/index.mjs +362 -0
  251. package/dist/vocaloidBooth/index.mjs.map +1 -0
  252. package/dist/vocaloidBooth/server/index.d.mts +111 -0
  253. package/dist/vocaloidBooth/server/index.d.ts +111 -0
  254. package/dist/vocaloidBooth/server/index.js +247 -0
  255. package/dist/vocaloidBooth/server/index.js.map +1 -0
  256. package/dist/vocaloidBooth/server/index.mjs +237 -0
  257. package/dist/vocaloidBooth/server/index.mjs.map +1 -0
  258. package/dist/vocaloidBooth/web/index.d.mts +3 -0
  259. package/dist/vocaloidBooth/web/index.d.ts +3 -0
  260. package/dist/vocaloidBooth/web/index.js +376 -0
  261. package/dist/vocaloidBooth/web/index.js.map +1 -0
  262. package/dist/vocaloidBooth/web/index.mjs +362 -0
  263. package/dist/vocaloidBooth/web/index.mjs.map +1 -0
  264. package/package.json +1 -1
@@ -0,0 +1,2516 @@
1
+ 'use strict';
2
+
3
+ var React10 = require('react');
4
+ var classVarianceAuthority = require('class-variance-authority');
5
+ var clsx = require('clsx');
6
+ var tailwindMerge = require('tailwind-merge');
7
+ var reactDom = require('react-dom');
8
+ var lucideReact = require('lucide-react');
9
+ var navigation = require('next/navigation');
10
+
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
23
+ });
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+
29
+ var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
30
+
31
+ // src/components/Button.tsx
32
+
33
+ // src/logger/console-adapter.ts
34
+ var ConsoleLoggerAdapter = class {
35
+ constructor() {
36
+ this.colors = {
37
+ DEBUG: "\x1B[36m",
38
+ // Cyan
39
+ INFO: "\x1B[32m",
40
+ // Green
41
+ WARN: "\x1B[33m",
42
+ // Yellow
43
+ ERROR: "\x1B[31m",
44
+ // Red
45
+ RESET: "\x1B[0m"
46
+ };
47
+ }
48
+ log(entry) {
49
+ const { level, message, timestamp, data, context, error } = entry;
50
+ let logMessage = "";
51
+ if (timestamp) {
52
+ logMessage += "[" + this.formatTimestamp(timestamp) + "] ";
53
+ }
54
+ const levelName = this.getLevelName(level);
55
+ logMessage += levelName + ": ";
56
+ if (context) {
57
+ logMessage += "[" + context + "] ";
58
+ }
59
+ logMessage += message;
60
+ switch (level) {
61
+ case 0:
62
+ console.debug(this.colorize(logMessage, "DEBUG"), data || "");
63
+ break;
64
+ case 1:
65
+ console.info(this.colorize(logMessage, "INFO"), data || "");
66
+ break;
67
+ case 2:
68
+ console.warn(this.colorize(logMessage, "WARN"), data || "");
69
+ break;
70
+ case 3:
71
+ console.error(this.colorize(logMessage, "ERROR"), data || "");
72
+ if (error) {
73
+ console.error(error);
74
+ }
75
+ break;
76
+ }
77
+ }
78
+ formatTimestamp(date) {
79
+ return date.toISOString();
80
+ }
81
+ getLevelName(level) {
82
+ const names = ["DEBUG", "INFO", "WARN", "ERROR", "NONE"];
83
+ return names[level] || "UNKNOWN";
84
+ }
85
+ colorize(message, level) {
86
+ if (typeof process !== "undefined" && process.stdout?.isTTY) {
87
+ return this.colors[level] + message + this.colors.RESET;
88
+ }
89
+ return message;
90
+ }
91
+ };
92
+
93
+ // src/logger/Logger.ts
94
+ var Logger = class _Logger {
95
+ constructor(config, context) {
96
+ const isProduction = typeof process !== "undefined" ? process.env.NODE_ENV === "production" : false;
97
+ this.config = {
98
+ minLevel: config?.minLevel ?? (isProduction ? 1 : 0),
99
+ // INFO in prod, DEBUG in dev
100
+ enableTimestamp: config?.enableTimestamp ?? true,
101
+ enableContext: config?.enableContext ?? true,
102
+ environment: config?.environment ?? (isProduction ? "production" : "development"),
103
+ adapter: config?.adapter ?? new ConsoleLoggerAdapter()
104
+ };
105
+ this.adapter = this.config.adapter;
106
+ this.context = context;
107
+ }
108
+ /**
109
+ * 创建带上下文的子 Logger
110
+ */
111
+ createChild(context) {
112
+ return new _Logger(this.config, context);
113
+ }
114
+ /**
115
+ * 调试日志
116
+ */
117
+ debug(message, data) {
118
+ this.log(0, message, data);
119
+ }
120
+ /**
121
+ * 信息日志
122
+ */
123
+ info(message, data) {
124
+ this.log(1, message, data);
125
+ }
126
+ /**
127
+ * 警告日志
128
+ */
129
+ warn(message, data) {
130
+ this.log(2, message, data);
131
+ }
132
+ /**
133
+ * 错误日志
134
+ */
135
+ error(message, error) {
136
+ this.log(
137
+ 3,
138
+ // LogLevel.ERROR
139
+ message,
140
+ error instanceof Error ? void 0 : error,
141
+ error instanceof Error ? error : void 0
142
+ );
143
+ }
144
+ /**
145
+ * 核心日志方法
146
+ */
147
+ log(level, message, data, error) {
148
+ if (level < this.config.minLevel) {
149
+ return;
150
+ }
151
+ if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
152
+ const loggerDebug = localStorage.getItem("logger-debug");
153
+ if (loggerDebug === "false" && level < 3) {
154
+ return;
155
+ }
156
+ }
157
+ const entry = {
158
+ level,
159
+ message,
160
+ timestamp: this.config.enableTimestamp ? /* @__PURE__ */ new Date() : void 0,
161
+ data,
162
+ context: this.config.enableContext ? this.context : void 0,
163
+ error
164
+ };
165
+ this.adapter.log(entry);
166
+ }
167
+ /**
168
+ * 设置日志级别
169
+ */
170
+ setLevel(level) {
171
+ this.config.minLevel = level;
172
+ }
173
+ /**
174
+ * 获取当前日志级别
175
+ */
176
+ getLevel() {
177
+ return this.config.minLevel;
178
+ }
179
+ };
180
+ new Logger();
181
+ function cn(...inputs) {
182
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
183
+ }
184
+
185
+ // src/components/Button.tsx
186
+ var buttonVariants = classVarianceAuthority.cva(
187
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
188
+ {
189
+ variants: {
190
+ variant: {
191
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
192
+ destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
193
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
194
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
195
+ ghost: "hover:bg-accent hover:text-accent-foreground",
196
+ link: "text-primary underline-offset-4 hover:underline"
197
+ },
198
+ size: {
199
+ default: "h-9 px-4 py-2",
200
+ sm: "h-8 rounded-md px-3 text-xs",
201
+ lg: "h-10 rounded-md px-8",
202
+ icon: "h-9 w-9"
203
+ }
204
+ },
205
+ defaultVariants: {
206
+ variant: "default",
207
+ size: "default"
208
+ }
209
+ }
210
+ );
211
+ var Button = React10__namespace.forwardRef(
212
+ ({ className, variant = "default", size = "default", asChild = false, children, ...props }, ref) => {
213
+ if (asChild && React10__namespace.isValidElement(children)) {
214
+ const childProps = children.props;
215
+ return React10__namespace.cloneElement(children, {
216
+ ...props,
217
+ className: cn(buttonVariants({ variant, size, className }), childProps.className)
218
+ });
219
+ }
220
+ return /* @__PURE__ */ React10__namespace.createElement(
221
+ "button",
222
+ {
223
+ className: cn(buttonVariants({ variant, size, className })),
224
+ ref,
225
+ ...props
226
+ },
227
+ children
228
+ );
229
+ }
230
+ );
231
+ Button.displayName = "Button";
232
+ var Card = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
233
+ "div",
234
+ {
235
+ ref,
236
+ className: cn(
237
+ "rounded-xl border bg-card text-card-foreground shadow",
238
+ className
239
+ ),
240
+ ...props
241
+ }
242
+ ));
243
+ Card.displayName = "Card";
244
+ var CardHeader = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
245
+ "div",
246
+ {
247
+ ref,
248
+ className: cn("flex flex-col space-y-1.5 p-6", className),
249
+ ...props
250
+ }
251
+ ));
252
+ CardHeader.displayName = "CardHeader";
253
+ var CardTitle = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
254
+ "div",
255
+ {
256
+ ref,
257
+ className: cn("font-semibold leading-none tracking-tight", className),
258
+ ...props
259
+ }
260
+ ));
261
+ CardTitle.displayName = "CardTitle";
262
+ var CardDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
263
+ "div",
264
+ {
265
+ ref,
266
+ className: cn("text-sm text-muted-foreground", className),
267
+ ...props
268
+ }
269
+ ));
270
+ CardDescription.displayName = "CardDescription";
271
+ var CardContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement("div", { ref, className: cn("p-6 pt-0", className), ...props }));
272
+ CardContent.displayName = "CardContent";
273
+ var CardFooter = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
274
+ "div",
275
+ {
276
+ ref,
277
+ className: cn("flex items-center p-6 pt-0", className),
278
+ ...props
279
+ }
280
+ ));
281
+ CardFooter.displayName = "CardFooter";
282
+ var badgeVariants = classVarianceAuthority.cva(
283
+ "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
284
+ {
285
+ variants: {
286
+ variant: {
287
+ default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
288
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
289
+ destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
290
+ outline: "text-foreground"
291
+ }
292
+ },
293
+ defaultVariants: {
294
+ variant: "default"
295
+ }
296
+ }
297
+ );
298
+ function Badge({ className, variant, ...props }) {
299
+ return /* @__PURE__ */ React10__namespace.createElement("div", { className: cn(badgeVariants({ variant }), className), ...props });
300
+ }
301
+ var Input = React10__namespace.forwardRef(
302
+ ({ className, type, ...props }, ref) => {
303
+ return /* @__PURE__ */ React10__namespace.createElement(
304
+ "input",
305
+ {
306
+ type,
307
+ className: cn(
308
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
309
+ className
310
+ ),
311
+ ref,
312
+ ...props
313
+ }
314
+ );
315
+ }
316
+ );
317
+ Input.displayName = "Input";
318
+ var labelVariants = classVarianceAuthority.cva(
319
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
320
+ );
321
+ var Label = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
322
+ "label",
323
+ {
324
+ ref,
325
+ className: cn(labelVariants(), className),
326
+ ...props
327
+ }
328
+ ));
329
+ Label.displayName = "Label";
330
+ function useControllableState({
331
+ value,
332
+ defaultValue,
333
+ onChange
334
+ }) {
335
+ const [internal, setInternal] = React10__namespace.useState(defaultValue);
336
+ const isControlled = value !== void 0;
337
+ const state = isControlled ? value : internal;
338
+ const setState = React10__namespace.useCallback(
339
+ (next) => {
340
+ if (!isControlled) setInternal(next);
341
+ onChange?.(next);
342
+ },
343
+ [isControlled, onChange]
344
+ );
345
+ return [state, setState];
346
+ }
347
+ function Portal({
348
+ children,
349
+ container
350
+ }) {
351
+ const [mounted, setMounted] = React10__namespace.useState(false);
352
+ React10__namespace.useEffect(() => {
353
+ setMounted(true);
354
+ }, []);
355
+ if (!mounted) return null;
356
+ return reactDom.createPortal(children, container ?? document.body);
357
+ }
358
+ function useOnClickOutside(refs, handler, enabled) {
359
+ React10__namespace.useEffect(() => {
360
+ if (!enabled) return;
361
+ const listener = (event) => {
362
+ const target = event.target;
363
+ const clickedInside = refs.some((ref) => {
364
+ const el = ref.current;
365
+ return el && el.contains(target);
366
+ });
367
+ if (!clickedInside) {
368
+ handler(event);
369
+ }
370
+ };
371
+ document.addEventListener("mousedown", listener);
372
+ document.addEventListener("touchstart", listener);
373
+ return () => {
374
+ document.removeEventListener("mousedown", listener);
375
+ document.removeEventListener("touchstart", listener);
376
+ };
377
+ }, [refs, handler, enabled]);
378
+ }
379
+ function mergeRefs(...refs) {
380
+ return (value) => {
381
+ refs.forEach((ref) => {
382
+ if (!ref) return;
383
+ if (typeof ref === "function") {
384
+ ref(value);
385
+ } else {
386
+ ref.current = value;
387
+ }
388
+ });
389
+ };
390
+ }
391
+
392
+ // src/components/Tabs.tsx
393
+ var TabsContext = React10__namespace.createContext(null);
394
+ var Tabs = ({
395
+ value,
396
+ defaultValue = "",
397
+ onValueChange,
398
+ className,
399
+ ...props
400
+ }) => {
401
+ const [current, setCurrent] = useControllableState({
402
+ value,
403
+ defaultValue,
404
+ onChange: onValueChange
405
+ });
406
+ return /* @__PURE__ */ React10__namespace.createElement(TabsContext.Provider, { value: { value: current, setValue: setCurrent } }, /* @__PURE__ */ React10__namespace.createElement("div", { className, ...props }));
407
+ };
408
+ var TabsList = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
409
+ "div",
410
+ {
411
+ ref,
412
+ className: cn(
413
+ "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
414
+ className
415
+ ),
416
+ ...props
417
+ }
418
+ ));
419
+ TabsList.displayName = "TabsList";
420
+ var TabsTrigger = React10__namespace.forwardRef(
421
+ ({ className, value, onClick, ...props }, ref) => {
422
+ const ctx = React10__namespace.useContext(TabsContext);
423
+ const active = ctx?.value === value;
424
+ return /* @__PURE__ */ React10__namespace.createElement(
425
+ "button",
426
+ {
427
+ ref,
428
+ type: "button",
429
+ "data-state": active ? "active" : "inactive",
430
+ className: cn(
431
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
432
+ active && "bg-background text-foreground shadow",
433
+ className
434
+ ),
435
+ onClick: (e) => {
436
+ ctx?.setValue(value);
437
+ onClick?.(e);
438
+ },
439
+ ...props
440
+ }
441
+ );
442
+ }
443
+ );
444
+ TabsTrigger.displayName = "TabsTrigger";
445
+ var TabsContent = React10__namespace.forwardRef(
446
+ ({ className, value, forceMount = false, ...props }, ref) => {
447
+ const ctx = React10__namespace.useContext(TabsContext);
448
+ const active = ctx?.value === value;
449
+ if (!active && !forceMount) return null;
450
+ return /* @__PURE__ */ React10__namespace.createElement(
451
+ "div",
452
+ {
453
+ ref,
454
+ "data-state": active ? "active" : "inactive",
455
+ hidden: !active && forceMount,
456
+ className: cn(
457
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
458
+ className
459
+ ),
460
+ ...props
461
+ }
462
+ );
463
+ }
464
+ );
465
+ TabsContent.displayName = "TabsContent";
466
+ var DialogContext = React10__namespace.createContext(null);
467
+ var Dialog = ({ open, defaultOpen = false, onOpenChange, children }) => {
468
+ const [isOpen, setIsOpen] = useControllableState({
469
+ value: open,
470
+ defaultValue: defaultOpen,
471
+ onChange: onOpenChange
472
+ });
473
+ const triggerRef = React10__namespace.useRef(null);
474
+ const contentRef = React10__namespace.useRef(null);
475
+ return /* @__PURE__ */ React10__namespace.createElement(DialogContext.Provider, { value: { open: isOpen, setOpen: setIsOpen, triggerRef, contentRef } }, children);
476
+ };
477
+ var DialogTrigger = React10__namespace.forwardRef(
478
+ ({ children, onClick, ...props }, ref) => {
479
+ const ctx = React10__namespace.useContext(DialogContext);
480
+ if (!ctx) return null;
481
+ const mergedRef = mergeRefs(ctx.triggerRef, ref);
482
+ const handleClick = (e) => {
483
+ ctx.setOpen(true);
484
+ onClick?.(e);
485
+ };
486
+ return /* @__PURE__ */ React10__namespace.createElement("button", { ref: mergedRef, type: "button", onClick: handleClick, ...props }, children);
487
+ }
488
+ );
489
+ DialogTrigger.displayName = "DialogTrigger";
490
+ var DialogPortal = ({ children }) => {
491
+ const ctx = React10__namespace.useContext(DialogContext);
492
+ if (!ctx?.open) return null;
493
+ return /* @__PURE__ */ React10__namespace.createElement(Portal, null, children);
494
+ };
495
+ var DialogClose = React10__namespace.forwardRef(({ onClick, ...props }, ref) => {
496
+ const ctx = React10__namespace.useContext(DialogContext);
497
+ return /* @__PURE__ */ React10__namespace.createElement(
498
+ "button",
499
+ {
500
+ ref,
501
+ type: "button",
502
+ onClick: (e) => {
503
+ ctx?.setOpen(false);
504
+ onClick?.(e);
505
+ },
506
+ ...props
507
+ }
508
+ );
509
+ });
510
+ DialogClose.displayName = "DialogClose";
511
+ var DialogOverlay = React10__namespace.forwardRef(({ className, ...props }, ref) => {
512
+ const ctx = React10__namespace.useContext(DialogContext);
513
+ if (!ctx?.open) return null;
514
+ return /* @__PURE__ */ React10__namespace.createElement(
515
+ "div",
516
+ {
517
+ ref,
518
+ className: cn("fixed inset-0 z-[9999] bg-black/80", className),
519
+ ...props
520
+ }
521
+ );
522
+ });
523
+ DialogOverlay.displayName = "DialogOverlay";
524
+ var DialogContent = React10__namespace.forwardRef(
525
+ ({ className, children, onPointerDownOutside, onEscapeKeyDown, showCloseButton = true, overlayClassName, ...props }, ref) => {
526
+ const ctx = React10__namespace.useContext(DialogContext);
527
+ const open = !!ctx?.open;
528
+ useOnClickOutside(
529
+ [ctx?.contentRef ?? { current: null }, ctx?.triggerRef ?? { current: null }],
530
+ (evt) => {
531
+ onPointerDownOutside?.(evt);
532
+ if (!evt.defaultPrevented) {
533
+ ctx?.setOpen(false);
534
+ }
535
+ },
536
+ open
537
+ );
538
+ React10__namespace.useEffect(() => {
539
+ if (!open) return;
540
+ const onKey = (e) => {
541
+ if (e.key !== "Escape") return;
542
+ onEscapeKeyDown?.(e);
543
+ if (!e.defaultPrevented) {
544
+ ctx?.setOpen(false);
545
+ }
546
+ };
547
+ document.addEventListener("keydown", onKey);
548
+ return () => document.removeEventListener("keydown", onKey);
549
+ }, [ctx, onEscapeKeyDown, open]);
550
+ if (!ctx || !open) return null;
551
+ return /* @__PURE__ */ React10__namespace.createElement(DialogPortal, null, /* @__PURE__ */ React10__namespace.createElement(DialogOverlay, { className: overlayClassName }), /* @__PURE__ */ React10__namespace.createElement(
552
+ "div",
553
+ {
554
+ ref: mergeRefs(ctx.contentRef, ref),
555
+ className: cn(
556
+ "fixed left-[50%] top-[50%] z-[10000] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg",
557
+ className
558
+ ),
559
+ ...props
560
+ },
561
+ children,
562
+ showCloseButton ? /* @__PURE__ */ React10__namespace.createElement(DialogClose, { className: "absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100" }, /* @__PURE__ */ React10__namespace.createElement(lucideReact.X, { className: "h-4 w-4" }), /* @__PURE__ */ React10__namespace.createElement("span", { className: "sr-only" }, "Close")) : null
563
+ ));
564
+ }
565
+ );
566
+ DialogContent.displayName = "DialogContent";
567
+ var DialogHeader = ({
568
+ className,
569
+ ...props
570
+ }) => /* @__PURE__ */ React10__namespace.createElement(
571
+ "div",
572
+ {
573
+ className: cn(
574
+ "flex flex-col space-y-1.5 text-center sm:text-left",
575
+ className
576
+ ),
577
+ ...props
578
+ }
579
+ );
580
+ DialogHeader.displayName = "DialogHeader";
581
+ var DialogFooter = ({
582
+ className,
583
+ ...props
584
+ }) => /* @__PURE__ */ React10__namespace.createElement(
585
+ "div",
586
+ {
587
+ className: cn(
588
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
589
+ className
590
+ ),
591
+ ...props
592
+ }
593
+ );
594
+ DialogFooter.displayName = "DialogFooter";
595
+ var DialogTitle = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
596
+ "h2",
597
+ {
598
+ ref,
599
+ className: cn(
600
+ "text-lg font-semibold leading-none tracking-tight",
601
+ className
602
+ ),
603
+ ...props
604
+ }
605
+ ));
606
+ DialogTitle.displayName = "DialogTitle";
607
+ var DialogDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
608
+ "p",
609
+ {
610
+ ref,
611
+ className: cn("text-sm text-muted-foreground", className),
612
+ ...props
613
+ }
614
+ ));
615
+ DialogDescription.displayName = "DialogDescription";
616
+ var AlertDialogContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
617
+ DialogContent,
618
+ {
619
+ ref,
620
+ className: cn("z-[9999]", className),
621
+ ...props
622
+ }
623
+ ));
624
+ AlertDialogContent.displayName = "AlertDialogContent";
625
+ var AlertDialogAction = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
626
+ DialogClose,
627
+ {
628
+ ref,
629
+ className: cn(buttonVariants(), className),
630
+ ...props
631
+ }
632
+ ));
633
+ AlertDialogAction.displayName = "AlertDialogAction";
634
+ var AlertDialogCancel = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
635
+ DialogClose,
636
+ {
637
+ ref,
638
+ className: cn(
639
+ buttonVariants({ variant: "outline" }),
640
+ "mt-2 sm:mt-0",
641
+ className
642
+ ),
643
+ ...props
644
+ }
645
+ ));
646
+ AlertDialogCancel.displayName = "AlertDialogCancel";
647
+ var DropdownMenuContext = React10__namespace.createContext(null);
648
+ var DropdownMenuRadioGroupContext = React10__namespace.createContext(null);
649
+ var DropdownMenu = ({ open, defaultOpen = false, onOpenChange, children }) => {
650
+ const [isOpen, setIsOpen] = useControllableState({
651
+ value: open,
652
+ defaultValue: defaultOpen,
653
+ onChange: onOpenChange
654
+ });
655
+ const triggerRef = React10__namespace.useRef(null);
656
+ const contentRef = React10__namespace.useRef(null);
657
+ return /* @__PURE__ */ React10__namespace.createElement(DropdownMenuContext.Provider, { value: { open: isOpen, setOpen: setIsOpen, triggerRef, contentRef } }, children);
658
+ };
659
+ var DropdownMenuTrigger = React10__namespace.forwardRef(({ children, onClick, ...props }, ref) => {
660
+ const ctx = React10__namespace.useContext(DropdownMenuContext);
661
+ if (!ctx) return null;
662
+ const mergedRef = mergeRefs(ctx.triggerRef, ref);
663
+ const handleClick = (e) => {
664
+ ctx.setOpen(!ctx.open);
665
+ onClick?.(e);
666
+ };
667
+ return /* @__PURE__ */ React10__namespace.createElement("button", { ref: mergedRef, type: "button", onClick: handleClick, ...props }, children);
668
+ });
669
+ DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
670
+ var DropdownMenuGroup = ({ children }) => /* @__PURE__ */ React10__namespace.createElement(React10__namespace.Fragment, null, children);
671
+ var DropdownMenuPortal = ({ children }) => /* @__PURE__ */ React10__namespace.createElement(Portal, null, children);
672
+ var DropdownMenuSub = ({ children }) => /* @__PURE__ */ React10__namespace.createElement(React10__namespace.Fragment, null, children);
673
+ var DropdownMenuContent = React10__namespace.forwardRef(({ className, sideOffset = 4, style, ...props }, ref) => {
674
+ const ctx = React10__namespace.useContext(DropdownMenuContext);
675
+ const [pos, setPos] = React10__namespace.useState({ top: 0, left: 0 });
676
+ const open = !!ctx?.open;
677
+ const trigger = ctx?.triggerRef.current ?? null;
678
+ React10__namespace.useLayoutEffect(() => {
679
+ if (!trigger) return;
680
+ const rect = trigger.getBoundingClientRect();
681
+ setPos({ top: rect.bottom + sideOffset, left: rect.left });
682
+ }, [trigger, sideOffset]);
683
+ useOnClickOutside(
684
+ [ctx?.contentRef ?? { current: null }, ctx?.triggerRef ?? { current: null }],
685
+ () => ctx?.setOpen(false),
686
+ open
687
+ );
688
+ if (!ctx || !open || !trigger) return null;
689
+ return /* @__PURE__ */ React10__namespace.createElement(DropdownMenuPortal, null, /* @__PURE__ */ React10__namespace.createElement(
690
+ "div",
691
+ {
692
+ ref: mergeRefs(ctx.contentRef, ref),
693
+ className: cn(
694
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
695
+ className
696
+ ),
697
+ style: { position: "fixed", top: pos.top, left: pos.left, ...style },
698
+ ...props
699
+ }
700
+ ));
701
+ });
702
+ DropdownMenuContent.displayName = "DropdownMenuContent";
703
+ var DropdownMenuItem = React10__namespace.forwardRef(({ className, inset, onSelect, onClick, ...props }, ref) => {
704
+ const ctx = React10__namespace.useContext(DropdownMenuContext);
705
+ return /* @__PURE__ */ React10__namespace.createElement(
706
+ "button",
707
+ {
708
+ ref,
709
+ type: "button",
710
+ className: cn(
711
+ "relative flex w-full cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
712
+ inset && "pl-8",
713
+ className
714
+ ),
715
+ onClick: (e) => {
716
+ onSelect?.(e.nativeEvent);
717
+ onClick?.(e);
718
+ if (!e.isDefaultPrevented()) {
719
+ ctx?.setOpen(false);
720
+ }
721
+ },
722
+ ...props
723
+ }
724
+ );
725
+ });
726
+ DropdownMenuItem.displayName = "DropdownMenuItem";
727
+ var DropdownMenuCheckboxItem = React10__namespace.forwardRef(({ className, children, checked = false, onCheckedChange, onClick, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
728
+ "button",
729
+ {
730
+ ref,
731
+ type: "button",
732
+ className: cn(
733
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
734
+ className
735
+ ),
736
+ onClick: (e) => {
737
+ onCheckedChange?.(!checked);
738
+ onClick?.(e);
739
+ },
740
+ ...props
741
+ },
742
+ /* @__PURE__ */ React10__namespace.createElement("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center" }, checked ? /* @__PURE__ */ React10__namespace.createElement(lucideReact.Check, { className: "h-4 w-4" }) : null),
743
+ children
744
+ ));
745
+ DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
746
+ var DropdownMenuRadioGroup = ({
747
+ value,
748
+ onValueChange,
749
+ children
750
+ }) => /* @__PURE__ */ React10__namespace.createElement(DropdownMenuRadioGroupContext.Provider, { value: { value, onValueChange } }, children);
751
+ var DropdownMenuRadioItem = React10__namespace.forwardRef(({ className, children, value, onClick, ...props }, ref) => {
752
+ const radioCtx = React10__namespace.useContext(DropdownMenuRadioGroupContext);
753
+ const menuCtx = React10__namespace.useContext(DropdownMenuContext);
754
+ const checked = radioCtx?.value === value;
755
+ return /* @__PURE__ */ React10__namespace.createElement(
756
+ "button",
757
+ {
758
+ ref,
759
+ type: "button",
760
+ className: cn(
761
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
762
+ className
763
+ ),
764
+ onClick: (e) => {
765
+ radioCtx?.onValueChange?.(value);
766
+ onClick?.(e);
767
+ menuCtx?.setOpen(false);
768
+ },
769
+ ...props
770
+ },
771
+ /* @__PURE__ */ React10__namespace.createElement("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center" }, checked ? /* @__PURE__ */ React10__namespace.createElement(lucideReact.Circle, { className: "h-2 w-2 fill-current" }) : null),
772
+ children
773
+ );
774
+ });
775
+ DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
776
+ var DropdownMenuLabel = React10__namespace.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
777
+ "div",
778
+ {
779
+ ref,
780
+ className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
781
+ ...props
782
+ }
783
+ ));
784
+ DropdownMenuLabel.displayName = "DropdownMenuLabel";
785
+ var DropdownMenuSeparator = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
786
+ "div",
787
+ {
788
+ ref,
789
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
790
+ ...props
791
+ }
792
+ ));
793
+ DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
794
+ var DropdownMenuShortcut = ({
795
+ className,
796
+ ...props
797
+ }) => /* @__PURE__ */ React10__namespace.createElement(
798
+ "span",
799
+ {
800
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
801
+ ...props
802
+ }
803
+ );
804
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
805
+ var DropdownMenuSubTrigger = React10__namespace.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
806
+ "button",
807
+ {
808
+ ref,
809
+ type: "button",
810
+ className: cn(
811
+ "flex w-full cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent",
812
+ inset && "pl-8",
813
+ className
814
+ ),
815
+ ...props
816
+ },
817
+ children,
818
+ /* @__PURE__ */ React10__namespace.createElement(lucideReact.ChevronRight, { className: "ml-auto" })
819
+ ));
820
+ DropdownMenuSubTrigger.displayName = "DropdownMenuSubTrigger";
821
+ var DropdownMenuSubContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
822
+ "div",
823
+ {
824
+ ref,
825
+ className: cn(
826
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg",
827
+ className
828
+ ),
829
+ ...props
830
+ }
831
+ ));
832
+ DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
833
+ var PopoverContext = React10__namespace.createContext(null);
834
+ var Popover = ({ open, defaultOpen = false, onOpenChange, children }) => {
835
+ const [isOpen, setIsOpen] = useControllableState({
836
+ value: open,
837
+ defaultValue: defaultOpen,
838
+ onChange: onOpenChange
839
+ });
840
+ const triggerRef = React10__namespace.useRef(null);
841
+ const anchorRef = React10__namespace.useRef(null);
842
+ const contentRef = React10__namespace.useRef(null);
843
+ return /* @__PURE__ */ React10__namespace.createElement(PopoverContext.Provider, { value: { open: isOpen, setOpen: setIsOpen, triggerRef, anchorRef, contentRef } }, children);
844
+ };
845
+ var PopoverTrigger = React10__namespace.forwardRef(
846
+ ({ children, onClick, ...props }, ref) => {
847
+ const ctx = React10__namespace.useContext(PopoverContext);
848
+ if (!ctx) return null;
849
+ const mergedRef = mergeRefs(ctx.triggerRef, ref);
850
+ const handleClick = (e) => {
851
+ ctx.setOpen(!ctx.open);
852
+ onClick?.(e);
853
+ };
854
+ return /* @__PURE__ */ React10__namespace.createElement("button", { ref: mergedRef, type: "button", onClick: handleClick, ...props }, children);
855
+ }
856
+ );
857
+ PopoverTrigger.displayName = "PopoverTrigger";
858
+ var PopoverAnchor = React10__namespace.forwardRef(
859
+ ({ ...props }, ref) => {
860
+ const ctx = React10__namespace.useContext(PopoverContext);
861
+ if (!ctx) return null;
862
+ return /* @__PURE__ */ React10__namespace.createElement("span", { ref: mergeRefs(ctx.anchorRef, ref), ...props });
863
+ }
864
+ );
865
+ PopoverAnchor.displayName = "PopoverAnchor";
866
+ var PopoverContent = React10__namespace.forwardRef(
867
+ ({ className, align = "center", sideOffset = 4, style, ...props }, ref) => {
868
+ const ctx = React10__namespace.useContext(PopoverContext);
869
+ const [position, setPosition] = React10__namespace.useState({ top: 0, left: 0 });
870
+ const open = !!ctx?.open;
871
+ const anchor = ctx?.anchorRef.current ?? ctx?.triggerRef.current ?? null;
872
+ React10__namespace.useLayoutEffect(() => {
873
+ if (!anchor) return;
874
+ const rect = anchor.getBoundingClientRect();
875
+ let left = rect.left + rect.width / 2;
876
+ if (align === "start") left = rect.left;
877
+ if (align === "end") left = rect.right;
878
+ setPosition({ top: rect.bottom + sideOffset, left });
879
+ }, [anchor, align, sideOffset]);
880
+ useOnClickOutside(
881
+ [ctx?.contentRef ?? { current: null }, ctx?.triggerRef ?? { current: null }],
882
+ () => ctx?.setOpen(false),
883
+ open
884
+ );
885
+ if (!ctx || !open) return null;
886
+ return /* @__PURE__ */ React10__namespace.createElement(Portal, null, /* @__PURE__ */ React10__namespace.createElement(
887
+ "div",
888
+ {
889
+ ref: mergeRefs(ctx.contentRef, ref),
890
+ className: cn(
891
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
892
+ className
893
+ ),
894
+ style: {
895
+ position: "fixed",
896
+ top: position.top,
897
+ left: position.left,
898
+ transform: align === "center" ? "translateX(-50%)" : align === "end" ? "translateX(-100%)" : void 0,
899
+ ...style
900
+ },
901
+ ...props
902
+ }
903
+ ));
904
+ }
905
+ );
906
+ PopoverContent.displayName = "PopoverContent";
907
+ var Progress = React10__namespace.forwardRef(
908
+ ({ className, value = 0, max = 100, ...props }, ref) => {
909
+ const safeMax = max <= 0 ? 100 : max;
910
+ const safeValue = Math.max(0, Math.min(value, safeMax));
911
+ const percent = safeValue / safeMax * 100;
912
+ return /* @__PURE__ */ React10__namespace.createElement(
913
+ "div",
914
+ {
915
+ ref,
916
+ role: "progressbar",
917
+ "aria-valuemin": 0,
918
+ "aria-valuemax": safeMax,
919
+ "aria-valuenow": safeValue,
920
+ className: cn(
921
+ "relative h-2 w-full overflow-hidden rounded-full bg-primary/20",
922
+ className
923
+ ),
924
+ ...props
925
+ },
926
+ /* @__PURE__ */ React10__namespace.createElement(
927
+ "div",
928
+ {
929
+ className: "h-full w-full flex-1 bg-primary transition-all",
930
+ style: { transform: `translateX(-${100 - percent}%)` }
931
+ }
932
+ )
933
+ );
934
+ }
935
+ );
936
+ Progress.displayName = "Progress";
937
+ var ScrollArea = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
938
+ "div",
939
+ {
940
+ ref,
941
+ className: cn("relative overflow-auto", className),
942
+ ...props
943
+ },
944
+ children
945
+ ));
946
+ ScrollArea.displayName = "ScrollArea";
947
+ var ScrollBar = React10__namespace.forwardRef(
948
+ ({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
949
+ "div",
950
+ {
951
+ ref,
952
+ className: cn(
953
+ "pointer-events-none absolute",
954
+ orientation === "vertical" ? "right-0 top-0 h-full w-2.5" : "bottom-0 left-0 h-2.5 w-full",
955
+ className
956
+ ),
957
+ ...props
958
+ }
959
+ )
960
+ );
961
+ ScrollBar.displayName = "ScrollBar";
962
+ var SelectContext = React10__namespace.createContext(null);
963
+ var SelectGroupContext = React10__namespace.createContext(false);
964
+ var Select = ({
965
+ value,
966
+ defaultValue,
967
+ onValueChange,
968
+ open,
969
+ defaultOpen = false,
970
+ onOpenChange,
971
+ disabled = false,
972
+ children
973
+ }) => {
974
+ const [isOpen, setIsOpen] = useControllableState({
975
+ value: open,
976
+ defaultValue: defaultOpen,
977
+ onChange: onOpenChange
978
+ });
979
+ const [currentValue, setCurrentValue] = useControllableState({
980
+ value,
981
+ defaultValue,
982
+ onChange: (next) => {
983
+ if (next !== void 0) {
984
+ onValueChange?.(next);
985
+ }
986
+ }
987
+ });
988
+ const triggerRef = React10__namespace.useRef(null);
989
+ const contentRef = React10__namespace.useRef(null);
990
+ const itemsRef = React10__namespace.useRef(/* @__PURE__ */ new Map());
991
+ return /* @__PURE__ */ React10__namespace.createElement(
992
+ SelectContext.Provider,
993
+ {
994
+ value: {
995
+ open: disabled ? false : isOpen,
996
+ setOpen: disabled ? () => void 0 : setIsOpen,
997
+ value: currentValue,
998
+ setValue: (next) => {
999
+ if (disabled) return;
1000
+ setCurrentValue(next);
1001
+ setIsOpen(false);
1002
+ },
1003
+ triggerRef,
1004
+ contentRef,
1005
+ itemsRef
1006
+ }
1007
+ },
1008
+ children
1009
+ );
1010
+ };
1011
+ var SelectGroup = ({ children }) => /* @__PURE__ */ React10__namespace.createElement(SelectGroupContext.Provider, { value: true }, children);
1012
+ var SelectValue = ({
1013
+ placeholder,
1014
+ children
1015
+ }) => {
1016
+ const ctx = React10__namespace.useContext(SelectContext);
1017
+ if (!ctx) return null;
1018
+ if (children) return /* @__PURE__ */ React10__namespace.createElement(React10__namespace.Fragment, null, children);
1019
+ if (ctx.value && ctx.itemsRef.current.has(ctx.value)) {
1020
+ return /* @__PURE__ */ React10__namespace.createElement(React10__namespace.Fragment, null, ctx.itemsRef.current.get(ctx.value));
1021
+ }
1022
+ return /* @__PURE__ */ React10__namespace.createElement("span", { className: "text-muted-foreground" }, placeholder);
1023
+ };
1024
+ var SelectTrigger = React10__namespace.forwardRef(({ className, children, onClick, ...props }, ref) => {
1025
+ const ctx = React10__namespace.useContext(SelectContext);
1026
+ if (!ctx) return null;
1027
+ return /* @__PURE__ */ React10__namespace.createElement(
1028
+ "button",
1029
+ {
1030
+ ref: mergeRefs(ctx.triggerRef, ref),
1031
+ type: "button",
1032
+ className: cn(
1033
+ "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
1034
+ className
1035
+ ),
1036
+ onClick: (e) => {
1037
+ ctx.setOpen(!ctx.open);
1038
+ onClick?.(e);
1039
+ },
1040
+ ...props
1041
+ },
1042
+ /* @__PURE__ */ React10__namespace.createElement("span", null, children),
1043
+ /* @__PURE__ */ React10__namespace.createElement(lucideReact.ChevronDown, { className: "h-4 w-4 opacity-50" })
1044
+ );
1045
+ });
1046
+ SelectTrigger.displayName = "SelectTrigger";
1047
+ var SelectScrollUpButton = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1048
+ "div",
1049
+ {
1050
+ ref,
1051
+ className: cn("flex cursor-default items-center justify-center py-1", className),
1052
+ ...props
1053
+ },
1054
+ /* @__PURE__ */ React10__namespace.createElement(lucideReact.ChevronUp, { className: "h-4 w-4" })
1055
+ ));
1056
+ SelectScrollUpButton.displayName = "SelectScrollUpButton";
1057
+ var SelectScrollDownButton = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1058
+ "div",
1059
+ {
1060
+ ref,
1061
+ className: cn("flex cursor-default items-center justify-center py-1", className),
1062
+ ...props
1063
+ },
1064
+ /* @__PURE__ */ React10__namespace.createElement(lucideReact.ChevronDown, { className: "h-4 w-4" })
1065
+ ));
1066
+ SelectScrollDownButton.displayName = "SelectScrollDownButton";
1067
+ var SelectContent = React10__namespace.forwardRef(({ className, children, style, ...props }, ref) => {
1068
+ const ctx = React10__namespace.useContext(SelectContext);
1069
+ const [pos, setPos] = React10__namespace.useState({ top: 0, left: 0, width: 0 });
1070
+ const open = !!ctx?.open;
1071
+ const trigger = ctx?.triggerRef.current ?? null;
1072
+ React10__namespace.useLayoutEffect(() => {
1073
+ if (!trigger) return;
1074
+ const rect = trigger.getBoundingClientRect();
1075
+ setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width });
1076
+ }, [trigger]);
1077
+ useOnClickOutside(
1078
+ [ctx?.contentRef ?? { current: null }, ctx?.triggerRef ?? { current: null }],
1079
+ () => ctx?.setOpen(false),
1080
+ open
1081
+ );
1082
+ if (!ctx || !open || !trigger) return null;
1083
+ return /* @__PURE__ */ React10__namespace.createElement(Portal, null, /* @__PURE__ */ React10__namespace.createElement(
1084
+ "div",
1085
+ {
1086
+ ref: mergeRefs(ctx.contentRef, ref),
1087
+ className: cn(
1088
+ "relative z-50 max-h-80 overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
1089
+ className
1090
+ ),
1091
+ style: {
1092
+ position: "fixed",
1093
+ top: pos.top,
1094
+ left: pos.left,
1095
+ minWidth: Math.max(pos.width, 128),
1096
+ ...style
1097
+ },
1098
+ ...props
1099
+ },
1100
+ /* @__PURE__ */ React10__namespace.createElement("div", { className: "p-1" }, children)
1101
+ ));
1102
+ });
1103
+ SelectContent.displayName = "SelectContent";
1104
+ var SelectLabel = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1105
+ "div",
1106
+ {
1107
+ ref,
1108
+ className: cn("px-2 py-1.5 text-sm font-semibold", className),
1109
+ ...props
1110
+ }
1111
+ ));
1112
+ SelectLabel.displayName = "SelectLabel";
1113
+ var SelectItem = React10__namespace.forwardRef(
1114
+ ({ className, children, value, onClick, ...props }, ref) => {
1115
+ const ctx = React10__namespace.useContext(SelectContext);
1116
+ React10__namespace.useEffect(() => {
1117
+ if (!ctx) return;
1118
+ ctx.itemsRef.current.set(value, children);
1119
+ return () => {
1120
+ ctx.itemsRef.current.delete(value);
1121
+ };
1122
+ }, [ctx, value, children]);
1123
+ if (!ctx) return null;
1124
+ const selected = ctx.value === value;
1125
+ return /* @__PURE__ */ React10__namespace.createElement(
1126
+ "button",
1127
+ {
1128
+ ref,
1129
+ type: "button",
1130
+ className: cn(
1131
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
1132
+ className
1133
+ ),
1134
+ onClick: (e) => {
1135
+ ctx.setValue(value);
1136
+ onClick?.(e);
1137
+ },
1138
+ ...props
1139
+ },
1140
+ /* @__PURE__ */ React10__namespace.createElement("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center" }, selected ? /* @__PURE__ */ React10__namespace.createElement(lucideReact.Check, { className: "h-4 w-4" }) : null),
1141
+ /* @__PURE__ */ React10__namespace.createElement("span", null, children)
1142
+ );
1143
+ }
1144
+ );
1145
+ SelectItem.displayName = "SelectItem";
1146
+ var SelectSeparator = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1147
+ "div",
1148
+ {
1149
+ ref,
1150
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
1151
+ ...props
1152
+ }
1153
+ ));
1154
+ SelectSeparator.displayName = "SelectSeparator";
1155
+ var Separator = React10__namespace.forwardRef(
1156
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1157
+ "div",
1158
+ {
1159
+ ref,
1160
+ role: decorative ? void 0 : "separator",
1161
+ "aria-orientation": orientation,
1162
+ className: cn(
1163
+ "shrink-0 bg-border",
1164
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
1165
+ className
1166
+ ),
1167
+ ...props
1168
+ }
1169
+ )
1170
+ );
1171
+ Separator.displayName = "Separator";
1172
+ var sheetVariants = classVarianceAuthority.cva(
1173
+ "fixed z-[10000] gap-4 bg-background p-6 shadow-lg transition ease-in-out translate-x-0 translate-y-0",
1174
+ {
1175
+ variants: {
1176
+ side: {
1177
+ top: "inset-x-0 top-0 left-0 border-b",
1178
+ bottom: "inset-x-0 bottom-0 left-0 border-t",
1179
+ left: "inset-y-0 left-0 top-0 h-full w-3/4 border-r sm:max-w-sm",
1180
+ right: "inset-y-0 right-0 top-0 h-full w-3/4 border-l sm:max-w-sm"
1181
+ }
1182
+ },
1183
+ defaultVariants: {
1184
+ side: "right"
1185
+ }
1186
+ }
1187
+ );
1188
+ var SheetContent = React10__namespace.forwardRef(
1189
+ ({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1190
+ DialogContent,
1191
+ {
1192
+ ref,
1193
+ className: cn(
1194
+ "max-w-none rounded-none",
1195
+ sheetVariants({ side }),
1196
+ className
1197
+ ),
1198
+ showCloseButton: false,
1199
+ ...props
1200
+ },
1201
+ /* @__PURE__ */ React10__namespace.createElement(DialogClose, { className: "absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100" }, /* @__PURE__ */ React10__namespace.createElement(lucideReact.X, { className: "h-4 w-4" }), /* @__PURE__ */ React10__namespace.createElement("span", { className: "sr-only" }, "Close")),
1202
+ children
1203
+ )
1204
+ );
1205
+ SheetContent.displayName = "SheetContent";
1206
+ var SheetHeader = ({
1207
+ className,
1208
+ ...props
1209
+ }) => /* @__PURE__ */ React10__namespace.createElement(
1210
+ "div",
1211
+ {
1212
+ className: cn(
1213
+ "flex flex-col space-y-2 text-center sm:text-left",
1214
+ className
1215
+ ),
1216
+ ...props
1217
+ }
1218
+ );
1219
+ SheetHeader.displayName = "SheetHeader";
1220
+ var SheetFooter = ({
1221
+ className,
1222
+ ...props
1223
+ }) => /* @__PURE__ */ React10__namespace.createElement(
1224
+ "div",
1225
+ {
1226
+ className: cn(
1227
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
1228
+ className
1229
+ ),
1230
+ ...props
1231
+ }
1232
+ );
1233
+ SheetFooter.displayName = "SheetFooter";
1234
+ var SheetTitle = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1235
+ "h2",
1236
+ {
1237
+ ref,
1238
+ className: cn("text-lg font-semibold text-foreground", className),
1239
+ ...props
1240
+ }
1241
+ ));
1242
+ SheetTitle.displayName = "SheetTitle";
1243
+ var SheetDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10__namespace.createElement(
1244
+ "p",
1245
+ {
1246
+ ref,
1247
+ className: cn("text-sm text-muted-foreground", className),
1248
+ ...props
1249
+ }
1250
+ ));
1251
+ SheetDescription.displayName = "SheetDescription";
1252
+ var Textarea = React10__namespace.forwardRef(({ className, ...props }, ref) => {
1253
+ return /* @__PURE__ */ React10__namespace.createElement(
1254
+ "textarea",
1255
+ {
1256
+ className: cn(
1257
+ "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1258
+ className
1259
+ ),
1260
+ ref,
1261
+ ...props
1262
+ }
1263
+ );
1264
+ });
1265
+ Textarea.displayName = "Textarea";
1266
+ var TooltipConfigContext = React10__namespace.createContext({
1267
+ delayDuration: 200
1268
+ });
1269
+ var TooltipContext = React10__namespace.createContext(null);
1270
+ var TooltipProvider = ({
1271
+ children,
1272
+ delayDuration = 200
1273
+ }) => {
1274
+ return /* @__PURE__ */ React10__namespace.createElement(TooltipConfigContext.Provider, { value: { delayDuration } }, children);
1275
+ };
1276
+ var Tooltip = ({ children }) => {
1277
+ const [open, setOpen] = React10__namespace.useState(false);
1278
+ const triggerRef = React10__namespace.useRef(null);
1279
+ return /* @__PURE__ */ React10__namespace.createElement(TooltipContext.Provider, { value: { open, setOpen, triggerRef } }, children);
1280
+ };
1281
+ var TooltipTrigger = React10__namespace.forwardRef(({ children, ...props }, ref) => {
1282
+ const ctx = React10__namespace.useContext(TooltipContext);
1283
+ const cfg = React10__namespace.useContext(TooltipConfigContext);
1284
+ const timer = React10__namespace.useRef(null);
1285
+ if (!ctx) return null;
1286
+ const setRef = mergeRefs(ctx.triggerRef, ref);
1287
+ const openWithDelay = () => {
1288
+ if (timer.current) clearTimeout(timer.current);
1289
+ timer.current = setTimeout(() => ctx.setOpen(true), cfg.delayDuration);
1290
+ };
1291
+ const closeNow = () => {
1292
+ if (timer.current) clearTimeout(timer.current);
1293
+ ctx.setOpen(false);
1294
+ };
1295
+ const shared = {
1296
+ onMouseEnter: openWithDelay,
1297
+ onMouseLeave: closeNow,
1298
+ onFocus: openWithDelay,
1299
+ onBlur: closeNow,
1300
+ ...props
1301
+ };
1302
+ return /* @__PURE__ */ React10__namespace.createElement("span", { ref: setRef, ...shared }, children);
1303
+ });
1304
+ TooltipTrigger.displayName = "TooltipTrigger";
1305
+ var TooltipContent = React10__namespace.forwardRef(({ className, sideOffset = 4, style, ...props }, ref) => {
1306
+ const ctx = React10__namespace.useContext(TooltipContext);
1307
+ const [pos, setPos] = React10__namespace.useState({ top: 0, left: 0 });
1308
+ const open = !!ctx?.open;
1309
+ const trigger = ctx?.triggerRef.current ?? null;
1310
+ React10__namespace.useLayoutEffect(() => {
1311
+ if (!trigger) return;
1312
+ const rect = trigger.getBoundingClientRect();
1313
+ setPos({
1314
+ top: rect.top - sideOffset,
1315
+ left: rect.left + rect.width / 2
1316
+ });
1317
+ }, [trigger, sideOffset]);
1318
+ if (!ctx || !open || !trigger) return null;
1319
+ return /* @__PURE__ */ React10__namespace.createElement(Portal, null, /* @__PURE__ */ React10__namespace.createElement(
1320
+ "div",
1321
+ {
1322
+ ref,
1323
+ className: cn(
1324
+ "z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground",
1325
+ className
1326
+ ),
1327
+ style: {
1328
+ position: "fixed",
1329
+ top: pos.top,
1330
+ left: pos.left,
1331
+ transform: "translate(-50%, -100%)",
1332
+ ...style
1333
+ },
1334
+ ...props
1335
+ }
1336
+ ));
1337
+ });
1338
+ TooltipContent.displayName = "TooltipContent";
1339
+ var AvatarContext = React10__namespace.createContext(null);
1340
+ var Avatar = React10__namespace.forwardRef(({ className, ...props }, ref) => {
1341
+ const [status, setStatus] = React10__namespace.useState("idle");
1342
+ return /* @__PURE__ */ React10__namespace.createElement(AvatarContext.Provider, { value: { status, setStatus } }, /* @__PURE__ */ React10__namespace.createElement(
1343
+ "span",
1344
+ {
1345
+ ref,
1346
+ className: cn(
1347
+ "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1348
+ className
1349
+ ),
1350
+ ...props
1351
+ }
1352
+ ));
1353
+ });
1354
+ Avatar.displayName = "Avatar";
1355
+ var AvatarImage = React10__namespace.forwardRef(({ className, onLoad, onError, ...props }, ref) => {
1356
+ const ctx = React10__namespace.useContext(AvatarContext);
1357
+ return /* @__PURE__ */ React10__namespace.createElement(
1358
+ "img",
1359
+ {
1360
+ ref,
1361
+ className: cn(
1362
+ "aspect-square h-full w-full",
1363
+ ctx?.status === "error" ? "hidden" : void 0,
1364
+ className
1365
+ ),
1366
+ onLoad: (e) => {
1367
+ ctx?.setStatus("loaded");
1368
+ onLoad?.(e);
1369
+ },
1370
+ onError: (e) => {
1371
+ ctx?.setStatus("error");
1372
+ onError?.(e);
1373
+ },
1374
+ ...props
1375
+ }
1376
+ );
1377
+ });
1378
+ AvatarImage.displayName = "AvatarImage";
1379
+ var AvatarFallback = React10__namespace.forwardRef(({ className, ...props }, ref) => {
1380
+ const ctx = React10__namespace.useContext(AvatarContext);
1381
+ const show = ctx?.status !== "loaded";
1382
+ if (!show) return null;
1383
+ return /* @__PURE__ */ React10__namespace.createElement(
1384
+ "span",
1385
+ {
1386
+ ref,
1387
+ className: cn(
1388
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1389
+ className
1390
+ ),
1391
+ ...props
1392
+ }
1393
+ );
1394
+ });
1395
+ AvatarFallback.displayName = "AvatarFallback";
1396
+ function buildGridColsClasses(columns) {
1397
+ return [
1398
+ "grid-cols-1",
1399
+ // 默认单列
1400
+ columns.sm ? "sm:grid-cols-" + columns.sm : "",
1401
+ columns.md ? "md:grid-cols-" + columns.md : "md:grid-cols-2",
1402
+ columns.lg ? "lg:grid-cols-" + columns.lg : "lg:grid-cols-3",
1403
+ columns.xl ? "xl:grid-cols-" + columns.xl : ""
1404
+ ].filter(Boolean).join(" ");
1405
+ }
1406
+ function getGapClassName(gap) {
1407
+ const gapClasses = {
1408
+ sm: "gap-3",
1409
+ md: "gap-6",
1410
+ lg: "gap-8",
1411
+ xl: "gap-10"
1412
+ };
1413
+ return gapClasses[gap];
1414
+ }
1415
+ function Grid({
1416
+ items,
1417
+ renderItem,
1418
+ columns = { md: 2, lg: 3 },
1419
+ gap = "md",
1420
+ className = "",
1421
+ style
1422
+ }) {
1423
+ const gridColsClasses = buildGridColsClasses(columns);
1424
+ const gapClass = getGapClassName(gap);
1425
+ return /* @__PURE__ */ React10__namespace.default.createElement(
1426
+ "div",
1427
+ {
1428
+ className: clsx.clsx("grid", gridColsClasses, gapClass, className),
1429
+ style
1430
+ },
1431
+ items.map((item, index) => /* @__PURE__ */ React10__namespace.default.createElement("div", { key: item.id }, renderItem(item, index)))
1432
+ );
1433
+ }
1434
+ var SearchBox = ({
1435
+ searchQuery,
1436
+ onSearchChange,
1437
+ placeholder = "\u641C\u7D22\u5B9E\u9A8C\u9879\u76EE\u7684\u6807\u9898\u3001\u63CF\u8FF0\u6216\u6807\u7B7E...",
1438
+ size = "large"
1439
+ }) => {
1440
+ const getSizeStyles = () => {
1441
+ switch (size) {
1442
+ case "small":
1443
+ return {
1444
+ container: "h-10",
1445
+ input: "pl-10 pr-10 text-sm",
1446
+ icon: "w-4 h-4",
1447
+ iconPosition: "left-3",
1448
+ clearButton: "right-2 w-6 h-6",
1449
+ clearIcon: "w-3 h-3"
1450
+ };
1451
+ case "medium":
1452
+ return {
1453
+ container: "h-12",
1454
+ input: "pl-12 pr-12 text-base",
1455
+ icon: "w-5 h-5",
1456
+ iconPosition: "left-3",
1457
+ clearButton: "right-3 w-7 h-7",
1458
+ clearIcon: "w-4 h-4"
1459
+ };
1460
+ case "large":
1461
+ default:
1462
+ return {
1463
+ container: "h-16",
1464
+ input: "pl-6 pr-16 text-lg",
1465
+ icon: "w-6 h-6",
1466
+ iconPosition: "left-6",
1467
+ clearButton: "right-4 w-8 h-8",
1468
+ clearIcon: "w-4 h-4"
1469
+ };
1470
+ }
1471
+ };
1472
+ const styles = getSizeStyles();
1473
+ const isLarge = size === "large";
1474
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "relative group w-full" }, /* @__PURE__ */ React10__namespace.default.createElement(
1475
+ "input",
1476
+ {
1477
+ type: "text",
1478
+ placeholder,
1479
+ value: searchQuery,
1480
+ onChange: (e) => onSearchChange(e.target.value),
1481
+ className: clsx.clsx(
1482
+ "w-full",
1483
+ styles.container,
1484
+ styles.input,
1485
+ isLarge ? "border-2 border-gray-200 rounded-2xl shadow-lg" : "border border-gray-300 rounded-lg shadow-sm",
1486
+ "bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 hover:border-gray-400",
1487
+ isLarge ? "hover:shadow-xl" : "hover:shadow-md",
1488
+ "transition-all duration-300 ease-out text-gray-800 placeholder-gray-500",
1489
+ isLarge ? "font-medium" : "font-normal"
1490
+ )
1491
+ }
1492
+ ), searchQuery && /* @__PURE__ */ React10__namespace.default.createElement(
1493
+ "button",
1494
+ {
1495
+ onClick: () => onSearchChange(""),
1496
+ className: clsx.clsx(
1497
+ "absolute top-1/2",
1498
+ styles.clearButton,
1499
+ "transform -translate-y-1/2 z-10 group/clear"
1500
+ )
1501
+ },
1502
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: clsx.clsx(
1503
+ styles.clearButton,
1504
+ "flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-all duration-200 group-hover/clear:scale-105"
1505
+ ) }, /* @__PURE__ */ React10__namespace.default.createElement(
1506
+ "svg",
1507
+ {
1508
+ className: clsx.clsx(styles.clearIcon, "text-gray-500 group-hover/clear:text-gray-700"),
1509
+ fill: "none",
1510
+ stroke: "currentColor",
1511
+ viewBox: "0 0 24 24"
1512
+ },
1513
+ /* @__PURE__ */ React10__namespace.default.createElement(
1514
+ "path",
1515
+ {
1516
+ strokeLinecap: "round",
1517
+ strokeLinejoin: "round",
1518
+ strokeWidth: 2,
1519
+ d: "M6 18L18 6M6 6l12 12"
1520
+ }
1521
+ )
1522
+ ))
1523
+ ));
1524
+ };
1525
+ var Timeline = ({ items = [] }) => {
1526
+ if (!items || items.length === 0) {
1527
+ return null;
1528
+ }
1529
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "absolute left-4 top-0 bottom-0 w-0.5 bg-gray-200" }), items.map((item, index) => /* @__PURE__ */ React10__namespace.default.createElement("div", { key: index, className: "relative pl-12 pb-8" }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "absolute left-0 w-8 h-8 rounded-full bg-blue-500 border-4 border-white shadow-md flex items-center justify-center" }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "w-2 h-2 rounded-full bg-white" })), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "bg-white rounded-lg p-4 shadow-md" }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "text-sm text-gray-500 mb-2" }, item.date), /* @__PURE__ */ React10__namespace.default.createElement("h4", { className: "text-lg font-semibold mb-2" }, item.title), /* @__PURE__ */ React10__namespace.default.createElement("p", { className: "text-gray-600" }, item.description)))));
1530
+ };
1531
+ var CollisionBalls = ({
1532
+ collisionBallsConfig: {
1533
+ balls,
1534
+ width,
1535
+ height
1536
+ }
1537
+ }) => {
1538
+ const canvasRef = React10.useRef(null);
1539
+ const containerRef = React10.useRef(null);
1540
+ const ballsRef = React10.useRef([]);
1541
+ const [isShaking, setIsShaking] = React10.useState(false);
1542
+ const [draggedBall, setDraggedBall] = React10.useState(null);
1543
+ const [mousePos, setMousePos] = React10.useState({ x: 0, y: 0 });
1544
+ const animationRef = React10.useRef(null);
1545
+ const updateCanvasSize = () => {
1546
+ const container = containerRef.current;
1547
+ const canvas = canvasRef.current;
1548
+ if (!container || !canvas) {
1549
+ console.error("Container or canvas not found");
1550
+ return;
1551
+ }
1552
+ const containerWidth = container.clientWidth;
1553
+ const containerHeight = container.clientHeight;
1554
+ console.log("Container size:", { containerWidth, containerHeight });
1555
+ canvas.width = containerWidth;
1556
+ canvas.height = containerHeight;
1557
+ canvas.style.width = containerWidth + "px";
1558
+ canvas.style.height = containerHeight + "px";
1559
+ console.log("Canvas size updated:", {
1560
+ width: canvas.width,
1561
+ height: canvas.height,
1562
+ containerWidth,
1563
+ containerHeight
1564
+ });
1565
+ };
1566
+ const initBalls = () => {
1567
+ const canvas = canvasRef.current;
1568
+ if (!canvas) {
1569
+ console.error("Canvas not found during ball initialization");
1570
+ return [];
1571
+ }
1572
+ console.log("Initializing balls with canvas size:", {
1573
+ width: canvas.width,
1574
+ height: canvas.height
1575
+ });
1576
+ return balls.map((ballConfig) => ({
1577
+ x: Math.random() * (canvas.width - 100) + 50,
1578
+ y: Math.random() * (canvas.height - 100) + 50,
1579
+ vx: (Math.random() - 0.5) * 4,
1580
+ vy: (Math.random() - 0.5) * 4,
1581
+ radius: ballConfig.size,
1582
+ color: ballConfig.color,
1583
+ text: ballConfig.label,
1584
+ isDragging: false
1585
+ }));
1586
+ };
1587
+ React10.useEffect(() => {
1588
+ const handleResize = () => {
1589
+ console.log("Window resized");
1590
+ updateCanvasSize();
1591
+ };
1592
+ if (typeof window !== "undefined") {
1593
+ window.addEventListener("resize", handleResize);
1594
+ updateCanvasSize();
1595
+ }
1596
+ return () => {
1597
+ if (typeof window !== "undefined") {
1598
+ window.removeEventListener("resize", handleResize);
1599
+ }
1600
+ };
1601
+ }, []);
1602
+ React10.useEffect(() => {
1603
+ const canvas = canvasRef.current;
1604
+ if (!canvas) {
1605
+ console.error("Canvas element not found");
1606
+ return;
1607
+ }
1608
+ const ctx = canvas.getContext("2d");
1609
+ if (!ctx) {
1610
+ console.error("Failed to get canvas context");
1611
+ return;
1612
+ }
1613
+ console.log("Starting animation setup...");
1614
+ updateCanvasSize();
1615
+ ballsRef.current = initBalls();
1616
+ console.log("Balls initialized:", ballsRef.current);
1617
+ let lastTime = performance.now();
1618
+ let frameCount = 0;
1619
+ const animate = (currentTime) => {
1620
+ try {
1621
+ frameCount++;
1622
+ if (currentTime - lastTime >= 1e3) {
1623
+ console.log("FPS: " + frameCount);
1624
+ frameCount = 0;
1625
+ lastTime = currentTime;
1626
+ }
1627
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1628
+ ballsRef.current.forEach((ball) => {
1629
+ if (!ball.isDragging) {
1630
+ updatePosition(ball, canvas.width, canvas.height);
1631
+ }
1632
+ for (let i = 0; i < ballsRef.current.length; i++) {
1633
+ for (let j = i + 1; j < ballsRef.current.length; j++) {
1634
+ const ball1 = ballsRef.current[i];
1635
+ const ball2 = ballsRef.current[j];
1636
+ if (ball1 && ball2) {
1637
+ checkCollision(ball1, ball2);
1638
+ }
1639
+ }
1640
+ }
1641
+ draw(ctx, ball);
1642
+ });
1643
+ animationRef.current = requestAnimationFrame(animate);
1644
+ } catch (error) {
1645
+ console.error("Animation error:", error);
1646
+ }
1647
+ };
1648
+ console.log("Starting animation loop...");
1649
+ animationRef.current = requestAnimationFrame(animate);
1650
+ return () => {
1651
+ console.log("Cleaning up animation...");
1652
+ if (animationRef.current) {
1653
+ cancelAnimationFrame(animationRef.current);
1654
+ animationRef.current = null;
1655
+ }
1656
+ };
1657
+ }, []);
1658
+ const shake = () => {
1659
+ setIsShaking(true);
1660
+ ballsRef.current.forEach((ball) => {
1661
+ ball.vx = (Math.random() - 0.5) * 10;
1662
+ ball.vy = (Math.random() - 0.5) * 10;
1663
+ });
1664
+ setTimeout(() => setIsShaking(false), 200);
1665
+ };
1666
+ const slowdown = () => {
1667
+ setIsShaking(true);
1668
+ ballsRef.current.forEach((ball) => {
1669
+ ball.vx = ball.vx * 0.5;
1670
+ ball.vy = ball.vy * 0.5;
1671
+ });
1672
+ setTimeout(() => setIsShaking(false), 200);
1673
+ };
1674
+ const checkCollision = (ball1, ball2) => {
1675
+ const dx = ball2.x - ball1.x;
1676
+ const dy = ball2.y - ball1.y;
1677
+ const distance = Math.sqrt(dx * dx + dy * dy);
1678
+ if (distance < ball1.radius + ball2.radius) {
1679
+ const angle = Math.atan2(dy, dx);
1680
+ const overlap = (ball1.radius + ball2.radius - distance) / 2;
1681
+ if (ball1.isDragging || ball2.isDragging) {
1682
+ const draggedBall2 = ball1.isDragging ? ball1 : ball2;
1683
+ const otherBall = ball1.isDragging ? ball2 : ball1;
1684
+ otherBall.x += (draggedBall2 === ball1 ? 1 : -1) * overlap * Math.cos(angle);
1685
+ otherBall.y += (draggedBall2 === ball1 ? 1 : -1) * overlap * Math.sin(angle);
1686
+ const pushForce = 2;
1687
+ otherBall.vx = (draggedBall2 === ball1 ? -1 : 1) * Math.cos(angle) * pushForce;
1688
+ otherBall.vy = (draggedBall2 === ball1 ? -1 : 1) * Math.sin(angle) * pushForce;
1689
+ return;
1690
+ }
1691
+ const sin = Math.sin(angle);
1692
+ const cos = Math.cos(angle);
1693
+ const vx1 = ball1.vx * cos + ball1.vy * sin;
1694
+ const vy1 = ball1.vy * cos - ball1.vx * sin;
1695
+ const vx2 = ball2.vx * cos + ball2.vy * sin;
1696
+ const vy2 = ball2.vy * cos - ball2.vx * sin;
1697
+ const newVx1 = vx2;
1698
+ const newVx2 = vx1;
1699
+ ball1.vx = newVx1 * cos - vy1 * sin;
1700
+ ball1.vy = vy1 * cos + newVx1 * sin;
1701
+ ball2.vx = newVx2 * cos - vy2 * sin;
1702
+ ball2.vy = vy2 * cos + newVx2 * sin;
1703
+ ball1.x -= overlap * Math.cos(angle);
1704
+ ball1.y -= overlap * Math.sin(angle);
1705
+ ball2.x += overlap * Math.cos(angle);
1706
+ ball2.y += overlap * Math.sin(angle);
1707
+ }
1708
+ };
1709
+ const updatePosition = (ball, width2, height2) => {
1710
+ const handleBoundaryCollision = (velocity, position, boundary, radius) => {
1711
+ let newVelocity = velocity;
1712
+ let newPosition = position;
1713
+ if (position - radius < 0) {
1714
+ newPosition = radius;
1715
+ newVelocity = Math.abs(velocity);
1716
+ } else if (position + radius > boundary) {
1717
+ newPosition = boundary - radius;
1718
+ newVelocity = -Math.abs(velocity);
1719
+ }
1720
+ return [newVelocity, newPosition];
1721
+ };
1722
+ const [newVx, newX] = handleBoundaryCollision(
1723
+ ball.vx,
1724
+ ball.x,
1725
+ width2,
1726
+ ball.radius
1727
+ );
1728
+ const [newVy, newY] = handleBoundaryCollision(
1729
+ ball.vy,
1730
+ ball.y,
1731
+ height2,
1732
+ ball.radius
1733
+ );
1734
+ ball.vx = newVx;
1735
+ ball.vy = newVy;
1736
+ ball.x = newX;
1737
+ ball.y = newY;
1738
+ };
1739
+ const draw = (ctx, ball) => {
1740
+ ctx.beginPath();
1741
+ ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
1742
+ ctx.fillStyle = ball.color;
1743
+ ctx.fill();
1744
+ ctx.closePath();
1745
+ if (ball.text) {
1746
+ ctx.font = "14px Arial";
1747
+ ctx.fillStyle = "#fff";
1748
+ ctx.textAlign = "center";
1749
+ ctx.textBaseline = "middle";
1750
+ ctx.fillText(ball.text, ball.x, ball.y);
1751
+ }
1752
+ };
1753
+ const handleMouseDown = (event) => {
1754
+ const mousePos2 = getMousePos(event);
1755
+ const ball = ballsRef.current.find((b) => {
1756
+ const dx = b.x - mousePos2.x;
1757
+ const dy = b.y - mousePos2.y;
1758
+ return Math.sqrt(dx * dx + dy * dy) < b.radius;
1759
+ });
1760
+ if (ball) {
1761
+ ball.isDragging = true;
1762
+ setDraggedBall(ball);
1763
+ }
1764
+ };
1765
+ const handleMouseMove = (event) => {
1766
+ const mousePos2 = getMousePos(event);
1767
+ setMousePos(mousePos2);
1768
+ if (draggedBall) {
1769
+ draggedBall.x = mousePos2.x;
1770
+ draggedBall.y = mousePos2.y;
1771
+ draggedBall.vx = 0;
1772
+ draggedBall.vy = 0;
1773
+ }
1774
+ };
1775
+ const handleMouseUp = () => {
1776
+ if (draggedBall) {
1777
+ draggedBall.isDragging = false;
1778
+ setDraggedBall(null);
1779
+ }
1780
+ };
1781
+ const getMousePos = (event) => {
1782
+ const canvas = canvasRef.current;
1783
+ if (!canvas) return { x: 0, y: 0 };
1784
+ const rect = canvas.getBoundingClientRect();
1785
+ const scaleX = canvas.width / rect.width;
1786
+ const scaleY = canvas.height / rect.height;
1787
+ return {
1788
+ x: (event.clientX - rect.left) * scaleX,
1789
+ y: (event.clientY - rect.top) * scaleY
1790
+ };
1791
+ };
1792
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { style: { width: "100%", height: "100%", position: "relative", backgroundColor: "#f9fafb", borderRadius: "0.5rem" } }, /* @__PURE__ */ React10__namespace.default.createElement("div", { ref: containerRef, style: { width: "100%", height: "100%", position: "absolute", top: 0, left: 0 } }, /* @__PURE__ */ React10__namespace.default.createElement(
1793
+ "canvas",
1794
+ {
1795
+ ref: canvasRef,
1796
+ style: {
1797
+ width: "100%",
1798
+ height: "100%",
1799
+ display: "block"
1800
+ // 确保canvas正确显示
1801
+ },
1802
+ onMouseDown: handleMouseDown,
1803
+ onMouseMove: handleMouseMove,
1804
+ onMouseUp: handleMouseUp,
1805
+ onMouseLeave: handleMouseUp
1806
+ }
1807
+ )), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "absolute bottom-4 right-4 flex gap-2" }, /* @__PURE__ */ React10__namespace.default.createElement(
1808
+ "button",
1809
+ {
1810
+ onClick: shake,
1811
+ className: clsx.clsx("px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors", isShaking ? "animate-pulse" : "")
1812
+ },
1813
+ "\u6447\u4E00\u6447"
1814
+ ), /* @__PURE__ */ React10__namespace.default.createElement(
1815
+ "button",
1816
+ {
1817
+ onClick: slowdown,
1818
+ className: clsx.clsx("px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors", isShaking ? "animate-pulse" : "")
1819
+ },
1820
+ "\u51CF\u901F"
1821
+ )));
1822
+ };
1823
+ function GenericOrderManager({
1824
+ operations,
1825
+ renderItem,
1826
+ className = "",
1827
+ title = "\u987A\u5E8F\u7BA1\u7406",
1828
+ description = "\u62D6\u62FD\u6216\u4F7F\u7528\u6309\u94AE\u8C03\u6574\u663E\u793A\u987A\u5E8F",
1829
+ onOrderChanged,
1830
+ emptyMessage = "\u6682\u65E0\u6570\u636E",
1831
+ loadingMessage = "\u52A0\u8F7D\u6570\u636E..."
1832
+ }) {
1833
+ const [items, setItems] = React10.useState([]);
1834
+ const [originalOrder, setOriginalOrder] = React10.useState([]);
1835
+ const [loading, setLoading] = React10.useState(true);
1836
+ const [saving, setSaving] = React10.useState(false);
1837
+ const [error, setError] = React10.useState(null);
1838
+ const [hasChanges, setHasChanges] = React10.useState(false);
1839
+ const [draggedItem, setDraggedItem] = React10.useState(null);
1840
+ const loadItems = React10.useCallback(async () => {
1841
+ try {
1842
+ setLoading(true);
1843
+ setError(null);
1844
+ const data = await operations.loadItems();
1845
+ setItems(data);
1846
+ setOriginalOrder([...data]);
1847
+ setHasChanges(false);
1848
+ } catch (err) {
1849
+ console.error("\u274C [\u901A\u7528\u6392\u5E8F] \u52A0\u8F7D\u6570\u636E\u9519\u8BEF:", err);
1850
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u6570\u636E\u5931\u8D25");
1851
+ } finally {
1852
+ setLoading(false);
1853
+ }
1854
+ }, [operations]);
1855
+ React10.useEffect(() => {
1856
+ loadItems();
1857
+ }, [loadItems]);
1858
+ React10.useEffect(() => {
1859
+ const hasOrderChanged = items.some(
1860
+ (item, index) => originalOrder[index]?.id !== item.id
1861
+ );
1862
+ setHasChanges(hasOrderChanged);
1863
+ }, [items, originalOrder]);
1864
+ const handleMoveUp = async (itemId) => {
1865
+ try {
1866
+ setError(null);
1867
+ const currentIndex = items.findIndex((item) => item.id === itemId);
1868
+ if (currentIndex === -1) {
1869
+ setError("\u9879\u76EE\u4E0D\u5B58\u5728");
1870
+ return;
1871
+ }
1872
+ if (currentIndex === 0) {
1873
+ setError("\u9879\u76EE\u5DF2\u7ECF\u5728\u6700\u524D\u9762\uFF0C\u65E0\u6CD5\u4E0A\u79FB");
1874
+ return;
1875
+ }
1876
+ await operations.moveItemUp(itemId);
1877
+ await loadItems();
1878
+ onOrderChanged?.();
1879
+ } catch (err) {
1880
+ console.error("\u274C [\u901A\u7528\u6392\u5E8F] \u4E0A\u79FB\u9879\u76EE\u9519\u8BEF:", err);
1881
+ setError(err instanceof Error ? err.message : "\u4E0A\u79FB\u5931\u8D25");
1882
+ }
1883
+ };
1884
+ const handleMoveDown = async (itemId) => {
1885
+ try {
1886
+ setError(null);
1887
+ const currentIndex = items.findIndex((item) => item.id === itemId);
1888
+ if (currentIndex === -1) {
1889
+ setError("\u9879\u76EE\u4E0D\u5B58\u5728");
1890
+ return;
1891
+ }
1892
+ if (currentIndex === items.length - 1) {
1893
+ setError("\u9879\u76EE\u5DF2\u7ECF\u5728\u6700\u540E\u9762\uFF0C\u65E0\u6CD5\u4E0B\u79FB");
1894
+ return;
1895
+ }
1896
+ await operations.moveItemDown(itemId);
1897
+ await loadItems();
1898
+ onOrderChanged?.();
1899
+ } catch (err) {
1900
+ console.error("\u274C [\u901A\u7528\u6392\u5E8F] \u4E0B\u79FB\u9879\u76EE\u9519\u8BEF:", err);
1901
+ setError(err instanceof Error ? err.message : "\u4E0B\u79FB\u5931\u8D25");
1902
+ }
1903
+ };
1904
+ const handleDragStart = (e, index) => {
1905
+ setDraggedItem(index);
1906
+ e.dataTransfer.effectAllowed = "move";
1907
+ };
1908
+ const handleDragOver = (e, _index) => {
1909
+ e.preventDefault();
1910
+ e.dataTransfer.dropEffect = "move";
1911
+ };
1912
+ const handleDrop = async (e, dropIndex) => {
1913
+ e.preventDefault();
1914
+ if (draggedItem === null || draggedItem === dropIndex) {
1915
+ setDraggedItem(null);
1916
+ return;
1917
+ }
1918
+ try {
1919
+ setError(null);
1920
+ const newItems = [...items];
1921
+ const draggedItemData = newItems[draggedItem];
1922
+ if (!draggedItemData) return;
1923
+ newItems.splice(draggedItem, 1);
1924
+ newItems.splice(dropIndex, 0, draggedItemData);
1925
+ const itemOrders = newItems.map((item, index) => ({
1926
+ id: item.id,
1927
+ order: index
1928
+ }));
1929
+ await operations.updateItemOrder(itemOrders);
1930
+ await loadItems();
1931
+ onOrderChanged?.();
1932
+ } catch (err) {
1933
+ console.error("\u274C [\u901A\u7528\u6392\u5E8F] \u62D6\u62FD\u6392\u5E8F\u9519\u8BEF:", err);
1934
+ setError(err instanceof Error ? err.message : "\u6392\u5E8F\u5931\u8D25");
1935
+ } finally {
1936
+ setDraggedItem(null);
1937
+ }
1938
+ };
1939
+ const handleSaveOrder = async () => {
1940
+ try {
1941
+ setSaving(true);
1942
+ setError(null);
1943
+ const itemOrders = items.map((item, index) => ({
1944
+ id: item.id,
1945
+ order: index
1946
+ }));
1947
+ await operations.updateItemOrder(itemOrders);
1948
+ setOriginalOrder([...items]);
1949
+ setHasChanges(false);
1950
+ onOrderChanged?.();
1951
+ } catch (err) {
1952
+ console.error("\u274C [\u901A\u7528\u6392\u5E8F] \u4FDD\u5B58\u987A\u5E8F\u9519\u8BEF:", err);
1953
+ setError(err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25");
1954
+ await loadItems();
1955
+ } finally {
1956
+ setSaving(false);
1957
+ }
1958
+ };
1959
+ const handleResetOrder = () => {
1960
+ setItems([...originalOrder]);
1961
+ };
1962
+ if (loading) {
1963
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: cn("flex flex-col items-center justify-center p-12 text-gray-500", className) }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "w-6 h-6 border-2 border-gray-200 border-t-blue-500 rounded-full animate-spin mb-2" }), /* @__PURE__ */ React10__namespace.default.createElement("span", null, loadingMessage));
1964
+ }
1965
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: cn("bg-white rounded-xl p-6 shadow-md border-2 border-gray-100", className) }, /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex items-center justify-between mb-4 pb-3 border-b border-gray-100 sm:flex-row flex-col sm:items-center items-start gap-4" }, /* @__PURE__ */ React10__namespace.default.createElement("h3", { className: "m-0 text-gray-900 text-lg font-semibold" }, title), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex gap-3 w-full sm:w-auto" }, hasChanges && /* @__PURE__ */ React10__namespace.default.createElement(React10__namespace.default.Fragment, null, /* @__PURE__ */ React10__namespace.default.createElement(
1966
+ "button",
1967
+ {
1968
+ onClick: handleResetOrder,
1969
+ className: "flex items-center gap-2 bg-amber-500 hover:bg-amber-600 text-white px-4 py-2 rounded-lg font-medium transition-colors",
1970
+ title: "\u91CD\u7F6E\u4E3A\u539F\u59CB\u987A\u5E8F"
1971
+ },
1972
+ /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.RotateCcw, { size: 16 }),
1973
+ "\u91CD\u7F6E"
1974
+ ), /* @__PURE__ */ React10__namespace.default.createElement(
1975
+ "button",
1976
+ {
1977
+ onClick: handleSaveOrder,
1978
+ disabled: saving,
1979
+ className: "flex items-center gap-2 bg-blue-500 hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg font-medium transition-colors",
1980
+ title: "\u4FDD\u5B58\u65B0\u987A\u5E8F"
1981
+ },
1982
+ /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.Save, { size: 16 }),
1983
+ saving ? "\u4FDD\u5B58\u4E2D..." : "\u4FDD\u5B58\u987A\u5E8F"
1984
+ )))), error && /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex items-center gap-2 bg-red-50 text-red-600 p-3 rounded-lg mb-4 border border-red-200" }, /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.AlertCircle, { size: 16 }), /* @__PURE__ */ React10__namespace.default.createElement("span", null, error)), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "bg-slate-50 border border-slate-200 rounded-lg p-4 mb-6" }, /* @__PURE__ */ React10__namespace.default.createElement("p", { className: "m-0 mb-2 color-slate-500 text-sm" }, description), /* @__PURE__ */ React10__namespace.default.createElement("ul", { className: "m-0 pl-6 color-slate-500 text-sm list-disc" }, /* @__PURE__ */ React10__namespace.default.createElement("li", { className: "mb-1" }, "\u4F7F\u7528\u62D6\u62FD\uFF1A\u70B9\u51FB\u5E76\u62D6\u52A8 ", /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.GripVertical, { size: 14, className: "inline-block align-middle text-gray-500" }), " \u56FE\u6807"), /* @__PURE__ */ React10__namespace.default.createElement("li", { className: "mb-1" }, "\u4F7F\u7528\u6309\u94AE\uFF1A\u70B9\u51FB ", /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.ChevronUp, { size: 14, className: "inline-block align-middle text-gray-500" }), " \u6216 ", /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.ChevronDown, { size: 14, className: "inline-block align-middle text-gray-500" }), " \u6309\u94AE"), /* @__PURE__ */ React10__namespace.default.createElement("li", null, '\u5B8C\u6210\u8C03\u6574\u540E\uFF0C\u70B9\u51FB"\u4FDD\u5B58\u987A\u5E8F"\u6309\u94AE\u4FDD\u5B58\u66F4\u6539'))), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex flex-col gap-3" }, items.map((item, index) => /* @__PURE__ */ React10__namespace.default.createElement(
1985
+ "div",
1986
+ {
1987
+ key: item.id,
1988
+ className: cn(
1989
+ "flex items-center gap-3 p-4 bg-gray-50 border-2 border-gray-200 rounded-lg transition-all hover:border-gray-300 hover:shadow-sm",
1990
+ draggedItem === index && "opacity-50 rotate-2 border-blue-500"
1991
+ ),
1992
+ draggable: true,
1993
+ onDragStart: (e) => handleDragStart(e, index),
1994
+ onDragOver: (e) => handleDragOver(e),
1995
+ onDrop: (e) => handleDrop(e, index)
1996
+ },
1997
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex items-center cursor-grab active:cursor-grabbing text-gray-400 p-1 rounded hover:text-gray-500 hover:bg-gray-100 transition-colors" }, /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.GripVertical, { size: 20 })),
1998
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex-1 min-w-0" }, renderItem(item, index, index === 0, index === items.length - 1)),
1999
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex items-center mx-3" }, /* @__PURE__ */ React10__namespace.default.createElement("span", { className: "flex items-center justify-center w-8 h-8 bg-blue-500 text-white text-sm font-semibold rounded-full sm:w-8 sm:h-8 w-7 h-7 sm:text-sm text-xs" }, "#", index + 1)),
2000
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex flex-col gap-1 sm:flex-col flex-row" }, /* @__PURE__ */ React10__namespace.default.createElement(
2001
+ "button",
2002
+ {
2003
+ onClick: () => handleMoveUp(item.id),
2004
+ disabled: index === 0,
2005
+ className: "flex items-center justify-center w-8 h-8 p-0 border border-gray-300 bg-white text-gray-500 rounded cursor-pointer transition-all hover:bg-gray-100 hover:border-gray-400 hover:text-gray-700 disabled:opacity-40 disabled:cursor-not-allowed disabled:bg-gray-50 sm:w-8 sm:h-8 w-7 h-7",
2006
+ title: "\u4E0A\u79FB"
2007
+ },
2008
+ /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.ChevronUp, { size: 18 })
2009
+ ), /* @__PURE__ */ React10__namespace.default.createElement(
2010
+ "button",
2011
+ {
2012
+ onClick: () => handleMoveDown(item.id),
2013
+ disabled: index === items.length - 1,
2014
+ className: "flex items-center justify-center w-8 h-8 p-0 border border-gray-300 bg-white text-gray-500 rounded cursor-pointer transition-all hover:bg-gray-100 hover:border-gray-400 hover:text-gray-700 disabled:opacity-40 disabled:cursor-not-allowed disabled:bg-gray-50 sm:w-8 sm:h-8 w-7 h-7",
2015
+ title: "\u4E0B\u79FB"
2016
+ },
2017
+ /* @__PURE__ */ React10__namespace.default.createElement(lucideReact.ChevronDown, { size: 18 })
2018
+ ))
2019
+ ))), items.length === 0 && /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "text-center p-12 text-gray-400 italic" }, /* @__PURE__ */ React10__namespace.default.createElement("p", { className: "m-0" }, emptyMessage)));
2020
+ }
2021
+ var BackButton = ({ href, className = "" }) => {
2022
+ const router = navigation.useRouter();
2023
+ const handleClick = () => {
2024
+ if (href) {
2025
+ router.push(href);
2026
+ } else {
2027
+ router.back();
2028
+ }
2029
+ };
2030
+ return /* @__PURE__ */ React10__namespace.default.createElement(
2031
+ "button",
2032
+ {
2033
+ onClick: handleClick,
2034
+ className: cn(
2035
+ "inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors",
2036
+ className
2037
+ )
2038
+ },
2039
+ /* @__PURE__ */ React10__namespace.default.createElement(
2040
+ "svg",
2041
+ {
2042
+ className: "w-5 h-5 mr-2",
2043
+ fill: "none",
2044
+ stroke: "currentColor",
2045
+ viewBox: "0 0 24 24"
2046
+ },
2047
+ /* @__PURE__ */ React10__namespace.default.createElement(
2048
+ "path",
2049
+ {
2050
+ strokeLinecap: "round",
2051
+ strokeLinejoin: "round",
2052
+ strokeWidth: 2,
2053
+ d: "M10 19l-7-7m0 0l7-7m-7 7h18"
2054
+ }
2055
+ )
2056
+ ),
2057
+ "\u8FD4\u56DE"
2058
+ );
2059
+ };
2060
+ function getColorValue(bgClass) {
2061
+ const colorMap = {
2062
+ "bg-blue-500": "#3b82f6",
2063
+ "bg-green-500": "#10b981",
2064
+ "bg-red-500": "#ef4444",
2065
+ "bg-purple-500": "#8b5cf6",
2066
+ "bg-slate-500": "#64748b",
2067
+ "bg-emerald-500": "#10b981",
2068
+ "bg-orange-500": "#f97316"
2069
+ };
2070
+ return colorMap[bgClass] || "#3b82f6";
2071
+ }
2072
+ function FilterButtonGroup({
2073
+ label,
2074
+ value,
2075
+ options,
2076
+ onChange,
2077
+ className
2078
+ }) {
2079
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: cn("space-y-4", className) }, /* @__PURE__ */ React10__namespace.default.createElement("h3", { className: "text-lg font-semibold text-gray-800" }, label), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex gap-3" }, options.map((option) => {
2080
+ const isActive = value === option.value;
2081
+ return /* @__PURE__ */ React10__namespace.default.createElement(
2082
+ "button",
2083
+ {
2084
+ key: option.value,
2085
+ onClick: () => onChange(option.value),
2086
+ style: isActive ? { backgroundColor: getColorValue(option.activeColor.bg) } : void 0,
2087
+ className: cn(
2088
+ "flex-1 h-12 rounded-lg font-medium text-sm transition-all duration-200 ease-out focus:outline-none focus:ring-2 focus:ring-opacity-50 border",
2089
+ isActive ? "text-white border-transparent shadow-md focus:ring-white" : "bg-white text-gray-700 border-gray-200 shadow-sm hover:bg-gray-50 hover:border-gray-300 hover:shadow focus:ring-blue-300"
2090
+ )
2091
+ },
2092
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "flex items-center justify-center space-x-2" }, /* @__PURE__ */ React10__namespace.default.createElement("span", { className: "text-lg" }, option.icon), /* @__PURE__ */ React10__namespace.default.createElement("span", null, option.label), option.showCount && option.count !== void 0 && /* @__PURE__ */ React10__namespace.default.createElement("span", { className: cn(
2093
+ "text-xs font-semibold px-2 py-0.5 rounded-full min-w-[1.25rem] text-center",
2094
+ isActive ? "bg-white/20 text-white" : "bg-gray-100 text-gray-600"
2095
+ ) }, option.count))
2096
+ );
2097
+ })));
2098
+ }
2099
+ function SearchResultHint({ searchQuery, resultCount, className }) {
2100
+ if (!searchQuery) return null;
2101
+ return /* @__PURE__ */ React10__namespace.default.createElement("div", { className: cn("mb-6 p-4 bg-blue-50 border border-blue-200 rounded-lg", className) }, /* @__PURE__ */ React10__namespace.default.createElement("p", { className: "text-sm text-blue-700" }, '\u641C\u7D22 "', /* @__PURE__ */ React10__namespace.default.createElement("span", { className: "font-medium" }, searchQuery), '" \u627E\u5230 ', resultCount, " \u4E2A\u7ED3\u679C"));
2102
+ }
2103
+ var Modal = ({
2104
+ isOpen,
2105
+ onClose,
2106
+ title,
2107
+ width,
2108
+ height,
2109
+ className,
2110
+ maskClosable = true,
2111
+ children,
2112
+ zIndex = 50,
2113
+ overlayClassName
2114
+ }) => {
2115
+ const contentZIndex = Math.max(zIndex, 1e4);
2116
+ return /* @__PURE__ */ React10__namespace.default.createElement(Dialog, { open: isOpen, onOpenChange: (open) => {
2117
+ if (!open) {
2118
+ if (maskClosable) {
2119
+ onClose();
2120
+ }
2121
+ }
2122
+ } }, /* @__PURE__ */ React10__namespace.default.createElement(
2123
+ DialogContent,
2124
+ {
2125
+ className: cn("sm:max-w-[425px]", className),
2126
+ overlayClassName,
2127
+ onPointerDownOutside: (e) => {
2128
+ if (!maskClosable) e.preventDefault();
2129
+ },
2130
+ onEscapeKeyDown: (e) => {
2131
+ if (!maskClosable) e.preventDefault();
2132
+ },
2133
+ style: {
2134
+ zIndex: contentZIndex,
2135
+ ...width ? { maxWidth: typeof width === "number" ? `${width}px` : width } : void 0,
2136
+ ...height ? { height: typeof height === "number" ? `${height}px` : height } : void 0
2137
+ }
2138
+ },
2139
+ title ? /* @__PURE__ */ React10__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React10__namespace.default.createElement(DialogTitle, null, title)) : (
2140
+ // 无障碍性:始终需要 DialogTitle,使用 sr-only 对视觉隐藏但对屏幕阅读器可见
2141
+ /* @__PURE__ */ React10__namespace.default.createElement(DialogTitle, { className: "sr-only" }, "\u5F39\u7A97")
2142
+ ),
2143
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "py-4" }, children)
2144
+ ));
2145
+ };
2146
+ var ConfirmModal = ({
2147
+ isOpen,
2148
+ onClose,
2149
+ onConfirm,
2150
+ title = "\u786E\u8BA4\u64CD\u4F5C",
2151
+ message,
2152
+ confirmText = "\u786E\u8BA4",
2153
+ cancelText = "\u53D6\u6D88",
2154
+ isLoading = false
2155
+ }) => {
2156
+ return /* @__PURE__ */ React10__namespace.default.createElement(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React10__namespace.default.createElement(AlertDialogContent, null, /* @__PURE__ */ React10__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React10__namespace.default.createElement(DialogTitle, null, title), /* @__PURE__ */ React10__namespace.default.createElement(DialogDescription, null, message)), /* @__PURE__ */ React10__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React10__namespace.default.createElement(AlertDialogCancel, { disabled: isLoading }, cancelText), /* @__PURE__ */ React10__namespace.default.createElement(
2157
+ AlertDialogAction,
2158
+ {
2159
+ onClick: (e) => {
2160
+ e.preventDefault();
2161
+ onConfirm();
2162
+ },
2163
+ disabled: isLoading,
2164
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90"
2165
+ },
2166
+ isLoading ? "\u5904\u7406\u4E2D..." : confirmText
2167
+ ))));
2168
+ };
2169
+ function ImageMappingPanel({
2170
+ title,
2171
+ items,
2172
+ value,
2173
+ onChange,
2174
+ className,
2175
+ uploadLabel = "\u4E0A\u4F20\u56FE\u7247",
2176
+ clearLabel = "\u6E05\u9664"
2177
+ }) {
2178
+ const handleFileChange = (id, file) => {
2179
+ if (!file) {
2180
+ return;
2181
+ }
2182
+ const reader = new FileReader();
2183
+ reader.onload = () => {
2184
+ const base64 = typeof reader.result === "string" ? reader.result : "";
2185
+ if (!base64) {
2186
+ return;
2187
+ }
2188
+ onChange({
2189
+ ...value,
2190
+ [id]: base64
2191
+ });
2192
+ };
2193
+ reader.readAsDataURL(file);
2194
+ };
2195
+ const handleRemove = (id) => {
2196
+ const next = { ...value };
2197
+ delete next[id];
2198
+ onChange(next);
2199
+ };
2200
+ return /* @__PURE__ */ React10__namespace.default.createElement("details", { className: cn("rounded-lg border border-slate-200 bg-white/80 p-3", className) }, /* @__PURE__ */ React10__namespace.default.createElement("summary", { className: "cursor-pointer text-sm font-semibold text-slate-700" }, title), /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "mt-3 grid grid-cols-1 gap-2 sm:grid-cols-2" }, items.map((item) => {
2201
+ const image = value[item.id];
2202
+ return /* @__PURE__ */ React10__namespace.default.createElement(
2203
+ "div",
2204
+ {
2205
+ key: item.id,
2206
+ className: "flex items-center gap-2 rounded-md border border-slate-200 bg-white p-2"
2207
+ },
2208
+ /* @__PURE__ */ React10__namespace.default.createElement("div", { className: "w-16 text-xs font-semibold text-slate-600" }, item.label),
2209
+ /* @__PURE__ */ React10__namespace.default.createElement("label", { className: "flex-1 cursor-pointer rounded-md bg-cyan-600 px-2 py-1 text-center text-xs font-medium text-white" }, uploadLabel, /* @__PURE__ */ React10__namespace.default.createElement(
2210
+ "input",
2211
+ {
2212
+ type: "file",
2213
+ accept: "image/*",
2214
+ className: "hidden",
2215
+ onChange: (event) => {
2216
+ handleFileChange(item.id, event.target.files?.[0]);
2217
+ event.currentTarget.value = "";
2218
+ }
2219
+ }
2220
+ )),
2221
+ image ? /* @__PURE__ */ React10__namespace.default.createElement(React10__namespace.default.Fragment, null, /* @__PURE__ */ React10__namespace.default.createElement(
2222
+ "img",
2223
+ {
2224
+ src: image,
2225
+ alt: item.label,
2226
+ className: "h-8 w-8 rounded-full border border-slate-200 object-cover"
2227
+ }
2228
+ ), /* @__PURE__ */ React10__namespace.default.createElement(
2229
+ "button",
2230
+ {
2231
+ type: "button",
2232
+ className: "rounded-md border border-red-200 px-2 py-1 text-xs text-red-600",
2233
+ onClick: () => handleRemove(item.id)
2234
+ },
2235
+ clearLabel
2236
+ )) : null
2237
+ );
2238
+ })));
2239
+ }
2240
+ function useStorage(storage, key, defaultValue) {
2241
+ const [value, setValue] = React10.useState(defaultValue);
2242
+ const [loading, setLoading] = React10.useState(true);
2243
+ React10.useEffect(() => {
2244
+ const loadValue = async () => {
2245
+ try {
2246
+ const stored = await storage.getItem(key);
2247
+ if (stored !== null) {
2248
+ setValue(JSON.parse(stored));
2249
+ }
2250
+ } catch (error) {
2251
+ console.error('Error reading storage key "' + key + '":', error);
2252
+ } finally {
2253
+ setLoading(false);
2254
+ }
2255
+ };
2256
+ void loadValue();
2257
+ }, [storage, key]);
2258
+ const updateValue = React10.useCallback(
2259
+ async (newValue) => {
2260
+ try {
2261
+ setValue(newValue);
2262
+ await storage.setItem(key, JSON.stringify(newValue));
2263
+ if ("dispatchChange" in storage && typeof storage.dispatchChange === "function") {
2264
+ storage.dispatchChange(key, JSON.stringify(newValue));
2265
+ }
2266
+ } catch (error) {
2267
+ console.error('Error setting storage key "' + key + '":', error);
2268
+ }
2269
+ },
2270
+ [storage, key]
2271
+ );
2272
+ const removeValue = React10.useCallback(async () => {
2273
+ try {
2274
+ setValue(defaultValue);
2275
+ await storage.removeItem(key);
2276
+ if ("dispatchChange" in storage && typeof storage.dispatchChange === "function") {
2277
+ storage.dispatchChange(key, null);
2278
+ }
2279
+ } catch (error) {
2280
+ console.error('Error removing storage key "' + key + '":', error);
2281
+ }
2282
+ }, [storage, key, defaultValue]);
2283
+ React10.useEffect(() => {
2284
+ if (!storage.addChangeListener) {
2285
+ return;
2286
+ }
2287
+ const cleanup = storage.addChangeListener((changedKey, newValue) => {
2288
+ if (changedKey === key) {
2289
+ try {
2290
+ if (newValue === null) {
2291
+ setValue(defaultValue);
2292
+ } else {
2293
+ setValue(JSON.parse(newValue));
2294
+ }
2295
+ } catch (error) {
2296
+ console.error("Error parsing storage change event:", error);
2297
+ }
2298
+ }
2299
+ });
2300
+ return cleanup;
2301
+ }, [storage, key, defaultValue]);
2302
+ return [value, updateValue, removeValue, loading];
2303
+ }
2304
+
2305
+ // src/storage/adapters/web-adapter.ts
2306
+ var isBrowser = typeof window !== "undefined" && typeof window.localStorage !== "undefined";
2307
+ var WebStorageAdapter = class {
2308
+ async getItem(key) {
2309
+ if (!isBrowser) {
2310
+ return null;
2311
+ }
2312
+ try {
2313
+ return localStorage.getItem(key);
2314
+ } catch (error) {
2315
+ console.error('[WebStorage] Error getting item "' + key + '":', error);
2316
+ return null;
2317
+ }
2318
+ }
2319
+ async setItem(key, value) {
2320
+ if (!isBrowser) {
2321
+ return;
2322
+ }
2323
+ try {
2324
+ localStorage.setItem(key, value);
2325
+ } catch (error) {
2326
+ console.error('[WebStorage] Error setting item "' + key + '":', error);
2327
+ throw error;
2328
+ }
2329
+ }
2330
+ async removeItem(key) {
2331
+ if (!isBrowser) {
2332
+ return;
2333
+ }
2334
+ try {
2335
+ localStorage.removeItem(key);
2336
+ } catch (error) {
2337
+ console.error('[WebStorage] Error removing item "' + key + '":', error);
2338
+ throw error;
2339
+ }
2340
+ }
2341
+ async clear() {
2342
+ if (!isBrowser) {
2343
+ return;
2344
+ }
2345
+ try {
2346
+ localStorage.clear();
2347
+ } catch (error) {
2348
+ console.error("[WebStorage] Error clearing storage:", error);
2349
+ throw error;
2350
+ }
2351
+ }
2352
+ addChangeListener(callback) {
2353
+ if (!isBrowser) {
2354
+ return () => {
2355
+ };
2356
+ }
2357
+ const handleStorageEvent = (e) => {
2358
+ if (e.key) {
2359
+ callback(e.key, e.newValue);
2360
+ }
2361
+ };
2362
+ const handleCustomEvent = (e) => {
2363
+ const customEvent = e;
2364
+ callback(customEvent.detail.key, customEvent.detail.value);
2365
+ };
2366
+ window.addEventListener("storage", handleStorageEvent);
2367
+ window.addEventListener("local-storage-change", handleCustomEvent);
2368
+ return () => {
2369
+ window.removeEventListener("storage", handleStorageEvent);
2370
+ window.removeEventListener("local-storage-change", handleCustomEvent);
2371
+ };
2372
+ }
2373
+ /**
2374
+ * 触发自定义事件,通知同标签页的其他组件
2375
+ */
2376
+ dispatchChange(key, value) {
2377
+ if (!isBrowser) {
2378
+ return;
2379
+ }
2380
+ window.dispatchEvent(
2381
+ new CustomEvent("local-storage-change", {
2382
+ detail: { key, value }
2383
+ })
2384
+ );
2385
+ }
2386
+ };
2387
+
2388
+ // src/storage/hooks/useLocalStorage.ts
2389
+ var webStorage = new WebStorageAdapter();
2390
+ function useLocalStorage(key, defaultValue) {
2391
+ return useStorage(webStorage, key, defaultValue);
2392
+ }
2393
+
2394
+ // src/components/LocalImageMappingPanel.tsx
2395
+ function LocalImageMappingPanel({
2396
+ storageKey,
2397
+ defaultValue = {},
2398
+ onValueChange,
2399
+ ...panelProps
2400
+ }) {
2401
+ const [value, setValue] = useLocalStorage(storageKey, defaultValue);
2402
+ return /* @__PURE__ */ React10__namespace.default.createElement(
2403
+ ImageMappingPanel,
2404
+ {
2405
+ ...panelProps,
2406
+ value,
2407
+ onChange: (next) => {
2408
+ setValue(next);
2409
+ onValueChange?.(next);
2410
+ }
2411
+ }
2412
+ );
2413
+ }
2414
+
2415
+ exports.AlertDialog = Dialog;
2416
+ exports.AlertDialogAction = AlertDialogAction;
2417
+ exports.AlertDialogCancel = AlertDialogCancel;
2418
+ exports.AlertDialogContent = AlertDialogContent;
2419
+ exports.AlertDialogDescription = DialogDescription;
2420
+ exports.AlertDialogFooter = DialogFooter;
2421
+ exports.AlertDialogHeader = DialogHeader;
2422
+ exports.AlertDialogOverlay = DialogOverlay;
2423
+ exports.AlertDialogPortal = DialogPortal;
2424
+ exports.AlertDialogTitle = DialogTitle;
2425
+ exports.AlertDialogTrigger = DialogTrigger;
2426
+ exports.Avatar = Avatar;
2427
+ exports.AvatarFallback = AvatarFallback;
2428
+ exports.AvatarImage = AvatarImage;
2429
+ exports.BackButton = BackButton;
2430
+ exports.Badge = Badge;
2431
+ exports.Button = Button;
2432
+ exports.Card = Card;
2433
+ exports.CardContent = CardContent;
2434
+ exports.CardDescription = CardDescription;
2435
+ exports.CardFooter = CardFooter;
2436
+ exports.CardHeader = CardHeader;
2437
+ exports.CardTitle = CardTitle;
2438
+ exports.CollisionBalls = CollisionBalls;
2439
+ exports.ConfirmModal = ConfirmModal;
2440
+ exports.Dialog = Dialog;
2441
+ exports.DialogClose = DialogClose;
2442
+ exports.DialogContent = DialogContent;
2443
+ exports.DialogDescription = DialogDescription;
2444
+ exports.DialogFooter = DialogFooter;
2445
+ exports.DialogHeader = DialogHeader;
2446
+ exports.DialogOverlay = DialogOverlay;
2447
+ exports.DialogPortal = DialogPortal;
2448
+ exports.DialogTitle = DialogTitle;
2449
+ exports.DialogTrigger = DialogTrigger;
2450
+ exports.DropdownMenu = DropdownMenu;
2451
+ exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem;
2452
+ exports.DropdownMenuContent = DropdownMenuContent;
2453
+ exports.DropdownMenuGroup = DropdownMenuGroup;
2454
+ exports.DropdownMenuItem = DropdownMenuItem;
2455
+ exports.DropdownMenuLabel = DropdownMenuLabel;
2456
+ exports.DropdownMenuPortal = DropdownMenuPortal;
2457
+ exports.DropdownMenuRadioGroup = DropdownMenuRadioGroup;
2458
+ exports.DropdownMenuRadioItem = DropdownMenuRadioItem;
2459
+ exports.DropdownMenuSeparator = DropdownMenuSeparator;
2460
+ exports.DropdownMenuShortcut = DropdownMenuShortcut;
2461
+ exports.DropdownMenuSub = DropdownMenuSub;
2462
+ exports.DropdownMenuSubContent = DropdownMenuSubContent;
2463
+ exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger;
2464
+ exports.DropdownMenuTrigger = DropdownMenuTrigger;
2465
+ exports.FilterButtonGroup = FilterButtonGroup;
2466
+ exports.GenericOrderManager = GenericOrderManager;
2467
+ exports.Grid = Grid;
2468
+ exports.ImageMappingPanel = ImageMappingPanel;
2469
+ exports.Input = Input;
2470
+ exports.Label = Label;
2471
+ exports.LocalImageMappingPanel = LocalImageMappingPanel;
2472
+ exports.Modal = Modal;
2473
+ exports.Popover = Popover;
2474
+ exports.PopoverAnchor = PopoverAnchor;
2475
+ exports.PopoverContent = PopoverContent;
2476
+ exports.PopoverTrigger = PopoverTrigger;
2477
+ exports.Progress = Progress;
2478
+ exports.ScrollArea = ScrollArea;
2479
+ exports.ScrollBar = ScrollBar;
2480
+ exports.SearchBox = SearchBox;
2481
+ exports.SearchResultHint = SearchResultHint;
2482
+ exports.Select = Select;
2483
+ exports.SelectContent = SelectContent;
2484
+ exports.SelectGroup = SelectGroup;
2485
+ exports.SelectItem = SelectItem;
2486
+ exports.SelectLabel = SelectLabel;
2487
+ exports.SelectScrollDownButton = SelectScrollDownButton;
2488
+ exports.SelectScrollUpButton = SelectScrollUpButton;
2489
+ exports.SelectSeparator = SelectSeparator;
2490
+ exports.SelectTrigger = SelectTrigger;
2491
+ exports.SelectValue = SelectValue;
2492
+ exports.Separator = Separator;
2493
+ exports.Sheet = Dialog;
2494
+ exports.SheetClose = DialogClose;
2495
+ exports.SheetContent = SheetContent;
2496
+ exports.SheetDescription = SheetDescription;
2497
+ exports.SheetFooter = SheetFooter;
2498
+ exports.SheetHeader = SheetHeader;
2499
+ exports.SheetOverlay = DialogOverlay;
2500
+ exports.SheetPortal = DialogPortal;
2501
+ exports.SheetTitle = SheetTitle;
2502
+ exports.SheetTrigger = DialogTrigger;
2503
+ exports.Tabs = Tabs;
2504
+ exports.TabsContent = TabsContent;
2505
+ exports.TabsList = TabsList;
2506
+ exports.TabsTrigger = TabsTrigger;
2507
+ exports.Textarea = Textarea;
2508
+ exports.Timeline = Timeline;
2509
+ exports.Tooltip = Tooltip;
2510
+ exports.TooltipContent = TooltipContent;
2511
+ exports.TooltipProvider = TooltipProvider;
2512
+ exports.TooltipTrigger = TooltipTrigger;
2513
+ exports.badgeVariants = badgeVariants;
2514
+ exports.buttonVariants = buttonVariants;
2515
+ //# sourceMappingURL=index.js.map
2516
+ //# sourceMappingURL=index.js.map