sa2kit 1.6.2 → 1.6.3

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 (50) hide show
  1. package/dist/audioDetection/index.js.map +1 -1
  2. package/dist/audioDetection/index.mjs.map +1 -1
  3. package/dist/{chunk-5XUE72Y3.mjs → chunk-6LEA37ZM.mjs} +2 -2
  4. package/dist/{chunk-5XUE72Y3.mjs.map → chunk-6LEA37ZM.mjs.map} +1 -1
  5. package/dist/chunk-EBP7AE6F.js +167 -0
  6. package/dist/chunk-EBP7AE6F.js.map +1 -0
  7. package/dist/chunk-MBG4DBGP.mjs +154 -0
  8. package/dist/chunk-MBG4DBGP.mjs.map +1 -0
  9. package/dist/{chunk-DQVPZTVC.js → chunk-QKXKXAAV.js} +2 -2
  10. package/dist/{chunk-DQVPZTVC.js.map → chunk-QKXKXAAV.js.map} +1 -1
  11. package/dist/imageCrop/index.js.map +1 -1
  12. package/dist/imageCrop/index.mjs.map +1 -1
  13. package/dist/index-DtLpANUB.d.mts +70 -0
  14. package/dist/index-DtLpANUB.d.ts +70 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/mmd/admin/index.d.mts +1 -1
  18. package/dist/mmd/admin/index.d.ts +1 -1
  19. package/dist/mmd/index.d.mts +16 -2
  20. package/dist/mmd/index.d.ts +16 -2
  21. package/dist/mmd/index.js +280 -130
  22. package/dist/mmd/index.js.map +1 -1
  23. package/dist/mmd/index.mjs +280 -130
  24. package/dist/mmd/index.mjs.map +1 -1
  25. package/dist/mmd/server/index.d.mts +1 -1
  26. package/dist/mmd/server/index.d.ts +1 -1
  27. package/dist/music/index.d.mts +30 -0
  28. package/dist/music/index.d.ts +30 -0
  29. package/dist/music/index.js +458 -0
  30. package/dist/music/index.js.map +1 -0
  31. package/dist/music/index.mjs +427 -0
  32. package/dist/music/index.mjs.map +1 -0
  33. package/dist/music/server/index.d.mts +1 -0
  34. package/dist/music/server/index.d.ts +1 -0
  35. package/dist/music/server/index.js +29 -0
  36. package/dist/music/server/index.js.map +1 -0
  37. package/dist/music/server/index.mjs +4 -0
  38. package/dist/music/server/index.mjs.map +1 -0
  39. package/dist/testYourself/admin/index.js +3 -3
  40. package/dist/testYourself/admin/index.mjs +1 -1
  41. package/dist/testYourself/index.js +7 -7
  42. package/dist/testYourself/index.js.map +1 -1
  43. package/dist/testYourself/index.mjs +2 -2
  44. package/dist/testYourself/index.mjs.map +1 -1
  45. package/dist/{types-DxYJqqes.d.mts → types-B60F7EZZ.d.mts} +16 -1
  46. package/dist/{types-DxYJqqes.d.ts → types-B60F7EZZ.d.ts} +16 -1
  47. package/dist/universalFile/server/index.js +5 -5
  48. package/dist/universalFile/server/index.mjs +1 -1
  49. package/package.json +32 -19
  50. package/tailwind.animations.js +5 -0
