sa2kit 1.6.68 → 1.6.69

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 (41) hide show
  1. package/dist/festivalCard/core/index.d.mts +8 -0
  2. package/dist/festivalCard/core/index.d.ts +8 -0
  3. package/dist/festivalCard/core/index.js +181 -0
  4. package/dist/festivalCard/core/index.js.map +1 -0
  5. package/dist/festivalCard/core/index.mjs +177 -0
  6. package/dist/festivalCard/core/index.mjs.map +1 -0
  7. package/dist/festivalCard/index.d.mts +5 -10
  8. package/dist/festivalCard/index.d.ts +5 -10
  9. package/dist/festivalCard/index.js +549 -173
  10. package/dist/festivalCard/index.js.map +1 -1
  11. package/dist/festivalCard/index.mjs +539 -153
  12. package/dist/festivalCard/index.mjs.map +1 -1
  13. package/dist/festivalCard/miniapp/index.d.mts +12 -0
  14. package/dist/festivalCard/miniapp/index.d.ts +12 -0
  15. package/dist/festivalCard/miniapp/index.js +341 -0
  16. package/dist/festivalCard/miniapp/index.js.map +1 -0
  17. package/dist/festivalCard/miniapp/index.mjs +329 -0
  18. package/dist/festivalCard/miniapp/index.mjs.map +1 -0
  19. package/dist/festivalCard/server/index.d.mts +6 -0
  20. package/dist/festivalCard/server/index.d.ts +6 -0
  21. package/dist/festivalCard/server/index.js +13 -0
  22. package/dist/festivalCard/server/index.js.map +1 -0
  23. package/dist/festivalCard/server/index.mjs +10 -0
  24. package/dist/festivalCard/server/index.mjs.map +1 -0
  25. package/dist/festivalCard/web/index.d.mts +31 -0
  26. package/dist/festivalCard/web/index.d.ts +31 -0
  27. package/dist/festivalCard/web/index.js +582 -0
  28. package/dist/festivalCard/web/index.js.map +1 -0
  29. package/dist/festivalCard/web/index.mjs +567 -0
  30. package/dist/festivalCard/web/index.mjs.map +1 -0
  31. package/dist/festivalCardService-C0fhTezx.d.ts +25 -0
  32. package/dist/festivalCardService-uSg0oNuD.d.mts +25 -0
  33. package/dist/index.d.mts +4 -1
  34. package/dist/index.d.ts +4 -1
  35. package/dist/index.js +562 -164
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +552 -163
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/types-B-tjQTGi.d.mts +62 -0
  40. package/dist/types-B-tjQTGi.d.ts +62 -0
  41. package/package.json +21 -1
package/dist/index.mjs CHANGED
@@ -16,7 +16,7 @@ import { sql, relations } from 'drizzle-orm';
16
16
  import 'crypto';
17
17
  import 'bcryptjs';
18
18
  import 'jsonwebtoken';
19
- import * as THREE3 from 'three';
19
+ import * as THREE2 from 'three';
20
20
 