@@ -199,6 +199,7 @@ var MMDPlayerBase = forwardRef((props, ref) => {
199
199
  const renderEffect = props.renderEffect || stage.renderEffect || "default";
200
200
  const outlineOptions = { ...stage.outlineOptions, ...props.outlineOptions };
201
201
  const bloomOptions = { ...stage.bloomOptions, ...props.bloomOptions };
202
+ const toonOptions = { ...stage.toonOptions, ...props.toonOptions };
202
203
  const containerRef = useRef(null);
203
204
  const sceneRef = useRef(null);
204
205
  const cameraRef = useRef(null);
@@ -396,6 +397,11 @@ var MMDPlayerBase = forwardRef((props, ref) => {
396
397
  const pixelRatio = mobileOptimization.enabled ? mobileOptimization.pixelRatio || Math.min(window.devicePixelRatio, 2) : window.devicePixelRatio;
397
398
  renderer.setPixelRatio(pixelRatio);
398
399
  console.log("[MMDPlayerBase] Pixel ratio set to:", pixelRatio);
400
+ if (renderEffect.includes("outline") || toonOptions.enabled) {
401
+ renderer.toneMapping = THREE.NoToneMapping;
402
+ } else {
403
+ renderer.toneMapping = THREE.ACESFilmicToneMapping;
404
+ }
399
405
  if (checkCancelled()) {
400
406
  renderer.dispose();
401
407
  return;
@@ -563,6 +569,41 @@ var MMDPlayerBase = forwardRef((props, ref) => {
563
569
  }
564
570
  }
565
571
  const enablePhysics = stage.enablePhysics !== false && !mobileOptimization.disablePhysics;
572
+ mesh.traverse((obj) => {
573
+ if (obj instanceof THREE.Mesh || obj instanceof THREE.SkinnedMesh) {
574
+ const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
575
+ materials.forEach((m) => {
576
+ if (!m.userData) m.userData = {};
577
+ if (!m.userData.outlineParameters) {
578
+ m.userData.outlineParameters = {
579
+ thickness: outlineOptions.thickness ?? 3e-3,
580
+ color: new THREE.Color(outlineOptions.color ?? "#000000").toArray(),
581
+ alpha: 1,
582
+ visible: true,
583
+ keepAlive: true
584
+ };
585
+ } else {
586
+ if (outlineOptions.thickness !== void 0) {
587
+ m.userData.outlineParameters.thickness = outlineOptions.thickness;
588
+ }
589
+ if (outlineOptions.color !== void 0) {
590
+ m.userData.outlineParameters.color = new THREE.Color(outlineOptions.color).toArray();
591
+ }
592
+ }
593
+ if (m instanceof THREE.MeshPhongMaterial) {
594
+ if (toonOptions.enabled !== false && (toonOptions.enabled || renderEffect.includes("outline"))) {
595
+ m.shininess = toonOptions.shininess ?? 0;
596
+ m.specular.setScalar(0);
597
+ if (toonOptions.forceHardShading && m.toonMap) {
598
+ m.toonMap.magFilter = THREE.NearestFilter;
599
+ m.toonMap.minFilter = THREE.NearestFilter;
600
+ m.toonMap.needsUpdate = true;
601
+ }
602
+ }
603
+ }
604
+ });
605
+ }
606
+ });
566
607
  helper.add(mesh, {
567
608
  animation,
568
609
  physics: enablePhysics
@@ -692,6 +733,22 @@ var MMDPlayerBase = forwardRef((props, ref) => {
692
733
  if (mesh2.morphTargetInfluences) {
693
734
  mesh2.morphTargetInfluences = [];
694
735
  }
736
+ materials.forEach((m) => {
737
+ if (!m.userData) m.userData = {};
738
+ m.userData.outlineParameters = {
739
+ thickness: outlineOptions.thickness ?? 3e-3,
740
+ color: new THREE.Color(outlineOptions.color ?? "#000000").toArray(),
741
+ alpha: 1,
742
+ visible: true,
743
+ keepAlive: true
744
+ };
745
+ if (m instanceof THREE.MeshPhongMaterial) {
746
+ if (toonOptions.enabled !== false && (toonOptions.enabled || renderEffect.includes("outline"))) {
747
+ m.shininess = toonOptions.shininess ?? 0;
748
+ m.specular.setScalar(0);
749
+ }
750
+ }
751
+ });
695
752
  }
696
753
  });
697
754
  try {
@@ -1167,7 +1224,27 @@ ${errorMessage}
1167
1224
  }
1168
1225
  }, [loop]);
1169
1226
  useEffect(() => {
1170
- if (outlineEffectRef.current) ;
1227
+ if (outlineEffectRef.current) {
1228
+ outlineEffectRef.current.defaultThickness = outlineOptions.thickness ?? 3e-3;
1229
+ outlineEffectRef.current.defaultColor = new THREE.Color(outlineOptions.color ?? "#000000").toArray();
1230
+ if (sceneRef.current) {
1231
+ sceneRef.current.traverse((obj) => {
1232
+ if (obj instanceof THREE.Mesh || obj instanceof THREE.SkinnedMesh) {
1233
+ const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
1234
+ materials.forEach((m) => {
1235
+ if (m.userData && m.userData.outlineParameters) {
1236
+ if (outlineOptions.thickness !== void 0) {
1237
+ m.userData.outlineParameters.thickness = outlineOptions.thickness;
1238
+ }
1239
+ if (outlineOptions.color !== void 0) {
1240
+ m.userData.outlineParameters.color = new THREE.Color(outlineOptions.color).toArray();
1241
+ }
1242
+ }
1243
+ });
1244
+ }
1245
+ });
1246
+ }
1247
+ }
1171
1248
  if (composerRef.current) {
1172
1249
  const bloomPass = composerRef.current.passes.find((p) => p instanceof UnrealBloomPass);
1173
1250
  if (bloomPass) {
@@ -1176,7 +1253,28 @@ ${errorMessage}
1176
1253
  bloomPass.threshold = bloomOptions.threshold ?? 0.8;
1177
1254
  }
1178
1255
  }
1179
- }, [bloomOptions.strength, bloomOptions.radius, bloomOptions.threshold]);
1256
+ }, [outlineOptions.thickness, outlineOptions.color, bloomOptions.strength, bloomOptions.radius, bloomOptions.threshold]);
1257
+ useEffect(() => {
1258
+ if (!sceneRef.current) return;
1259
+ sceneRef.current.traverse((obj) => {
1260
+ if (obj instanceof THREE.Mesh || obj instanceof THREE.SkinnedMesh) {
1261
+ const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
1262
+ materials.forEach((m) => {
1263
+ if (m instanceof THREE.MeshPhongMaterial) {
1264
+ if (toonOptions.enabled !== false && (toonOptions.enabled || renderEffect.includes("outline"))) {
1265
+ m.shininess = toonOptions.shininess ?? 0;
1266
+ m.specular.setScalar(0);
1267
+ if (toonOptions.forceHardShading && m.toonMap) {
1268
+ m.toonMap.magFilter = THREE.NearestFilter;
1269
+ m.toonMap.minFilter = THREE.NearestFilter;
1270
+ m.toonMap.needsUpdate = true;
1271
+ }
1272
+ }
1273
+ }
1274
+ });
1275
+ }
1276
+ });
1277
+ }, [toonOptions.enabled, toonOptions.shininess, toonOptions.forceHardShading, renderEffect]);
1180
1278
  useEffect(() => {
1181
1279
  if (!isReadyRef.current) return;
1182
1280
  if (sceneRef.current) {
@@ -2585,164 +2683,207 @@ var LoadingScreen = ({
2585
2683
  return createPortal(content, portalContainer);
2586
2684
  };
2587
2685
  LoadingScreen.displayName = "LoadingScreen";
2686
+ var VNModal = ({ title, show, onClose, children }) => {
2687
+ if (!show) return null;
2688
+ return /* @__PURE__ */ React6.createElement(
2689
+ "div",
2690
+ {
2691
+ className: "fixed inset-0 flex items-center justify-center bg-black/40 backdrop-blur-xl z-[1000000] pointer-events-auto transition-all animate-in fade-in zoom-in-95 duration-300",
2692
+ onClick: onClose
2693
+ },
2694
+ /* @__PURE__ */ React6.createElement(
2695
+ "div",
2696
+ {
2697
+ className: "w-full max-w-lg mx-4 p-8 rounded-[2.5rem] border border-white/40 shadow-[0_20px_80px_rgba(0,0,0,0.4)] relative overflow-hidden",
2698
+ style: {
2699
+ background: "linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.15))",
2700
+ backdropFilter: "blur(40px) saturate(200%)",
2701
+ WebkitBackdropFilter: "blur(40px) saturate(200%)"
2702
+ },
2703
+ onClick: (e) => e.stopPropagation()
2704
+ },
2705
+ /* @__PURE__ */ React6.createElement("div", { className: "absolute -top-24 -right-24 w-64 h-64 bg-cyan-400/20 rounded-full blur-3xl pointer-events-none" }),
2706
+ /* @__PURE__ */ React6.createElement("div", { className: "absolute -bottom-24 -left-24 w-64 h-64 bg-pink-400/20 rounded-full blur-3xl pointer-events-none" }),
2707
+ /* @__PURE__ */ React6.createElement("div", { className: "flex items-center justify-between mb-8 relative" }, /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React6.createElement("h2", { className: "text-2xl font-bold text-white tracking-wider drop-shadow-lg" }, title), /* @__PURE__ */ React6.createElement("div", { className: "h-1.5 w-16 bg-white/60 rounded-full mt-2 shadow-[0_0_10px_rgba(255,255,255,0.5)]" })), /* @__PURE__ */ React6.createElement(
2708
+ "button",
2709
+ {
2710
+ onClick: onClose,
2711
+ className: "w-12 h-12 rounded-full flex items-center justify-center bg-white/10 hover:bg-white/30 text-white transition-all border border-white/20 shadow-inner"
2712
+ },
2713
+ "\u2715"
2714
+ )),
2715
+ /* @__PURE__ */ React6.createElement("div", { className: "text-white leading-relaxed max-h-[50vh] overflow-y-auto pr-4 custom-scrollbar relative font-medium" }, children),
2716
+ /* @__PURE__ */ React6.createElement("div", { className: "mt-10 flex justify-center relative" }, /* @__PURE__ */ React6.createElement(
2717
+ "button",
2718
+ {
2719
+ onClick: onClose,
2720
+ className: "px-14 py-3.5 rounded-2xl bg-white/20 hover:bg-white/40 text-white font-bold transition-all border border-white/50 shadow-[0_0_20px_rgba(255,255,255,0.2)] hover:scale-105 active:scale-95 tracking-[0.2em] uppercase text-sm"
2721
+ },
2722
+ "Confirm"
2723
+ ))
2724
+ )
2725
+ );
2726
+ };
2588
2727
  var StartScreen = ({
2589
2728
  showStartScreen = false,
2590
2729
  scriptName = "",
2591
- startText = "\u70B9\u51FB\u5F00\u59CB",
2730
+ startText = "\u5F00\u59CB\u6E38\u620F",
2731
+ settingsText = "\u6E38\u620F\u8BBE\u7F6E",
2732
+ aboutText = "\u5173\u4E8E\u4F5C\u54C1",
2592
2733
  onStart,
2593
2734
  className = ""
2594
2735
  }) => {
2595
2736
  const [isMounted, setIsMounted] = useState(false);
2737
+ const [showSettings, setShowSettings] = useState(false);
2738
+ const [showAbout, setShowAbout] = useState(false);
2596
2739
  useEffect(() => {
2597
2740
  setIsMounted(true);
2598
2741
  }, []);
2599
- console.log("[StartScreen] Render state:", {
2600
- showStartScreen,
2601
- scriptName,
2602
- isMounted
2603
- });
2604
- if (!isMounted) {
2605
- return null;
2606
- }
2607
- if (!showStartScreen) {
2608
- console.log("[StartScreen] Not showing, returning null");
2609
- return null;
2610
- }
2742
+ if (!isMounted) return null;
2743
+ if (!showStartScreen) return null;
2611
2744
  const content = /* @__PURE__ */ React6.createElement(
2612
2745
  "div",
2613
2746
  {
2614
- className: `fixed inset-0 w-screen h-screen flex items-center justify-center cursor-pointer ${className}`,
2747
+ className: `fixed inset-0 w-screen h-screen flex items-center justify-center overflow-hidden ${className}`,
2615
2748
  style: {
2616
2749
  zIndex: 999999,
2617
2750
  pointerEvents: "auto",
2618
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2751
+ backgroundColor: "#050505",
2619
2752
  margin: 0,
2620
2753
  padding: 0
2621
- },
2622
- onClick: onStart
2754
+ }
2623
2755
  },
2624
- /* @__PURE__ */ React6.createElement(
2756
+ /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0 w-full h-full overflow-hidden" }, /* @__PURE__ */ React6.createElement(
2625
2757
  "div",
2626
2758
  {
2627
- className: "absolute inset-0 w-full h-full pointer-events-none",
2759
+ className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[150vw] h-[150vw] opacity-40 pointer-events-none",
2628
2760
  style: {
2629
- background: "linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.15))",
2630
- backdropFilter: "blur(40px) saturate(200%)",
2631
- WebkitBackdropFilter: "blur(40px) saturate(200%)"
2761
+ background: "radial-gradient(circle at center, rgba(57, 197, 187, 0.4) 0%, rgba(255, 182, 193, 0.2) 30%, transparent 70%)",
2762
+ filter: "blur(60px)",
2763
+ animation: "pulse 10s ease-in-out infinite"
2764
+ }
2765
+ }
2766
+ ), /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0 transition-opacity duration-1000" }, /* @__PURE__ */ React6.createElement("div", { className: "absolute top-[-10%] left-[-10%] w-[60%] h-[60%] bg-cyan-500/10 rounded-full blur-[120px] animate-blob" }), /* @__PURE__ */ React6.createElement("div", { className: "absolute bottom-[-10%] right-[-10%] w-[60%] h-[60%] bg-purple-500/10 rounded-full blur-[120px] animate-blob animation-delay-2000" }), /* @__PURE__ */ React6.createElement("div", { className: "absolute top-[20%] right-[10%] w-[40%] h-[40%] bg-pink-500/10 rounded-full blur-[100px] animate-blob animation-delay-4000" })), /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0 opacity-60" }, [...Array(40)].map((_, i) => /* @__PURE__ */ React6.createElement(
2767
+ "div",
2768
+ {
2769
+ key: i,
2770
+ className: "absolute bg-white/40 rounded-full",
2771
+ style: {
2772
+ width: Math.random() * 3 + 1 + "px",
2773
+ height: Math.random() * 3 + 1 + "px",
2774
+ top: Math.random() * 100 + "%",
2775
+ left: Math.random() * 100 + "%",
2776
+ boxShadow: "0 0 10px rgba(255,255,255,0.5)",
2777
+ animation: `floatParticle ${Math.random() * 10 + 10}s linear infinite`,
2778
+ animationDelay: `-${Math.random() * 20}s`
2779
+ }
2780
+ }
2781
+ )))),
2782
+ /* @__PURE__ */ React6.createElement("div", { className: "relative z-10 w-full max-w-5xl mx-auto px-6 flex flex-col items-center" }, /* @__PURE__ */ React6.createElement("div", { className: "text-center mb-20 md:mb-32 group flex flex-col items-center" }, /* @__PURE__ */ React6.createElement("div", { className: "w-40 h-px bg-gradient-to-r from-transparent via-white/60 to-transparent mb-10 shadow-[0_0_15px_rgba(255,255,255,0.5)]" }), /* @__PURE__ */ React6.createElement(
2783
+ "h1",
2784
+ {
2785
+ className: "text-6xl md:text-8xl font-black text-white tracking-[0.15em] leading-tight select-none",
2786
+ style: {
2787
+ filter: "drop-shadow(0 0 20px rgba(255,255,255,0.3))",
2788
+ textShadow: "0 10px 30px rgba(0,0,0,0.5)"
2632
2789
  }
2633
2790
  },
2791
+ scriptName || "VISUAL NOVEL"
2792
+ ), /* @__PURE__ */ React6.createElement("div", { className: "mt-10 flex flex-col items-center gap-4" }, /* @__PURE__ */ React6.createElement("div", { className: "h-1 w-32 bg-white rounded-full opacity-80 shadow-[0_0_20px_rgba(255,255,255,0.8)]" }), /* @__PURE__ */ React6.createElement("span", { className: "text-sm md:text-base tracking-[0.8em] text-white/60 font-medium uppercase translate-x-[0.4em]" }, "Adventure System"))), /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-10 items-center w-full max-w-sm" }, /* @__PURE__ */ React6.createElement(
2793
+ "button",
2794
+ {
2795
+ onClick: onStart,
2796
+ className: "group relative w-full h-20 flex items-center justify-center transition-all duration-500 active:scale-95"
2797
+ },
2634
2798
  /* @__PURE__ */ React6.createElement(
2635
2799
  "div",
2636
2800
  {
2637
- className: "flex items-center justify-center flex-col inset-0 w-full h-full pointer-events-none",
2638
- style: {
2639
- background: `linear-gradient(45deg,
2640
- rgba(255, 182, 193, 0.25) 0%,
2641
- rgba(173, 216, 230, 0.25) 25%,
2642
- rgba(221, 160, 221, 0.25) 50%,
2643
- rgba(255, 218, 185, 0.25) 75%,
2644
- rgba(255, 182, 193, 0.25) 100%)`,
2645
- backgroundSize: "400% 400%",
2646
- animation: "gradientShift 15s ease infinite"
2647
- }
2648
- },
2649
- /* @__PURE__ */ React6.createElement(
2650
- "div",
2651
- {
2652
- className: "relative z-10 text-center px-16 py-14 rounded-3xl max-w-2xl mx-auto transform transition-all hover:scale-105",
2653
- style: {
2654
- background: "linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.15))",
2655
- backdropFilter: "blur(24px)",
2656
- WebkitBackdropFilter: "blur(24px)",
2657
- border: "2px solid rgba(255, 255, 255, 0.3)",
2658
- boxShadow: `
2659
- 0 12px 48px rgba(255, 255, 255, 0.15),
2660
- 0 4px 16px rgba(255, 255, 255, 0.1),
2661
- inset 0 1px 0 rgba(255, 255, 255, 0.4)
2662
- `
2663
- }
2664
- },
2665
- /* @__PURE__ */ React6.createElement(
2666
- "div",
2667
- {
2668
- className: "absolute top-0 left-0 right-0 h-1 margin-auto",
2669
- style: {
2670
- background: "linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent)"
2671
- }
2672
- }
2673
- ),
2674
- /* @__PURE__ */ React6.createElement(
2675
- "h1",
2676
- {
2677
- className: "text-5xl font-bold text-white mb-8 relative",
2678
- style: {
2679
- textShadow: "0 4px 16px rgba(255, 255, 255, 0.3), 0 2px 8px rgba(0, 0, 0, 0.5)"
2680
- }
2681
- },
2682
- scriptName,
2683
- /* @__PURE__ */ React6.createElement(
2684
- "div",
2685
- {
2686
- className: "absolute -bottom-3 left-1/2 transform -translate-x-1/2 h-1 rounded-full",
2687
- style: {
2688
- width: "60%",
2689
- background: "linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent)"
2690
- }
2691
- }
2692
- )
2693
- ),
2694
- /* @__PURE__ */ React6.createElement(
2695
- "div",
2696
- {
2697
- className: "inline-block px-10 py-4 rounded-2xl font-bold text-xl text-white transition-all hover:scale-110 active:scale-95",
2698
- style: {
2699
- background: "linear-gradient(135deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0.25))",
2700
- backdropFilter: "blur(16px)",
2701
- WebkitBackdropFilter: "blur(16px)",
2702
- border: "2px solid rgba(255, 255, 255, 0.4)",
2703
- boxShadow: `
2704
- 0 8px 32px rgba(255, 255, 255, 0.2),
2705
- inset 0 1px 0 rgba(255, 255, 255, 0.5)
2706
- `,
2707
- textShadow: "0 2px 8px rgba(0, 0, 0, 0.3)",
2708
- animation: "pulse 2s ease-in-out infinite"
2709
- }
2710
- },
2711
- /* @__PURE__ */ React6.createElement("span", { className: "relative z-10" }, startText)
2712
- ),
2713
- /* @__PURE__ */ React6.createElement(
2714
- "div",
2715
- {
2716
- className: "absolute bottom-0 left-0 right-0 h-px",
2717
- style: {
2718
- background: "linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent)"
2719
- }
2720
- }
2721
- )
2722
- )
2723
- )
2724
- )
2801
+ className: "absolute inset-0 bg-white/10 backdrop-blur-2xl border-2 border-white/40 rounded-3xl transition-all duration-500 group-hover:bg-white/25 group-hover:border-white/70 group-hover:shadow-[0_0_50px_rgba(255,255,255,0.3)] group-hover:-inset-1"
2802
+ }
2803
+ ),
2804
+ /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0 overflow-hidden rounded-3xl pointer-events-none" }, /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-700 bg-gradient-to-r from-transparent via-white/20 to-transparent -skew-x-[25deg] -translate-x-[200%] group-hover:translate-x-[200%] transition-transform duration-1000 ease-in-out" })),
2805
+ /* @__PURE__ */ React6.createElement("div", { className: "relative flex items-center gap-6" }, /* @__PURE__ */ React6.createElement("div", { className: "w-3 h-3 rounded-full bg-cyan-400 animate-ping opacity-75" }), /* @__PURE__ */ React6.createElement("span", { className: "text-2xl font-black text-white tracking-[0.4em] drop-shadow-md" }, startText), /* @__PURE__ */ React6.createElement("div", { className: "w-3 h-3 rounded-full bg-pink-400 animate-ping opacity-75" }))
2806
+ ), /* @__PURE__ */ React6.createElement("div", { className: "flex gap-8 w-full justify-center" }, [
2807
+ { text: settingsText, onClick: () => setShowSettings(true), color: "rgba(57, 197, 187, 0.2)" },
2808
+ { text: aboutText, onClick: () => setShowAbout(true), color: "rgba(255, 182, 193, 0.2)" }
2809
+ ].map((btn, idx) => /* @__PURE__ */ React6.createElement(
2810
+ "button",
2811
+ {
2812
+ key: idx,
2813
+ onClick: btn.onClick,
2814
+ className: "group relative flex-1 h-14 flex items-center justify-center transition-all duration-300 active:scale-95 overflow-hidden rounded-2xl"
2815
+ },
2816
+ /* @__PURE__ */ React6.createElement(
2817
+ "div",
2818
+ {
2819
+ className: "absolute inset-0 bg-white/5 backdrop-blur-xl border border-white/20 transition-all duration-300 group-hover:bg-white/15 group-hover:border-white/40"
2820
+ }
2821
+ ),
2822
+ /* @__PURE__ */ React6.createElement(
2823
+ "div",
2824
+ {
2825
+ className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity",
2826
+ style: { background: btn.color }
2827
+ }
2828
+ ),
2829
+ /* @__PURE__ */ React6.createElement("span", { className: "relative text-sm md:text-base font-bold text-white/80 group-hover:text-white tracking-[0.25em] transition-colors uppercase" }, btn.text)
2830
+ ))))),
2831
+ /* @__PURE__ */ React6.createElement("div", { className: "fixed bottom-10 left-0 right-0 text-center pointer-events-none select-none" }, /* @__PURE__ */ React6.createElement("div", { className: "inline-block px-6 py-2 rounded-full bg-white/5 backdrop-blur-md border border-white/10" }, /* @__PURE__ */ React6.createElement("span", { className: "text-[10px] md:text-xs text-white/30 tracking-[0.5em] font-light uppercase" }, "Ver 1.6.2 \u2014 ENGINE POWERED BY SA2KIT"))),
2832
+ /* @__PURE__ */ React6.createElement(VNModal, { title: settingsText, show: showSettings, onClose: () => setShowSettings(false) }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-8 py-4" }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React6.createElement("div", { className: "flex justify-between items-center text-sm font-bold tracking-widest text-white/60" }, /* @__PURE__ */ React6.createElement("span", null, "MUSIC VOLUME"), /* @__PURE__ */ React6.createElement("span", null, "80%")), /* @__PURE__ */ React6.createElement("div", { className: "h-3 bg-white/10 rounded-full p-0.5 border border-white/10" }, /* @__PURE__ */ React6.createElement("div", { className: "h-full w-[80%] bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full shadow-[0_0_15px_rgba(34,211,238,0.5)]" }))), /* @__PURE__ */ React6.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React6.createElement("div", { className: "flex justify-between items-center text-sm font-bold tracking-widest text-white/60" }, /* @__PURE__ */ React6.createElement("span", null, "TEXT SPEED"), /* @__PURE__ */ React6.createElement("span", null, "NORMAL")), /* @__PURE__ */ React6.createElement("div", { className: "flex gap-3" }, ["SLOW", "NORMAL", "FAST"].map((s, i) => /* @__PURE__ */ React6.createElement("div", { key: s, className: `flex-1 py-3 rounded-xl border text-center text-xs font-bold transition-all cursor-pointer ${i === 1 ? "bg-white/20 border-white/60 text-white" : "bg-white/5 border-white/10 text-white/40 hover:bg-white/10 hover:border-white/30"}` }, s)))), /* @__PURE__ */ React6.createElement("div", { className: "pt-4 flex items-center justify-between opacity-50 italic text-xs border-t border-white/10" }, /* @__PURE__ */ React6.createElement("span", null, "Auto Save Enabled"), /* @__PURE__ */ React6.createElement("span", null, "Cloud Sync Active")))),
2833
+ /* @__PURE__ */ React6.createElement(VNModal, { title: aboutText, show: showAbout, onClose: () => setShowAbout(false) }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-8 py-4" }, /* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-6 p-6 rounded-3xl bg-white/5 border border-white/10" }, /* @__PURE__ */ React6.createElement("div", { className: "w-20 h-20 rounded-2xl bg-gradient-to-br from-cyan-400 via-blue-500 to-purple-600 flex items-center justify-center text-3xl font-black text-white shadow-[0_10px_30px_rgba(0,0,0,0.3)]" }, "S2"), /* @__PURE__ */ React6.createElement("div", null, /* @__PURE__ */ React6.createElement("h3", { className: "text-2xl font-black text-white tracking-tight" }, scriptName || "Project SA2"), /* @__PURE__ */ React6.createElement("p", { className: "text-xs font-bold text-white/40 tracking-widest mt-1 uppercase" }, "Visual Novel Experience"))), /* @__PURE__ */ React6.createElement("div", { className: "space-y-4 px-2" }, /* @__PURE__ */ React6.createElement("p", { className: "text-white/80 font-medium leading-relaxed" }, "\u91C7\u7528 sa2kit \u5F15\u64CE\u6784\u5EFA\u7684\u65B0\u4E00\u4EE3\u5B9E\u65F6 3D \u89C6\u89C9\u5C0F\u8BF4\u3002\u7ED3\u5408\u4E86 MMD \u5B9E\u65F6\u6E32\u67D3\u6280\u672F\u4E0E\u4EA4\u4E92\u5F0F\u5267\u60C5\u5206\u652F\u7CFB\u7EDF\uFF0C\u81F4\u529B\u4E8E\u6253\u9020\u6781\u81F4\u7684\u6C89\u6D78\u5F0F\u53D9\u4E8B\u4F53\u9A8C\u3002")), /* @__PURE__ */ React6.createElement("div", { className: "grid grid-cols-2 gap-4 pt-6 border-t border-white/10" }, /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React6.createElement("span", { className: "text-[10px] font-bold text-white/30 tracking-widest" }, "DEVELOPER"), /* @__PURE__ */ React6.createElement("span", { className: "text-xs font-bold text-white/80" }, "SA2KIT TEAM")), /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-1 text-right" }, /* @__PURE__ */ React6.createElement("span", { className: "text-[10px] font-bold text-white/30 tracking-widest" }, "ENGINE"), /* @__PURE__ */ React6.createElement("span", { className: "text-xs font-bold text-white/80" }, "THREE.JS / REACT"))))),
2834
+ /* @__PURE__ */ React6.createElement("style", null, `
2835
+ @keyframes floatParticle {
2836
+ from { transform: translateY(0) translateX(0); opacity: 0; }
2837
+ 20% { opacity: 1; }
2838
+ 80% { opacity: 1; }
2839
+ to { transform: translateY(-100vh) translateX(50px); opacity: 0; }
2840
+ }
2841
+ @keyframes blob {
2842
+ 0%, 100% { transform: scale(1); opacity: 0.1; }
2843
+ 50% { transform: scale(1.2); opacity: 0.2; }
2844
+ }
2845
+ .animate-blob {
2846
+ animation: blob 10s infinite;
2847
+ }
2848
+ .animation-delay-2000 {
2849
+ animation-delay: 2s;
2850
+ }
2851
+ .animation-delay-4000 {
2852
+ animation-delay: 4s;
2853
+ }
2854
+ .custom-scrollbar::-webkit-scrollbar {
2855
+ width: 6px;
2856
+ }
2857
+ .custom-scrollbar::-webkit-scrollbar-track {
2858
+ background: rgba(255, 255, 255, 0.05);
2859
+ border-radius: 10px;
2860
+ }
2861
+ .custom-scrollbar::-webkit-scrollbar-thumb {
2862
+ background: rgba(255, 255, 255, 0.3);
2863
+ border-radius: 10px;
2864
+ border: 2px solid transparent;
2865
+ background-clip: content-box;
2866
+ }
2867
+ `)
2725
2868
  );
2726
- let portalContainer = document.getElementById("start-screen-portal-root");
2727
- if (!portalContainer) {
2869
+ let portalContainer = typeof document !== "undefined" ? document.getElementById("start-screen-portal-root") : null;
2870
+ if (typeof document !== "undefined" && !portalContainer) {
2728
2871
  portalContainer = document.createElement("div");
2729
2872
  portalContainer.id = "start-screen-portal-root";
2730
2873
  document.body.appendChild(portalContainer);
2731
2874
  }
2732
- portalContainer.style.cssText = `
2733
- position: fixed;
2734
- top: 0;
2735
- left: 0;
2736
- right: 0;
2737
- bottom: 0;
2738
- width: 100vw;
2739
- height: 100vh;
2740
- margin: 0;
2741
- padding: 0;
2742
- overflow: hidden;
2743
- z-index: 999999;
2744
- pointer-events: none;
2745
- `.replace(/\s+/g, " ").trim();
2875
+ if (portalContainer) {
2876
+ portalContainer.style.cssText = `
2877
+ position: fixed;
2878
+ top: 0; left: 0; right: 0; bottom: 0;
2879
+ width: 100vw; height: 100vh;
2880
+ margin: 0; padding: 0;
2881
+ overflow: hidden;
2882
+ z-index: 999999;
2883
+ pointer-events: none;
2884
+ `.replace(/\s+/g, " ").trim();
2885
+ }
2886
+ if (!portalContainer) return content;
2746
2887
  return createPortal(content, portalContainer);
2747
2888
  };