21
21
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
22
22
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -5839,7 +5839,7 @@ function createCircularSpriteTexture() {
5839
5839
  canvas.height = size;
5840
5840
  const ctx = canvas.getContext("2d");
5841
5841
  if (!ctx) {
5842
- return new THREE3.CanvasTexture(canvas);
5842
+ return new THREE2.CanvasTexture(canvas);
5843
5843
  }
5844
5844
  const center = size / 2;
5845
5845
  const gradient = ctx.createRadialGradient(center, center, 2, center, center, center);
@@ -5848,7 +5848,7 @@ function createCircularSpriteTexture() {
5848
5848
  gradient.addColorStop(1, "rgba(255,255,255,0)");
5849
5849
  ctx.fillStyle = gradient;
5850
5850
  ctx.fillRect(0, 0, size, size);
5851
- const texture = new THREE3.CanvasTexture(canvas);
5851
+ const texture = new THREE2.CanvasTexture(canvas);
5852
5852
  texture.needsUpdate = true;
5853
5853
  return texture;
5854
5854
  }
@@ -6055,11 +6055,11 @@ var FireworksEngine = class {
6055
6055
  this.maxActiveFireworks = init.options?.maxActiveFireworks ?? DEFAULT_MAX_ACTIVE_FIREWORKS;
6056
6056
  this.onError = init.options?.onError;
6057
6057
  this.onFpsReport = init.options?.onFpsReport;
6058
- this.scene = new THREE3.Scene();
6059
- this.scene.background = new THREE3.Color("#060816");
6060
- this.camera = new THREE3.PerspectiveCamera(50, 1, 0.1, 1e3);
6058
+ this.scene = new THREE2.Scene();
6059
+ this.scene.background = new THREE2.Color("#060816");
6060
+ this.camera = new THREE2.PerspectiveCamera(50, 1, 0.1, 1e3);
6061
6061
  this.camera.position.set(0, 0, 45);
6062
- this.renderer = new THREE3.WebGLRenderer({
6062
+ this.renderer = new THREE2.WebGLRenderer({
6063
6063
  canvas: this.canvas,
6064
6064
  alpha: true,
6065
6065
  antialias: true,
@@ -6104,7 +6104,7 @@ var FireworksEngine = class {
6104
6104
  const particles = [];
6105
6105
  const positions = new Float32Array(seeds.length * 3);
6106
6106
  const colors = new Float32Array(seeds.length * 3);
6107
- const colorHelper = new THREE3.Color();
6107
+ const colorHelper = new THREE2.Color();
6108
6108
  for (let i = 0; i < seeds.length; i += 1) {
6109
6109
  const seed = seeds[i];
6110
6110
  if (!seed) {
@@ -6136,19 +6136,19 @@ var FireworksEngine = class {
6136
6136
  this.releaseParticles(particles);
6137
6137
  return;
6138
6138
  }
6139
- const geometry = new THREE3.BufferGeometry();
6140
- geometry.setAttribute("position", new THREE3.BufferAttribute(positions, 3));
6141
- geometry.setAttribute("color", new THREE3.BufferAttribute(colors, 3));
6142
- const material = new THREE3.PointsMaterial({
6139
+ const geometry = new THREE2.BufferGeometry();
6140
+ geometry.setAttribute("position", new THREE2.BufferAttribute(positions, 3));
6141
+ geometry.setAttribute("color", new THREE2.BufferAttribute(colors, 3));
6142
+ const material = new THREE2.PointsMaterial({
6143
6143
  size: payload.kind === "miku" ? 0.42 : 0.36,
6144
6144
  vertexColors: true,
6145
6145
  map: this.spriteTexture,
6146
6146
  transparent: true,
6147
6147
  opacity: 1,
6148
6148
  depthWrite: false,
6149
- blending: THREE3.AdditiveBlending
6149
+ blending: THREE2.AdditiveBlending
6150
6150
  });
6151
- const points = new THREE3.Points(geometry, material);
6151
+ const points = new THREE2.Points(geometry, material);
6152
6152
  this.scene.add(points);
6153
6153
  const burst = {
6154
6154
  id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
@@ -7129,179 +7129,568 @@ function ScreenReceiverPanel(props) {
7129
7129
  function StatusItem({ label, value }) {
7130
7130
  return /* @__PURE__ */ React42__default.createElement("div", { className: "rounded-md border px-3 py-2" }, /* @__PURE__ */ React42__default.createElement("p", { className: "text-xs text-slate-500" }, label), /* @__PURE__ */ React42__default.createElement("p", { className: "text-sm font-medium" }, value));
7131
7131
  }
7132
- var createSnow = (count) => {
7133
- const positions = new Float32Array(count * 3);
7134
- const speeds = new Float32Array(count);
7135
- for (let i = 0; i < count; i++) {
7136
- const i3 = i * 3;
7137
- positions[i3] = (Math.random() - 0.5) * 16;
7138
- positions[i3 + 1] = Math.random() * 10 + 1;
7139
- positions[i3 + 2] = (Math.random() - 0.5) * 16;
7140
- speeds[i] = 4e-3 + Math.random() * 0.01;
7141
- }
7142
- return { positions, speeds };
7132
+
7133
+ // src/festivalCard/core/defaults.ts
7134
+ var DEFAULT_FESTIVAL_CARD_CONFIG = {
7135
+ id: "default-festival-card",
7136
+ name: "Holiday Card",
7137
+ theme: "winter",
7138
+ coverTitle: "Happy Holidays",
7139
+ coverSubtitle: "Warm wishes for you",
7140
+ background: {
7141
+ colorA: "#0c1a34",
7142
+ colorB: "#1f4f8a"
7143
+ },
7144
+ backgroundMusic: {
7145
+ src: "",
7146
+ loop: true,
7147
+ autoPlay: false,
7148
+ volume: 0.5
7149
+ },
7150
+ pages: [
7151
+ {
7152
+ id: "page-1",
7153
+ title: "\u5C01\u9762",
7154
+ background: { color: "#11284d" },
7155
+ elements: [
7156
+ {
7157
+ id: "p1-text-1",
7158
+ type: "text",
7159
+ x: 50,
7160
+ y: 20,
7161
+ content: "\u65B0\u5E74\u5FEB\u4E50",
7162
+ fontSize: 34,
7163
+ fontWeight: 700,
7164
+ align: "center",
7165
+ color: "#f8fafc"
7166
+ },
7167
+ {
7168
+ id: "p1-text-2",
7169
+ type: "text",
7170
+ x: 50,
7171
+ y: 36,
7172
+ content: "\u613F\u8FD9\u4E00\u5E74\u5E73\u5B89\u559C\u4E50",
7173
+ fontSize: 18,
7174
+ fontWeight: 500,
7175
+ align: "center",
7176
+ color: "#dbeafe"
7177
+ },
7178
+ {
7179
+ id: "p1-image-1",
7180
+ type: "image",
7181
+ x: 50,
7182
+ y: 68,
7183
+ width: 72,
7184
+ height: 42,
7185
+ src: "https://images.unsplash.com/photo-1512389142860-9c449e58a543?auto=format&fit=crop&w=1200&q=80",
7186
+ fit: "cover",
7187
+ borderRadius: 16,
7188
+ alt: "holiday"
7189
+ }
7190
+ ]
7191
+ },
7192
+ {
7193
+ id: "page-2",
7194
+ title: "\u795D\u798F",
7195
+ background: { color: "#1a3766" },
7196
+ elements: [
7197
+ {
7198
+ id: "p2-text-1",
7199
+ type: "text",
7200
+ x: 50,
7201
+ y: 28,
7202
+ content: "\u613F\u4F60\u65B0\u5C81\uFF1A",
7203
+ fontSize: 28,
7204
+ fontWeight: 700,
7205
+ align: "center",
7206
+ color: "#fef3c7"
7207
+ },
7208
+ {
7209
+ id: "p2-text-2",
7210
+ type: "text",
7211
+ x: 50,
7212
+ y: 42,
7213
+ content: "\u6240\u5F97\u7686\u6240\u671F\uFF0C\u6240\u5931\u4EA6\u65E0\u788D",
7214
+ fontSize: 18,
7215
+ fontWeight: 500,
7216
+ align: "center",
7217
+ color: "#f8fafc"
7218
+ },
7219
+ {
7220
+ id: "p2-text-3",
7221
+ type: "text",
7222
+ x: 50,
7223
+ y: 55,
7224
+ content: "\u613F\u4F60\u7684\u6BCF\u4E00\u6B65\u90FD\u8D70\u5411\u5149\u4EAE",
7225
+ fontSize: 16,
7226
+ fontWeight: 400,
7227
+ align: "center",
7228
+ color: "#dbeafe"
7229
+ }
7230
+ ]
7231
+ },
7232
+ {
7233
+ id: "page-3",
7234
+ title: "\u843D\u6B3E",
7235
+ background: { color: "#11284d" },
7236
+ elements: [
7237
+ {
7238
+ id: "p3-image-1",
7239
+ type: "image",
7240
+ x: 50,
7241
+ y: 34,
7242
+ width: 60,
7243
+ height: 42,
7244
+ src: "https://images.unsplash.com/photo-1456324504439-367cee3b3c32?auto=format&fit=crop&w=1200&q=80",
7245
+ fit: "cover",
7246
+ borderRadius: 14,
7247
+ alt: "gift"
7248
+ },
7249
+ {
7250
+ id: "p3-text-1",
7251
+ type: "text",
7252
+ x: 50,
7253
+ y: 72,
7254
+ content: "Best wishes, from SA2Kit",
7255
+ fontSize: 18,
7256
+ fontWeight: 600,
7257
+ align: "center",
7258
+ color: "#f8fafc"
7259
+ }
7260
+ ]
7261
+ }
7262
+ ]
7143
7263
  };
7144
- var FestivalCard3D = ({
7145
- title = "Happy Holidays",
7146
- subtitle = "Wishing you joy and peace",
7147
- className
7148
- }) => {
7149
- const mountRef = useRef(null);
7264
+
7265
+ // src/festivalCard/core/normalize.ts
7266
+ var ensurePage = (page, index) => ({
7267
+ id: page.id || `page-${index + 1}`,
7268
+ title: page.title || `\u7B2C ${index + 1} \u9875`,
7269
+ elements: Array.isArray(page.elements) ? page.elements : [],
7270
+ background: page.background || {}
7271
+ });
7272
+ var normalizeFestivalCardConfig = (config) => {
7273
+ const pages = config?.pages && config.pages.length > 0 ? config.pages : DEFAULT_FESTIVAL_CARD_CONFIG.pages;
7274
+ return {
7275
+ ...DEFAULT_FESTIVAL_CARD_CONFIG,
7276
+ ...config,
7277
+ background: {
7278
+ ...DEFAULT_FESTIVAL_CARD_CONFIG.background,
7279
+ ...config?.background || {}
7280
+ },
7281
+ backgroundMusic: {
7282
+ ...DEFAULT_FESTIVAL_CARD_CONFIG.backgroundMusic,
7283
+ ...config?.backgroundMusic || {},
7284
+ src: config?.backgroundMusic?.src ?? DEFAULT_FESTIVAL_CARD_CONFIG.backgroundMusic?.src ?? ""
7285
+ },
7286
+ pages: pages.map(ensurePage)
7287
+ };
7288
+ };
7289
+ var resizeFestivalCardPages = (config, pageCount) => {
7290
+ const safeCount = Math.max(1, Math.min(12, Math.floor(pageCount || 1)));
7291
+ const nextPages = [...config.pages];
7292
+ while (nextPages.length < safeCount) {
7293
+ const idx = nextPages.length;
7294
+ nextPages.push({
7295
+ id: `page-${idx + 1}`,
7296
+ title: `\u7B2C ${idx + 1} \u9875`,
7297
+ elements: [],
7298
+ background: {}
7299
+ });
7300
+ }
7301
+ return {
7302
+ ...config,
7303
+ pages: nextPages.slice(0, safeCount)
7304
+ };
7305
+ };
7306
+ var useFestivalCardConfig = (options) => {
7307
+ const [config, setConfig] = useState(
7308
+ () => normalizeFestivalCardConfig(options?.initialConfig || DEFAULT_FESTIVAL_CARD_CONFIG)
7309
+ );
7310
+ const [loading, setLoading] = useState(Boolean(options?.fetchConfig));
7311
+ const [saving, setSaving] = useState(false);
7150
7312
  useEffect(() => {
7151
- const mount = mountRef.current;
7152
- if (!mount) return;
7153
- const scene = new THREE3.Scene();
7154
- scene.fog = new THREE3.Fog(528934, 12, 28);
7155
- const camera = new THREE3.PerspectiveCamera(50, mount.clientWidth / mount.clientHeight, 0.1, 100);
7156
- camera.position.set(0, 2.6, 7.5);
7157
- const renderer = new THREE3.WebGLRenderer({ antialias: true, alpha: true });
7158
- renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
7159
- renderer.setSize(mount.clientWidth, mount.clientHeight);
7160
- renderer.outputColorSpace = THREE3.SRGBColorSpace;
7161
- mount.appendChild(renderer.domElement);
7162
- const ambientLight = new THREE3.AmbientLight(9090303, 0.8);
7163
- scene.add(ambientLight);
7164
- const keyLight = new THREE3.DirectionalLight(16777215, 1.25);
7165
- keyLight.position.set(2, 5, 4);
7166
- scene.add(keyLight);
7167
- const fillLight = new THREE3.PointLight(8050687, 0.9, 24);
7168
- fillLight.position.set(-4, 3, -2);
7169
- scene.add(fillLight);
7170
- const floor = new THREE3.Mesh(
7171
- new THREE3.CircleGeometry(12, 48),
7172
- new THREE3.MeshStandardMaterial({ color: 1056826, roughness: 0.95, metalness: 0.05 })
7173
- );
7174
- floor.rotation.x = -Math.PI / 2;
7175
- floor.position.y = -1.2;
7176
- scene.add(floor);
7177
- const giftGroup = new THREE3.Group();
7178
- scene.add(giftGroup);
7179
- const box = new THREE3.Mesh(
7180
- new THREE3.BoxGeometry(2, 1.6, 2),
7181
- new THREE3.MeshStandardMaterial({ color: 14238053, roughness: 0.55, metalness: 0.2 })
7182
- );
7183
- giftGroup.add(box);
7184
- const ribbonMaterial = new THREE3.MeshStandardMaterial({ color: 16767354, roughness: 0.3, metalness: 0.5 });
7185
- const verticalRibbon = new THREE3.Mesh(new THREE3.BoxGeometry(0.24, 1.7, 2.02), ribbonMaterial);
7186
- const horizontalRibbon = new THREE3.Mesh(new THREE3.BoxGeometry(2.02, 1.7, 0.24), ribbonMaterial);
7187
- giftGroup.add(verticalRibbon);
7188
- giftGroup.add(horizontalRibbon);
7189
- const lid = new THREE3.Mesh(
7190
- new THREE3.BoxGeometry(2.15, 0.34, 2.15),
7191
- new THREE3.MeshStandardMaterial({ color: 13448278, roughness: 0.52, metalness: 0.2 })
7192
- );
7193
- lid.position.y = 0.98;
7194
- giftGroup.add(lid);
7195
- const bowLeft = new THREE3.Mesh(new THREE3.TorusGeometry(0.26, 0.08, 12, 32), ribbonMaterial);
7196
- bowLeft.rotation.set(Math.PI / 2, Math.PI / 6, 0);
7197
- bowLeft.position.set(-0.22, 1.14, 0);
7198
- const bowRight = bowLeft.clone();
7199
- bowRight.rotation.y = -Math.PI / 6;
7200
- bowRight.position.x = 0.22;
7201
- giftGroup.add(bowLeft, bowRight);
7202
- giftGroup.position.y = -0.15;
7203
- const { positions, speeds } = createSnow(260);
7204
- const snowGeometry = new THREE3.BufferGeometry();
7205
- snowGeometry.setAttribute("position", new THREE3.BufferAttribute(positions, 3));
7206
- const snow = new THREE3.Points(
7207
- snowGeometry,
7208
- new THREE3.PointsMaterial({
7209
- color: 15267071,
7210
- size: 0.08,
7211
- transparent: true,
7212
- opacity: 0.92,
7213
- depthWrite: false
7214
- })
7215
- );
7216
- scene.add(snow);
7217
- let rafId = 0;
7218
- const clock = new THREE3.Clock();
7219
- const animate = () => {
7220
- const elapsed = clock.getElapsedTime();
7221
- const pos = snowGeometry.attributes.position;
7222
- for (let i = 0; i < pos.count; i++) {
7223
- const speed = speeds[i] ?? 0.01;
7224
- const y = pos.getY(i) - speed;
7225
- pos.setY(i, y < -1.1 ? 10 + Math.random() * 2 : y);
7226
- pos.setX(i, pos.getX(i) + Math.sin(elapsed + i * 0.04) * 16e-4);
7227
- }
7228
- pos.needsUpdate = true;
7229
- giftGroup.rotation.y = elapsed * 0.35;
7230
- giftGroup.position.y = -0.15 + Math.sin(elapsed * 1.4) * 0.08;
7231
- lid.position.y = 0.98 + Math.sin(elapsed * 2.2) * 0.08;
7232
- renderer.render(scene, camera);
7233
- rafId = window.requestAnimationFrame(animate);
7234
- };
7235
- const handleResize = () => {
7236
- if (!mount) return;
7237
- const width = mount.clientWidth;
7238
- const height = mount.clientHeight;
7239
- camera.aspect = width / height;
7240
- camera.updateProjectionMatrix();
7241
- renderer.setSize(width, height);
7242
- };
7243
- window.addEventListener("resize", handleResize);
7244
- animate();
7313
+ if (!options?.fetchConfig) return;
7314
+ let active = true;
7315
+ void options.fetchConfig().then((value) => {
7316
+ if (!active) return;
7317
+ setConfig(normalizeFestivalCardConfig(value));
7318
+ }).finally(() => {
7319
+ if (active) setLoading(false);
7320
+ });
7245
7321
  return () => {
7246
- window.cancelAnimationFrame(rafId);
7247
- window.removeEventListener("resize", handleResize);
7248
- scene.traverse((obj) => {
7249
- const mesh = obj;
7250
- if (mesh.geometry) mesh.geometry.dispose();
7251
- const material = mesh.material;
7252
- if (Array.isArray(material)) material.forEach((m) => m.dispose());
7253
- else material?.dispose();
7254
- });
7255
- renderer.dispose();
7256
- mount.removeChild(renderer.domElement);
7322
+ active = false;
7257
7323
  };
7258
- }, []);
7324
+ }, [options]);
7325
+ const save = useCallback(async () => {
7326
+ if (!options?.onSave) return;
7327
+ setSaving(true);
7328
+ try {
7329
+ await options.onSave(config);
7330
+ } finally {
7331
+ setSaving(false);
7332
+ }
7333
+ }, [config, options]);
7334
+ return useMemo(
7335
+ () => ({
7336
+ config,
7337
+ setConfig,
7338
+ loading,
7339
+ saving,
7340
+ save
7341
+ }),
7342
+ [config, loading, save, saving]
7343
+ );
7344
+ };
7345
+ var elementStyle = (element) => ({
7346
+ position: "absolute",
7347
+ left: `${element.x}%`,
7348
+ top: `${element.y}%`,
7349
+ width: `${element.width ?? 70}%`,
7350
+ height: element.height ? `${element.height}%` : void 0,
7351
+ transform: "translate(-50%, -50%)"
7352
+ });
7353
+ var renderElement = (element) => {
7354
+ if (element.type === "text") {
7355
+ return /* @__PURE__ */ React42__default.createElement(
7356
+ "div",
7357
+ {
7358
+ key: element.id,
7359
+ style: {
7360
+ ...elementStyle(element),
7361
+ color: element.color || "#f8fafc",
7362
+ fontSize: element.fontSize || 18,
7363
+ fontWeight: element.fontWeight || 500,
7364
+ textAlign: element.align || "left",
7365
+ lineHeight: 1.45,
7366
+ whiteSpace: "pre-wrap"
7367
+ }
7368
+ },
7369
+ element.content
7370
+ );
7371
+ }
7372
+ return /* @__PURE__ */ React42__default.createElement(
7373
+ "img",
7374
+ {
7375
+ key: element.id,
7376
+ src: element.src,
7377
+ alt: element.alt || "festival-card-image",
7378
+ style: {
7379
+ ...elementStyle(element),
7380
+ objectFit: element.fit || "cover",
7381
+ borderRadius: element.borderRadius || 0,
7382
+ overflow: "hidden",
7383
+ boxShadow: "0 12px 30px rgba(2, 6, 23, 0.32)"
7384
+ }
7385
+ }
7386
+ );
7387
+ };
7388
+ var FestivalCardPageRenderer = ({ page }) => {
7259
7389
  return /* @__PURE__ */ React42__default.createElement(
7260
7390
  "div",
7261
7391
  {
7262
- className,
7263
7392
  style: {
7264
7393
  position: "relative",
7265
7394
  width: "100%",
7266
- minHeight: 420,
7267
- borderRadius: 20,
7395
+ height: "100%",
7268
7396
  overflow: "hidden",
7269
- background: "radial-gradient(circle at 20% 20%, #244d8c 0%, #0c1a34 45%, #060d1f 100%)"
7397
+ borderRadius: 16,
7398
+ backgroundColor: page.background?.color || "#0f172a",
7399
+ backgroundImage: page.background?.image ? `url(${page.background.image})` : void 0,
7400
+ backgroundSize: "cover",
7401
+ backgroundPosition: "center"
7402
+ }
7403
+ },
7404
+ page.elements.map(renderElement)
7405
+ );
7406
+ };
7407
+
7408
+ // src/festivalCard/components/FestivalCardBook3D.tsx
7409
+ var FestivalCardBook3D = ({ config, className }) => {
7410
+ const [currentPage, setCurrentPage] = useState(0);
7411
+ const normalized = useMemo(() => normalizeFestivalCardConfig(config), [config]);
7412
+ const pages = normalized.pages;
7413
+ const canPrev = currentPage > 0;
7414
+ const canNext = currentPage < pages.length - 1;
7415
+ return /* @__PURE__ */ React42__default.createElement("div", { className }, /* @__PURE__ */ React42__default.createElement(
7416
+ "div",
7417
+ {
7418
+ style: {
7419
+ width: "100%",
7420
+ minHeight: 560,
7421
+ borderRadius: 24,
7422
+ padding: 24,
7423
+ background: `linear-gradient(145deg, ${normalized.background?.colorA || "#0c1a34"} 0%, ${normalized.background?.colorB || "#1f4f8a"} 100%)`,
7424
+ boxShadow: "0 26px 70px rgba(2, 6, 23, 0.45)"
7270
7425
  }
7271
7426
  },
7272
- /* @__PURE__ */ React42__default.createElement("div", { ref: mountRef, style: { position: "absolute", inset: 0 } }),
7273
7427
  /* @__PURE__ */ React42__default.createElement(
7274
7428
  "div",
7275
7429
  {
7276
7430
  style: {
7277
- position: "absolute",
7278
- inset: 0,
7279
- pointerEvents: "none",
7280
- background: "linear-gradient(180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.04) 35%, rgba(4,8,20,0.36) 100%)"
7431
+ marginBottom: 14,
7432
+ color: "#f8fafc",
7433
+ fontSize: 14,
7434
+ opacity: 0.9,
7435
+ textAlign: "center"
7281
7436
  }
7282
- }
7437
+ },
7438
+ normalized.coverTitle || "Festival Card",
7439
+ " \xB7 \u7B2C ",
7440
+ currentPage + 1,
7441
+ " / ",
7442
+ pages.length,
7443
+ " \u9875"
7283
7444
  ),
7284
- /* @__PURE__ */ React42__default.createElement(
7445
+ /* @__PURE__ */ React42__default.createElement("div", { style: { perspective: 1400, width: "100%", maxWidth: 920, margin: "0 auto" } }, /* @__PURE__ */ React42__default.createElement(
7285
7446
  "div",
7286
7447
  {
7287
7448
  style: {
7288
- position: "absolute",
7289
- left: 20,
7290
- right: 20,
7291
- bottom: 20,
7292
- zIndex: 2,
7293
- padding: "16px 18px",
7294
- borderRadius: 14,
7295
- backgroundColor: "rgba(8, 16, 35, 0.66)",
7296
- border: "1px solid rgba(255, 255, 255, 0.16)",
7297
- color: "#f8fafc"
7449
+ position: "relative",
7450
+ height: 460,
7451
+ transformStyle: "preserve-3d"
7298
7452
  }
7299
7453
  },
7300
- /* @__PURE__ */ React42__default.createElement("div", { style: { fontSize: 26, fontWeight: 700, lineHeight: 1.2 } }, title),
7301
- /* @__PURE__ */ React42__default.createElement("div", { style: { marginTop: 6, fontSize: 15, opacity: 0.92 } }, subtitle)
7302
- )
7303
- );
7454
+ pages.map((page, index) => {
7455
+ const isFlipped = index < currentPage;
7456
+ const zIndex = pages.length - index;
7457
+ return /* @__PURE__ */ React42__default.createElement(
7458
+ "div",
7459
+ {
7460
+ key: page.id,
7461
+ style: {
7462
+ position: "absolute",
7463
+ inset: 0,
7464
+ transformStyle: "preserve-3d",
7465
+ transformOrigin: "left center",
7466
+ transform: `rotateY(${isFlipped ? -170 : 0}deg)`,
7467
+ transition: "transform 600ms cubic-bezier(0.2, 0.8, 0.2, 1)",
7468
+ zIndex
7469
+ }
7470
+ },
7471
+ /* @__PURE__ */ React42__default.createElement(
7472
+ "div",
7473
+ {
7474
+ style: {
7475
+ position: "absolute",
7476
+ inset: 0,
7477
+ backfaceVisibility: "hidden"
7478
+ }
7479
+ },
7480
+ /* @__PURE__ */ React42__default.createElement(FestivalCardPageRenderer, { page })
7481
+ ),
7482
+ /* @__PURE__ */ React42__default.createElement(
7483
+ "div",
7484
+ {
7485
+ style: {
7486
+ position: "absolute",
7487
+ inset: 0,
7488
+ transform: "rotateY(180deg)",
7489
+ backfaceVisibility: "hidden",
7490
+ borderRadius: 16,
7491
+ background: "#0f172a"
7492
+ }
7493
+ }
7494
+ )
7495
+ );
7496
+ })
7497
+ )),
7498
+ /* @__PURE__ */ React42__default.createElement("div", { style: { display: "flex", justifyContent: "center", gap: 12, marginTop: 18 } }, /* @__PURE__ */ React42__default.createElement(
7499
+ "button",
7500
+ {
7501
+ type: "button",
7502
+ disabled: !canPrev,
7503
+ onClick: () => setCurrentPage((p) => Math.max(0, p - 1)),
7504
+ style: {
7505
+ border: "none",
7506
+ borderRadius: 999,
7507
+ padding: "9px 16px",
7508
+ fontSize: 14,
7509
+ cursor: canPrev ? "pointer" : "not-allowed",
7510
+ opacity: canPrev ? 1 : 0.4
7511
+ }
7512
+ },
7513
+ "\u4E0A\u4E00\u9875"
7514
+ ), /* @__PURE__ */ React42__default.createElement(
7515
+ "button",
7516
+ {
7517
+ type: "button",
7518
+ disabled: !canNext,
7519
+ onClick: () => setCurrentPage((p) => Math.min(pages.length - 1, p + 1)),
7520
+ style: {
7521
+ border: "none",
7522
+ borderRadius: 999,
7523
+ padding: "9px 16px",
7524
+ fontSize: 14,
7525
+ cursor: canNext ? "pointer" : "not-allowed",
7526
+ opacity: canNext ? 1 : 0.4
7527
+ }
7528
+ },
7529
+ "\u4E0B\u4E00\u9875"
7530
+ ))
7531
+ ), normalized.backgroundMusic?.src ? /* @__PURE__ */ React42__default.createElement(
7532
+ "audio",
7533
+ {
7534
+ src: normalized.backgroundMusic.src,
7535
+ autoPlay: normalized.backgroundMusic.autoPlay,
7536
+ loop: normalized.backgroundMusic.loop,
7537
+ controls: true,
7538
+ style: { width: "100%", marginTop: 10 }
7539
+ }
7540
+ ) : null);
7304
7541
  };
7542
+ var createTextElement = (pageIndex) => ({
7543
+ id: `text-${Date.now()}-${pageIndex}`,
7544
+ type: "text",
7545
+ x: 50,
7546
+ y: 50,
7547
+ content: "\u8BF7\u8F93\u5165\u6587\u5B57",
7548
+ fontSize: 18,
7549
+ fontWeight: 500,
7550
+ align: "center",
7551
+ color: "#ffffff"
7552
+ });
7553
+ var createImageElement = (pageIndex) => ({
7554
+ id: `image-${Date.now()}-${pageIndex}`,
7555
+ type: "image",
7556
+ x: 50,
7557
+ y: 50,
7558
+ width: 60,
7559
+ height: 40,
7560
+ src: "https://images.unsplash.com/photo-1482517967863-00e15c9b44be?auto=format&fit=crop&w=1200&q=80",
7561
+ fit: "cover",
7562
+ borderRadius: 12
7563
+ });
7564
+ var FestivalCardConfigEditor = ({ value, onChange }) => {
7565
+ const [activePageIndex, setActivePageIndex] = useState(0);
7566
+ const page = value.pages[activePageIndex];
7567
+ const canEditPage = Boolean(page);
7568
+ const pageOptions = useMemo(() => value.pages.map((_, index) => index), [value.pages]);
7569
+ const updateElement = (elementId, patch) => {
7570
+ onChange({
7571
+ ...value,
7572
+ pages: value.pages.map(
7573
+ (p, pIndex) => pIndex === activePageIndex ? {
7574
+ ...p,
7575
+ elements: p.elements.map((el) => el.id === elementId ? { ...el, ...patch } : el)
7576
+ } : p
7577
+ )
7578
+ });
7579
+ };
7580
+ return /* @__PURE__ */ React42__default.createElement("div", { style: { borderRadius: 16, background: "#0f172a", color: "#e2e8f0", padding: 16 } }, /* @__PURE__ */ React42__default.createElement("div", { style: { display: "grid", gap: 12 } }, /* @__PURE__ */ React42__default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React42__default.createElement("span", null, "\u9875\u9762\u6570\u91CF"), /* @__PURE__ */ React42__default.createElement(
7581
+ "input",
7582
+ {
7583
+ type: "number",
7584
+ min: 1,
7585
+ max: 12,
7586
+ value: value.pages.length,
7587
+ onChange: (event) => onChange(resizeFestivalCardPages(value, Number(event.target.value)))
7588
+ }
7589
+ )), /* @__PURE__ */ React42__default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React42__default.createElement("span", null, "\u80CC\u666F\u97F3\u4E50 URL"), /* @__PURE__ */ React42__default.createElement(
7590
+ "input",
7591
+ {
7592
+ type: "url",
7593
+ value: value.backgroundMusic?.src || "",
7594
+ onChange: (event) => onChange({
7595
+ ...value,
7596
+ backgroundMusic: {
7597
+ ...value.backgroundMusic,
7598
+ src: event.target.value
7599
+ }
7600
+ })
7601
+ }
7602
+ )), /* @__PURE__ */ React42__default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React42__default.createElement("span", null, "\u7F16\u8F91\u9875\u9762"), /* @__PURE__ */ React42__default.createElement("select", { value: activePageIndex, onChange: (event) => setActivePageIndex(Number(event.target.value)) }, pageOptions.map((index) => /* @__PURE__ */ React42__default.createElement("option", { key: index, value: index }, "\u7B2C ", index + 1, " \u9875"))))), canEditPage ? /* @__PURE__ */ React42__default.createElement("div", { style: { marginTop: 16 } }, /* @__PURE__ */ React42__default.createElement("div", { style: { display: "flex", gap: 8, marginBottom: 12 } }, /* @__PURE__ */ React42__default.createElement(
7603
+ "button",
7604
+ {
7605
+ type: "button",
7606
+ onClick: () => onChange({
7607
+ ...value,
7608
+ pages: value.pages.map(
7609
+ (p, index) => index === activePageIndex ? { ...p, elements: [...p.elements, createTextElement(index)] } : p
7610
+ )
7611
+ })
7612
+ },
7613
+ "+ \u6587\u5B57"
7614
+ ), /* @__PURE__ */ React42__default.createElement(
7615
+ "button",
7616
+ {
7617
+ type: "button",
7618
+ onClick: () => onChange({
7619
+ ...value,
7620
+ pages: value.pages.map(
7621
+ (p, index) => index === activePageIndex ? { ...p, elements: [...p.elements, createImageElement(index)] } : p
7622
+ )
7623
+ })
7624
+ },
7625
+ "+ \u56FE\u7247"
7626
+ )), /* @__PURE__ */ React42__default.createElement("div", { style: { display: "grid", gap: 10, maxHeight: 340, overflow: "auto" } }, (page?.elements ?? []).map((element) => /* @__PURE__ */ React42__default.createElement("div", { key: element.id, style: { border: "1px solid #334155", borderRadius: 10, padding: 10 } }, /* @__PURE__ */ React42__default.createElement("div", { style: { marginBottom: 8 } }, element.type.toUpperCase()), element.type === "text" ? /* @__PURE__ */ React42__default.createElement(
7627
+ "textarea",
7628
+ {
7629
+ value: element.content,
7630
+ onChange: (event) => updateElement(element.id, { content: event.target.value }),
7631
+ rows: 3,
7632
+ style: { width: "100%" }
7633
+ }
7634
+ ) : /* @__PURE__ */ React42__default.createElement(
7635
+ "input",
7636
+ {
7637
+ type: "url",
7638
+ value: element.src,
7639
+ onChange: (event) => updateElement(element.id, { src: event.target.value }),
7640
+ style: { width: "100%" }
7641
+ }
7642
+ ))))) : null);
7643
+ };
7644
+ var FestivalCardStudio = ({ initialConfig, fetchConfig, onSave }) => {
7645
+ const { config, setConfig, loading, save, saving } = useFestivalCardConfig({
7646
+ initialConfig: normalizeFestivalCardConfig(initialConfig),
7647
+ fetchConfig,
7648
+ onSave
7649
+ });
7650
+ if (loading) return /* @__PURE__ */ React42__default.createElement("div", null, "\u52A0\u8F7D\u4E2D...");
7651
+ return /* @__PURE__ */ React42__default.createElement("div", { style: { display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 16 } }, /* @__PURE__ */ React42__default.createElement(FestivalCardBook3D, { config }), /* @__PURE__ */ React42__default.createElement("div", null, /* @__PURE__ */ React42__default.createElement(FestivalCardConfigEditor, { value: config, onChange: setConfig }), onSave ? /* @__PURE__ */ React42__default.createElement(
7652
+ "button",
7653
+ {
7654
+ type: "button",
7655
+ onClick: () => void save(),
7656
+ disabled: saving,
7657
+ style: { marginTop: 12, width: "100%", padding: "10px 16px" }
7658
+ },
7659
+ saving ? "\u4FDD\u5B58\u4E2D..." : "\u4FDD\u5B58\u914D\u7F6E"
7660
+ ) : null));
7661
+ };
7662
+
7663
+ // src/festivalCard/server/db.ts
7664
+ var dbAdapter = null;
7665
+ var getFestivalCardDb = () => dbAdapter;
7666
+
7667
+ // src/festivalCard/services/festivalCardService.ts
7668
+ var FestivalCardService = class {
7669
+ constructor(options) {
7670
+ this.db = options?.db || getFestivalCardDb();
7671
+ }
7672
+ async getConfig(cardId = "default-festival-card") {
7673
+ if (!this.db) return DEFAULT_FESTIVAL_CARD_CONFIG;
7674
+ const config = await this.db.getConfig(cardId);
7675
+ return normalizeFestivalCardConfig(config);
7676
+ }
7677
+ async saveConfig(cardId, config) {
7678
+ const normalized = normalizeFestivalCardConfig(config);
7679
+ if (!this.db) return normalized;
7680
+ await this.db.saveConfig(cardId, normalized);
7681
+ return normalized;
7682
+ }
7683
+ };
7684
+ var memoryStore = /* @__PURE__ */ new Map();
7685
+ var createInMemoryFestivalCardDb = () => ({
7686
+ getConfig(id) {
7687
+ return Promise.resolve(memoryStore.get(id) || null);
7688
+ },
7689
+ saveConfig(id, config) {
7690
+ memoryStore.set(id, config);
7691
+ return Promise.resolve();
7692
+ }
7693
+ });
7305
7694
 
7306
7695
  // src/storage/adapters/react-native-adapter.ts
7307
7696
  var AsyncStorage = null;
@@ -7656,6 +8045,6 @@ function useElectronStorage(key, defaultValue) {
7656
8045
  return useStorage(electronStorage, key, defaultValue);
7657
8046
  }
7658
8047
 
7659
- export { About_default as About, Dialog as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, DialogDescription as AlertDialogDescription, DialogFooter as AlertDialogFooter, DialogHeader as AlertDialogHeader, DialogOverlay as AlertDialogOverlay, DialogPortal as AlertDialogPortal, DialogTitle as AlertDialogTitle, DialogTrigger as AlertDialogTrigger, AutoOpenModal, Avatar, AvatarFallback, AvatarImage, BackButton, BackgroundRemover, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryFilter, CollisionBalls, CompletionFilterComponent, ConfirmModal, ConsoleLoggerAdapter, Contact_default as Contact, DANMAKU_MAX_LENGTH, DANMAKU_TRACK_COUNT, DEFAULT_MAX_ACTIVE_FIREWORKS, DEFAULT_MAX_PARTICLES, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DanmakuPanel, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DraggableExperimentGrid, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EnhancedAvatar, ExperimentCard, ExperimentGrid, ExperimentItemGrid, FIREWORK_KIND_LABELS, FestivalCard3D, FilterButtonGroup, FireworksCanvas, FireworksControlPanel, FloatingMenu_default as FloatingMenu, FloatingMenuExample_default as FloatingMenuExample, GenericOrderManager, Grid, Home_default as Home, ImageMappingPanel, InMemorySkillRegistry, Input, Label, LocalImageMappingPanel, LogLevel, Logger, MIKU_PALETTE, MikuFireworks3D, Modal, NORMAL_PALETTE, Navigation_default as Navigation, NavigationItem_default as NavigationItem, NavigationToggle_default as NavigationToggle, OCRScanner, PageHeader, PermissionGuard, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProfileButton, ProfileModal, Progress, ProjectCarousel, ScreenReceiverPanel, ScrollArea, ScrollBar, SearchBox, SearchResultHint, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SentimentAnalyzer, Separator, Dialog as Sheet, DialogClose as SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, DialogOverlay as SheetOverlay, DialogPortal as SheetPortal, SheetTitle, DialogTrigger as SheetTrigger, SmartAssistant, SortControl, SortModeToggle, SortableExperimentItem, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Timeline, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserInfoBar, WebSocketTransport, applyPromptTemplate, arrayUtils, badgeVariants, buttonVariants, cn, createAiClient, createChatSession, createLogger, createOpenAICompatibleProvider, createSkillRegistry, debugUtils, errorUtils, fileUtils, filterExperiments, formatTime, getAllTags, getCategoryColor, getCategoryDisplayName, getCompletionFilterDisplayName, getCompletionStatusColor, getCompletionStatusText, getExperimentCounts, japaneseUtils, logger, normalizePromptVariables, resolveScreenReceiverSignalUrl, skillToToolDefinition, sortExperiments, stringUtils, useAiChat, useAsyncStorage, useBackgroundRemoval, useDanmakuController, useElectronStorage, useFireworksEngine, useFireworksRealtime, useLocalStorage, useOCR, useScreenReceiver, useSentimentAnalysis, useStorage, useTaroStorage, useTextGeneration, validateExperiment, validators };
8048
+ export { About_default as About, Dialog as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, DialogDescription as AlertDialogDescription, DialogFooter as AlertDialogFooter, DialogHeader as AlertDialogHeader, DialogOverlay as AlertDialogOverlay, DialogPortal as AlertDialogPortal, DialogTitle as AlertDialogTitle, DialogTrigger as AlertDialogTrigger, AutoOpenModal, Avatar, AvatarFallback, AvatarImage, BackButton, BackgroundRemover, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryFilter, CollisionBalls, CompletionFilterComponent, ConfirmModal, ConsoleLoggerAdapter, Contact_default as Contact, DANMAKU_MAX_LENGTH, DANMAKU_TRACK_COUNT, DEFAULT_FESTIVAL_CARD_CONFIG, DEFAULT_MAX_ACTIVE_FIREWORKS, DEFAULT_MAX_PARTICLES, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DanmakuPanel, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DraggableExperimentGrid, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EnhancedAvatar, ExperimentCard, ExperimentGrid, ExperimentItemGrid, FIREWORK_KIND_LABELS, FestivalCardBook3D, FestivalCardConfigEditor, FestivalCardPageRenderer, FestivalCardService, FestivalCardStudio, FilterButtonGroup, FireworksCanvas, FireworksControlPanel, FloatingMenu_default as FloatingMenu, FloatingMenuExample_default as FloatingMenuExample, GenericOrderManager, Grid, Home_default as Home, ImageMappingPanel, InMemorySkillRegistry, Input, Label, LocalImageMappingPanel, LogLevel, Logger, MIKU_PALETTE, MikuFireworks3D, Modal, NORMAL_PALETTE, Navigation_default as Navigation, NavigationItem_default as NavigationItem, NavigationToggle_default as NavigationToggle, OCRScanner, PageHeader, PermissionGuard, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProfileButton, ProfileModal, Progress, ProjectCarousel, ScreenReceiverPanel, ScrollArea, ScrollBar, SearchBox, SearchResultHint, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SentimentAnalyzer, Separator, Dialog as Sheet, DialogClose as SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, DialogOverlay as SheetOverlay, DialogPortal as SheetPortal, SheetTitle, DialogTrigger as SheetTrigger, SmartAssistant, SortControl, SortModeToggle, SortableExperimentItem, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Timeline, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserInfoBar, WebSocketTransport, applyPromptTemplate, arrayUtils, badgeVariants, buttonVariants, cn, createAiClient, createChatSession, createInMemoryFestivalCardDb, createLogger, createOpenAICompatibleProvider, createSkillRegistry, debugUtils, errorUtils, fileUtils, filterExperiments, formatTime, getAllTags, getCategoryColor, getCategoryDisplayName, getCompletionFilterDisplayName, getCompletionStatusColor, getCompletionStatusText, getExperimentCounts, japaneseUtils, logger, normalizeFestivalCardConfig, normalizePromptVariables, resizeFestivalCardPages, resolveScreenReceiverSignalUrl, skillToToolDefinition, sortExperiments, stringUtils, useAiChat, useAsyncStorage, useBackgroundRemoval, useDanmakuController, useElectronStorage, useFestivalCardConfig, useFireworksEngine, useFireworksRealtime, useLocalStorage, useOCR, useScreenReceiver, useSentimentAnalysis, useStorage, useTaroStorage, useTextGeneration, validateExperiment, validators };
7660
8049
  //# sourceMappingURL=index.mjs.map
7661
8050
  //# sourceMappingURL=index.mjs.map