2748
2889
  StartScreen.displayName = "StartScreen";
@@ -2769,7 +2910,9 @@ var LoadingOverlay = ({
2769
2910
  showStartScreen = false,
2770
2911
  scriptName = "",
2771
2912
  loadingText = "\u6B63\u5728\u51C6\u5907\u573A\u666F\u4E2D...",
2772
- startText = "\u70B9\u51FB\u5F00\u59CB",
2913
+ startText = "\u5F00\u59CB\u6E38\u620F",
2914
+ settingsText = "\u6E38\u620F\u8BBE\u7F6E",
2915
+ aboutText = "\u5173\u4E8E\u4F5C\u54C1",
2773
2916
  onStart,
2774
2917
  className = ""
2775
2918
  }) => {
@@ -2786,6 +2929,8 @@ var LoadingOverlay = ({
2786
2929
  showStartScreen,
2787
2930
  scriptName,
2788
2931
  startText,
2932
+ settingsText,
2933
+ aboutText,
2789
2934
  onStart,
2790
2935
  className
2791
2936
  }
@@ -2900,6 +3045,9 @@ var MMDVisualNovel = forwardRef(
2900
3045
  mobileOptimization,
2901
3046
  dialogueTheme,
2902
3047
  autoStart = false,
3048
+ startText,
3049
+ settingsText,
3050
+ aboutText,
2903
3051
  initialNodeIndex = 0,
2904
3052
  initialDialogueIndex = 0,
2905
3053
  onNodeChange,
@@ -3276,7 +3424,9 @@ var MMDVisualNovel = forwardRef(
3276
3424
  showStartScreen: !isStarted,
3277
3425
  scriptName: script.name,
3278
3426
  loadingText: "\u6B63\u5728\u51C6\u5907\u573A\u666F\u4E2D...",
3279
- startText: "\u70B9\u51FB\u5F00\u59CB",
3427
+ startText,
3428
+ settingsText,
3429
+ aboutText,
3280
3430
  onStart: handleStart
3281
3431
  }
3282
3432
  ),