@rslsp1/fa-app-tools 2.0.22 → 2.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -407,10 +407,10 @@ async function loadHFState(namespace, token) {
407
407
  async function loadPendingEvents(namespace, token, sinceTs) {
408
408
  const files = await hfListDir(namespace, "events", token);
409
409
  const pending = files.filter((f) => f.type === "file" && tsFromEventPath(f.path) > sinceTs).sort((a, b) => a.path.localeCompare(b.path));
410
- const events = await Promise.all(
410
+ const raw = await Promise.all(
411
411
  pending.map((f) => hfDownloadJsonByPath(f.path, token))
412
412
  );
413
- return events;
413
+ return raw.flatMap((e) => Array.isArray(e) ? e : [e]);
414
414
  }
415
415
  function getSessionClientId() {
416
416
  return SESSION_CLIENT_ID;
@@ -566,23 +566,27 @@ async function hfUploadImage(base64, id, token, mimeType = "image/jpeg") {
566
566
  commitTitle: `Add image ${id}`
567
567
  });
568
568
  }
569
- async function hfLoadImageAsBase64(id, token) {
570
- for (const ext of ["jpg", "png"]) {
571
- try {
572
- const res = await fetch(
573
- `${HF_BASE}/datasets/${HF_REPO}/resolve/main/images/${id}.${ext}?download=true`,
574
- { headers: { Authorization: `Bearer ${token}` } }
575
- );
576
- if (!res.ok) continue;
577
- const blob = await res.blob();
578
- return new Promise((resolve, reject) => {
579
- const reader = new FileReader();
580
- reader.onload = () => resolve(reader.result.split(",")[1]);
581
- reader.onerror = reject;
582
- reader.readAsDataURL(blob);
583
- });
584
- } catch {
585
- continue;
569
+ async function hfLoadImageAsBase64(id, token, namespace) {
570
+ const paths = [`images/${id}`];
571
+ if (namespace) paths.push(`${namespace}images/${id}`);
572
+ for (const basePath of paths) {
573
+ for (const ext of ["jpg", "png"]) {
574
+ try {
575
+ const res = await fetch(
576
+ `${HF_BASE}/datasets/${HF_REPO}/resolve/main/${basePath}.${ext}?download=true`,
577
+ { headers: { Authorization: `Bearer ${token}` } }
578
+ );
579
+ if (!res.ok) continue;
580
+ const blob = await res.blob();
581
+ return new Promise((resolve, reject) => {
582
+ const reader = new FileReader();
583
+ reader.onload = () => resolve(reader.result.split(",")[1]);
584
+ reader.onerror = reject;
585
+ reader.readAsDataURL(blob);
586
+ });
587
+ } catch {
588
+ continue;
589
+ }
586
590
  }
587
591
  }
588
592
  return null;
@@ -615,6 +619,7 @@ __export(index_exports, {
615
619
  LIB_VERSION: () => LIB_VERSION,
616
620
  LabBlend: () => LabBlend,
617
621
  LabCompare: () => LabCompare,
622
+ LabFrameExtractor: () => LabFrameExtractor,
618
623
  LabImagePicker: () => LabImagePicker,
619
624
  LabLoop: () => LabLoop,
620
625
  LabRemix: () => LabRemix,
@@ -625,6 +630,7 @@ __export(index_exports, {
625
630
  ProjectSyncTab: () => ProjectSyncTab,
626
631
  PromptTab: () => PromptTab,
627
632
  SectionLabel: () => SectionLabel,
633
+ ServerTab: () => ServerTab,
628
634
  SetupPanel: () => SetupPanel,
629
635
  TagManagerPanel: () => TagManagerPanel,
630
636
  applyEvent: () => applyEvent,
@@ -644,6 +650,10 @@ __export(index_exports, {
644
650
  cleanAiResponse: () => cleanAiResponse,
645
651
  createFlowServices: () => createFlowServices,
646
652
  exportProjectToZip: () => exportProjectToZip,
653
+ faServerDelete: () => faServerDelete,
654
+ faServerGet: () => faServerGet,
655
+ faServerPost: () => faServerPost,
656
+ faServerPut: () => faServerPut,
647
657
  findForks: () => findForks,
648
658
  findTips: () => findTips,
649
659
  formatTreeToMarkdown: () => formatTreeToMarkdown,
@@ -1461,7 +1471,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
1461
1471
  }
1462
1472
 
1463
1473
  // src/components/AvatarArchitectApp.tsx
1464
- var import_react23 = require("react");
1474
+ var import_react25 = require("react");
1465
1475
 
1466
1476
  // src/components/PromptTab.tsx
1467
1477
  var import_react12 = require("react");
@@ -2754,7 +2764,7 @@ function useHFState(token, namespace) {
2754
2764
  }
2755
2765
 
2756
2766
  // src/components/labs/LabsTab.tsx
2757
- var import_react20 = require("react");
2767
+ var import_react21 = require("react");
2758
2768
 
2759
2769
  // src/components/labs/LabRemix.tsx
2760
2770
  var import_react16 = require("react");
@@ -3592,52 +3602,313 @@ var LabLoop = ({ services, onResult }) => {
3592
3602
  ] });
3593
3603
  };
3594
3604
 
3595
- // src/components/labs/LabsTab.tsx
3605
+ // src/components/labs/LabFrameExtractor.tsx
3606
+ var import_react20 = require("react");
3596
3607
  var import_jsx_runtime18 = require("react/jsx-runtime");
3597
- var TABS = [
3608
+ var formatTime = (s) => {
3609
+ const m = Math.floor(s / 60);
3610
+ const sec = (s % 60).toFixed(1);
3611
+ return `${m}:${sec.padStart(4, "0")}`;
3612
+ };
3613
+ var MAX_FRAMES = 40;
3614
+ var INTERVAL_OPTIONS = ["0.5", "1", "2", "5", "10"];
3615
+ var LabFrameExtractor = ({
3616
+ videoItems,
3617
+ onResult,
3618
+ resolveVideoUrl
3619
+ }) => {
3620
+ const videoRef = (0, import_react20.useRef)(null);
3621
+ const canvasRef = (0, import_react20.useRef)(null);
3622
+ const cancelledRef = (0, import_react20.useRef)(false);
3623
+ const [selectedItem, setSelectedItem] = (0, import_react20.useState)(null);
3624
+ const [videoSrc, setVideoSrc] = (0, import_react20.useState)(null);
3625
+ const [videoReady, setVideoReady] = (0, import_react20.useState)(false);
3626
+ const [frames, setFrames] = (0, import_react20.useState)([]);
3627
+ const [isExtracting, setIsExtracting] = (0, import_react20.useState)(false);
3628
+ const [intervalSec, setIntervalSec] = (0, import_react20.useState)("1");
3629
+ const handleVideoSelect = (item) => {
3630
+ const mediaId = item.frames[0]?.mediaId;
3631
+ if (!mediaId) return;
3632
+ setSelectedItem(item);
3633
+ setVideoSrc(resolveVideoUrl(mediaId));
3634
+ setFrames([]);
3635
+ setVideoReady(false);
3636
+ cancelledRef.current = false;
3637
+ };
3638
+ const captureAt = (0, import_react20.useCallback)(
3639
+ (t, label) => new Promise((resolve) => {
3640
+ const video = videoRef.current;
3641
+ const canvas = canvasRef.current;
3642
+ if (!video || !canvas || !isFinite(video.duration)) return resolve(null);
3643
+ const onSeeked = () => {
3644
+ canvas.width = video.videoWidth;
3645
+ canvas.height = video.videoHeight;
3646
+ const ctx = canvas.getContext("2d");
3647
+ if (!ctx) return resolve(null);
3648
+ ctx.drawImage(video, 0, 0);
3649
+ resolve({
3650
+ id: `fe-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
3651
+ dataUrl: canvas.toDataURL("image/png"),
3652
+ timeSeconds: t,
3653
+ label
3654
+ });
3655
+ };
3656
+ video.addEventListener("seeked", onSeeked, { once: true });
3657
+ video.currentTime = t;
3658
+ }),
3659
+ []
3660
+ );
3661
+ const extractSingle = async (mode) => {
3662
+ const v = videoRef.current;
3663
+ if (!v || !videoReady) return;
3664
+ const t = mode === "start" ? 0 : mode === "end" ? Math.max(0, v.duration - 0.01) : v.currentTime;
3665
+ const frame = await captureAt(t, mode === "start" ? "Start" : mode === "end" ? "End" : formatTime(t));
3666
+ if (frame) setFrames((prev) => [frame, ...prev]);
3667
+ };
3668
+ const extractInterval = async () => {
3669
+ const v = videoRef.current;
3670
+ if (!v || !videoReady || isExtracting) return;
3671
+ const every = parseFloat(intervalSec);
3672
+ if (!isFinite(every) || every <= 0) return;
3673
+ const ts = [];
3674
+ for (let t = 0; t <= v.duration; t += every) {
3675
+ ts.push(Math.min(t, v.duration - 0.01));
3676
+ if (ts.length >= MAX_FRAMES) break;
3677
+ }
3678
+ setIsExtracting(true);
3679
+ cancelledRef.current = false;
3680
+ setFrames([]);
3681
+ const collected = [];
3682
+ for (const t of ts) {
3683
+ if (cancelledRef.current) break;
3684
+ const f = await captureAt(t, formatTime(t));
3685
+ if (f) {
3686
+ collected.push(f);
3687
+ setFrames([...collected]);
3688
+ }
3689
+ }
3690
+ setIsExtracting(false);
3691
+ };
3692
+ const useFrame = (frame) => {
3693
+ if (!onResult || !selectedItem) return;
3694
+ const base64 = frame.dataUrl.replace(/^data:image\/png;base64,/, "");
3695
+ const labFrame = {
3696
+ id: frame.id,
3697
+ base64,
3698
+ source: "flow-gallery"
3699
+ };
3700
+ onResult({
3701
+ id: frame.id,
3702
+ prompt: selectedItem.prompt,
3703
+ label: `Frame ${frame.label} \u2013 ${selectedItem.label ?? selectedItem.id}`,
3704
+ tags: selectedItem.tags ?? [],
3705
+ frames: [labFrame]
3706
+ });
3707
+ };
3708
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 12, padding: 12, height: "100%", overflow: "auto" }, children: [
3709
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
3710
+ videoItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: 11, color: "#666", fontStyle: "italic" }, children: "No video items available" }),
3711
+ videoItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3712
+ "button",
3713
+ {
3714
+ onClick: () => handleVideoSelect(item),
3715
+ style: {
3716
+ padding: "4px 8px",
3717
+ fontSize: 11,
3718
+ background: selectedItem?.id === item.id ? "rgba(168,85,247,0.2)" : "rgba(255,255,255,0.05)",
3719
+ border: `1px solid ${selectedItem?.id === item.id ? "#a855f7" : "rgba(255,255,255,0.1)"}`,
3720
+ borderRadius: 4,
3721
+ color: "#fff",
3722
+ cursor: "pointer"
3723
+ },
3724
+ children: item.label ?? item.id
3725
+ },
3726
+ item.id
3727
+ ))
3728
+ ] }),
3729
+ videoSrc && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3730
+ "video",
3731
+ {
3732
+ ref: videoRef,
3733
+ src: videoSrc,
3734
+ controls: true,
3735
+ crossOrigin: "anonymous",
3736
+ onLoadedMetadata: () => setVideoReady(true),
3737
+ style: { width: "100%", maxHeight: 280, background: "#000", borderRadius: 6, display: "block" }
3738
+ }
3739
+ ),
3740
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
3741
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center" }, children: [
3742
+ ["start", "current", "end"].map((mode) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3743
+ "button",
3744
+ {
3745
+ disabled: !videoReady,
3746
+ onClick: () => extractSingle(mode),
3747
+ style: {
3748
+ padding: "4px 10px",
3749
+ fontSize: 11,
3750
+ borderRadius: 4,
3751
+ background: "rgba(255,255,255,0.08)",
3752
+ border: "1px solid rgba(255,255,255,0.15)",
3753
+ color: "#fff",
3754
+ cursor: videoReady ? "pointer" : "not-allowed",
3755
+ opacity: videoReady ? 1 : 0.4
3756
+ },
3757
+ children: mode === "start" ? "Start Frame" : mode === "end" ? "End Frame" : "Current Frame"
3758
+ },
3759
+ mode
3760
+ )),
3761
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: 11, color: "#aaa" }, children: "every" }),
3762
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3763
+ "select",
3764
+ {
3765
+ value: intervalSec,
3766
+ onChange: (e) => setIntervalSec(e.target.value),
3767
+ disabled: !videoReady || isExtracting,
3768
+ style: { fontSize: 11, background: "#111", border: "1px solid #333", color: "#fff", borderRadius: 4, padding: "2px 4px" },
3769
+ children: INTERVAL_OPTIONS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("option", { value: v, children: [
3770
+ v,
3771
+ "s"
3772
+ ] }, v))
3773
+ }
3774
+ ),
3775
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3776
+ "button",
3777
+ {
3778
+ disabled: !videoReady,
3779
+ onClick: isExtracting ? () => {
3780
+ cancelledRef.current = true;
3781
+ } : extractInterval,
3782
+ style: {
3783
+ padding: "4px 10px",
3784
+ fontSize: 11,
3785
+ borderRadius: 4,
3786
+ background: isExtracting ? "rgba(239,68,68,0.2)" : "rgba(255,255,255,0.08)",
3787
+ border: `1px solid ${isExtracting ? "#ef4444" : "rgba(255,255,255,0.15)"}`,
3788
+ color: isExtracting ? "#f87171" : "#fff",
3789
+ cursor: videoReady ? "pointer" : "not-allowed",
3790
+ opacity: videoReady ? 1 : 0.4
3791
+ },
3792
+ children: isExtracting ? "Cancel" : "Extract All"
3793
+ }
3794
+ )
3795
+ ] }),
3796
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 8, overflowX: "auto", paddingBottom: 4 }, children: [
3797
+ frames.map((frame) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3798
+ "div",
3799
+ {
3800
+ style: {
3801
+ flexShrink: 0,
3802
+ width: 100,
3803
+ border: "1px solid rgba(255,255,255,0.1)",
3804
+ borderRadius: 6,
3805
+ overflow: "hidden",
3806
+ background: "rgba(255,255,255,0.03)"
3807
+ },
3808
+ children: [
3809
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { src: frame.dataUrl, style: { width: "100%", aspectRatio: "16/9", objectFit: "cover", display: "block" }, alt: frame.label }),
3810
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 9, color: "#888", textAlign: "center", padding: "2px 4px", fontFamily: "monospace" }, children: frame.label }),
3811
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 2, padding: "0 4px 4px", justifyContent: "center" }, children: [
3812
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3813
+ "button",
3814
+ {
3815
+ onClick: () => useFrame(frame),
3816
+ style: {
3817
+ flex: 1,
3818
+ padding: "2px 0",
3819
+ fontSize: 9,
3820
+ borderRadius: 3,
3821
+ background: "rgba(168,85,247,0.2)",
3822
+ border: "1px solid #a855f7",
3823
+ color: "#c084fc",
3824
+ cursor: "pointer"
3825
+ },
3826
+ children: "Use"
3827
+ }
3828
+ ),
3829
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3830
+ "button",
3831
+ {
3832
+ onClick: () => setFrames((prev) => prev.filter((f) => f.id !== frame.id)),
3833
+ style: {
3834
+ padding: "2px 4px",
3835
+ fontSize: 9,
3836
+ borderRadius: 3,
3837
+ background: "rgba(255,255,255,0.05)",
3838
+ border: "1px solid rgba(255,255,255,0.1)",
3839
+ color: "#666",
3840
+ cursor: "pointer"
3841
+ },
3842
+ children: "\u2715"
3843
+ }
3844
+ )
3845
+ ] })
3846
+ ]
3847
+ },
3848
+ frame.id
3849
+ )),
3850
+ frames.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: 11, color: "#444", fontStyle: "italic", padding: "16px 0" }, children: isExtracting ? "Extracting frames\u2026" : "No frames yet" })
3851
+ ] })
3852
+ ] });
3853
+ };
3854
+
3855
+ // src/components/labs/LabsTab.tsx
3856
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3857
+ var BASE_TABS = [
3598
3858
  { key: "remix", label: "Remix", icon: "auto_fix_high" },
3599
3859
  { key: "blend", label: "Blend", icon: "merge" },
3600
3860
  { key: "compare", label: "Compare", icon: "compare" },
3601
3861
  { key: "loop", label: "Loop", icon: "loop" }
3602
3862
  ];
3603
- var LabsTab = ({ services, onResult }) => {
3604
- const [activeTab, setActiveTab] = (0, import_react20.useState)("remix");
3605
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
3606
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex border-b border-white/5 shrink-0", children: TABS.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3863
+ var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
3864
+ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
3865
+ const [activeTab, setActiveTab] = (0, import_react21.useState)("remix");
3866
+ const showFrames = !!(videoItems && resolveVideoUrl);
3867
+ const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
3868
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
3869
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex border-b border-white/5 shrink-0", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3607
3870
  "button",
3608
3871
  {
3609
3872
  onClick: () => setActiveTab(tab.key),
3610
3873
  className: `flex-1 flex items-center justify-center gap-1 h-10 text-[9px] font-bold uppercase tracking-wide transition-colors ${activeTab === tab.key ? "text-white border-b-2 border-white" : "text-white/30 hover:text-white/60"}`,
3611
3874
  children: [
3612
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: tab.icon }),
3875
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: tab.icon }),
3613
3876
  tab.label
3614
3877
  ]
3615
3878
  },
3616
3879
  tab.key
3617
3880
  )) }),
3618
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 overflow-hidden", children: [
3619
- activeTab === "remix" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LabRemix, { services, onResult }),
3620
- activeTab === "blend" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LabBlend, { services, onResult }),
3621
- activeTab === "compare" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LabCompare, { services, onResult }),
3622
- activeTab === "loop" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LabLoop, { services, onResult })
3881
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 overflow-hidden", children: [
3882
+ activeTab === "remix" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabRemix, { services, onResult }),
3883
+ activeTab === "blend" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabBlend, { services, onResult }),
3884
+ activeTab === "compare" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabCompare, { services, onResult }),
3885
+ activeTab === "loop" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabLoop, { services, onResult }),
3886
+ activeTab === "frames" && showFrames && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3887
+ LabFrameExtractor,
3888
+ {
3889
+ videoItems,
3890
+ onResult,
3891
+ resolveVideoUrl
3892
+ }
3893
+ )
3623
3894
  ] })
3624
3895
  ] });
3625
3896
  };
3626
3897
 
3627
3898
  // src/components/TagManagerPanel.tsx
3628
- var import_react21 = require("react");
3629
- var import_jsx_runtime19 = require("react/jsx-runtime");
3899
+ var import_react22 = require("react");
3900
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3630
3901
  function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
3631
3902
  const categories = Object.keys(workspaceTags.by_category).filter(
3632
3903
  (cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
3633
3904
  );
3634
- const [selectedCategory, setSelectedCategory] = (0, import_react21.useState)(categories[0] || "");
3905
+ const [selectedCategory, setSelectedCategory] = (0, import_react22.useState)(categories[0] || "");
3635
3906
  const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
3636
- const [editingLabel, setEditingLabel] = (0, import_react21.useState)(null);
3637
- const [editState, setEditState] = (0, import_react21.useState)({ label: "", value: "" });
3638
- const [newTag, setNewTag] = (0, import_react21.useState)({ label: "", value: "" });
3639
- const [movingLabel, setMovingLabel] = (0, import_react21.useState)(null);
3640
- const [moveTarget, setMoveTarget] = (0, import_react21.useState)("");
3907
+ const [editingLabel, setEditingLabel] = (0, import_react22.useState)(null);
3908
+ const [editState, setEditState] = (0, import_react22.useState)({ label: "", value: "" });
3909
+ const [newTag, setNewTag] = (0, import_react22.useState)({ label: "", value: "" });
3910
+ const [movingLabel, setMovingLabel] = (0, import_react22.useState)(null);
3911
+ const [moveTarget, setMoveTarget] = (0, import_react22.useState)("");
3641
3912
  const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
3642
3913
  const otherCategories = categories.filter((c) => c !== effectiveCategory);
3643
3914
  const startEdit = (tag) => {
@@ -3680,10 +3951,10 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3680
3951
  if (!confirm(`Tag "${tag.label}" l\xF6schen?`)) return;
3681
3952
  onTagDelete(tag.label, effectiveCategory);
3682
3953
  };
3683
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
3684
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "px-3 py-2 border-b border-white/5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-white/40", children: "Tag Manager" }) }),
3685
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "px-3 py-2 shrink-0 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex gap-1.5 flex-nowrap", children: [
3686
- categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3954
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
3955
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "px-3 py-2 border-b border-white/5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-white/40", children: "Tag Manager" }) }),
3956
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "px-3 py-2 shrink-0 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1.5 flex-nowrap", children: [
3957
+ categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3687
3958
  "button",
3688
3959
  {
3689
3960
  onClick: () => {
@@ -3695,17 +3966,17 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3695
3966
  children: [
3696
3967
  cat,
3697
3968
  " ",
3698
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ml-1 opacity-50", children: (workspaceTags.by_category[cat] || []).filter((t) => !t.is_deleted).length })
3969
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ml-1 opacity-50", children: (workspaceTags.by_category[cat] || []).filter((t) => !t.is_deleted).length })
3699
3970
  ]
3700
3971
  },
3701
3972
  cat
3702
3973
  )),
3703
- categories.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[10px] text-white/20", children: "Erst Workspace importieren" })
3974
+ categories.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/20", children: "Erst Workspace importieren" })
3704
3975
  ] }) }),
3705
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 overflow-y-auto dark-scrollbar px-3 pb-2 space-y-1", children: [
3706
- tags.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
3707
- editingLabel === tag.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "bg-white/5 border border-blue-600/40 rounded-lg p-2.5 space-y-1.5", children: [
3708
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3976
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-y-auto dark-scrollbar px-3 pb-2 space-y-1", children: [
3977
+ tags.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
3978
+ editingLabel === tag.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "bg-white/5 border border-blue-600/40 rounded-lg p-2.5 space-y-1.5", children: [
3979
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3709
3980
  "input",
3710
3981
  {
3711
3982
  value: editState.label,
@@ -3716,7 +3987,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3716
3987
  onKeyDown: (e) => e.key === "Enter" && saveEdit(tag.label)
3717
3988
  }
3718
3989
  ),
3719
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3990
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3720
3991
  "textarea",
3721
3992
  {
3722
3993
  value: editState.value,
@@ -3726,24 +3997,24 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3726
3997
  placeholder: "Prompt-Wert (leer = Label)"
3727
3998
  }
3728
3999
  ),
3729
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
3730
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => saveEdit(tag.label), className: "px-2.5 py-1 bg-blue-700 hover:bg-blue-600 text-white text-[10px] font-bold rounded transition", children: "SPEICHERN" }),
3731
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => setEditingLabel(null), className: "px-2.5 py-1 bg-white/5 hover:bg-white/10 text-white/50 text-[10px] font-bold rounded transition", children: "ABBRUCH" })
4000
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4001
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => saveEdit(tag.label), className: "px-2.5 py-1 bg-blue-700 hover:bg-blue-600 text-white text-[10px] font-bold rounded transition", children: "SPEICHERN" }),
4002
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setEditingLabel(null), className: "px-2.5 py-1 bg-white/5 hover:bg-white/10 text-white/50 text-[10px] font-bold rounded transition", children: "ABBRUCH" })
3732
4003
  ] })
3733
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "group flex items-center gap-1.5 bg-white/3 hover:bg-white/6 border border-white/5 rounded-lg px-2 py-1.5 transition", children: [
3734
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-0 shrink-0", children: [
3735
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => handleMoveUp(i), disabled: i === 0, className: "text-white/20 hover:text-white/60 disabled:opacity-10 transition leading-none", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_up" }) }),
3736
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => handleMoveDown(i), disabled: i === tags.length - 1, className: "text-white/20 hover:text-white/60 disabled:opacity-10 transition leading-none", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_down" }) })
4004
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "group flex items-center gap-1.5 bg-white/3 hover:bg-white/6 border border-white/5 rounded-lg px-2 py-1.5 transition", children: [
4005
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-0 shrink-0", children: [
4006
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => handleMoveUp(i), disabled: i === 0, className: "text-white/20 hover:text-white/60 disabled:opacity-10 transition leading-none", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_up" }) }),
4007
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => handleMoveDown(i), disabled: i === tags.length - 1, className: "text-white/20 hover:text-white/60 disabled:opacity-10 transition leading-none", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_down" }) })
3737
4008
  ] }),
3738
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 min-w-0", children: [
3739
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "text-[12px] text-white/80 font-medium truncate", children: tag.label }),
3740
- tag.value && tag.value !== tag.label && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "text-[10px] text-white/30 truncate", children: [
4009
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 min-w-0", children: [
4010
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "text-[12px] text-white/80 font-medium truncate", children: tag.label }),
4011
+ tag.value && tag.value !== tag.label && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-[10px] text-white/30 truncate", children: [
3741
4012
  tag.value.slice(0, 60),
3742
4013
  tag.value.length > 60 ? "\u2026" : ""
3743
4014
  ] })
3744
4015
  ] }),
3745
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition shrink-0", children: [
3746
- otherCategories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4016
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition shrink-0", children: [
4017
+ otherCategories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3747
4018
  "button",
3748
4019
  {
3749
4020
  onClick: () => {
@@ -3753,29 +4024,29 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3753
4024
  },
3754
4025
  className: "p-1 rounded text-white/30 hover:text-purple-400 transition",
3755
4026
  title: "Kategorie wechseln",
3756
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "drive_file_move" })
4027
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "drive_file_move" })
3757
4028
  }
3758
4029
  ),
3759
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => startEdit(tag), className: "p-1 rounded text-white/30 hover:text-blue-400 transition", title: "Bearbeiten", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "edit" }) }),
3760
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => handleDelete(tag), className: "p-1 rounded text-white/30 hover:text-red-400 transition", title: "L\xF6schen", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "delete" }) })
4030
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => startEdit(tag), className: "p-1 rounded text-white/30 hover:text-blue-400 transition", title: "Bearbeiten", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "edit" }) }),
4031
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => handleDelete(tag), className: "p-1 rounded text-white/30 hover:text-red-400 transition", title: "L\xF6schen", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "delete" }) })
3761
4032
  ] })
3762
4033
  ] }),
3763
- movingLabel === tag.label && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "mt-1 bg-purple-900/20 border border-purple-700/30 rounded-lg p-2.5 space-y-1.5", children: [
3764
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-purple-400/70", children: "Verschieben nach Kategorie" }),
3765
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4034
+ movingLabel === tag.label && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mt-1 bg-purple-900/20 border border-purple-700/30 rounded-lg p-2.5 space-y-1.5", children: [
4035
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-purple-400/70", children: "Verschieben nach Kategorie" }),
4036
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3766
4037
  "select",
3767
4038
  {
3768
4039
  value: moveTarget,
3769
4040
  onChange: (e) => setMoveTarget(e.target.value),
3770
4041
  className: "w-full bg-black/40 border border-white/10 rounded px-2 py-1 text-[11px] text-white/70 outline-none",
3771
4042
  children: [
3772
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "", children: "\u2014 Kategorie w\xE4hlen \u2014" }),
3773
- otherCategories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: cat, children: cat }, cat))
4043
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { value: "", children: "\u2014 Kategorie w\xE4hlen \u2014" }),
4044
+ otherCategories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { value: cat, children: cat }, cat))
3774
4045
  ]
3775
4046
  }
3776
4047
  ),
3777
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
3778
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4048
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4049
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3779
4050
  "button",
3780
4051
  {
3781
4052
  onClick: () => handleMove(tag),
@@ -3784,19 +4055,19 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3784
4055
  children: "VERSCHIEBEN"
3785
4056
  }
3786
4057
  ),
3787
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => setMovingLabel(null), className: "px-2.5 py-1 bg-white/5 hover:bg-white/10 text-white/50 text-[10px] font-bold rounded transition", children: "ABBRUCH" })
4058
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setMovingLabel(null), className: "px-2.5 py-1 bg-white/5 hover:bg-white/10 text-white/50 text-[10px] font-bold rounded transition", children: "ABBRUCH" })
3788
4059
  ] })
3789
4060
  ] })
3790
4061
  ] }, `${effectiveCategory}-${i}`)),
3791
- tags.length === 0 && effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "text-center text-[11px] text-white/20 py-6", children: "Keine Tags in dieser Kategorie." })
4062
+ tags.length === 0 && effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "text-center text-[11px] text-white/20 py-6", children: "Keine Tags in dieser Kategorie." })
3792
4063
  ] }),
3793
- effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "px-3 py-2 border-t border-white/5 shrink-0 space-y-1.5", children: [
3794
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30", children: [
4064
+ effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "px-3 py-2 border-t border-white/5 shrink-0 space-y-1.5", children: [
4065
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30", children: [
3795
4066
  "Neuer Tag in \u201E",
3796
4067
  effectiveCategory,
3797
4068
  '"'
3798
4069
  ] }),
3799
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4070
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3800
4071
  "input",
3801
4072
  {
3802
4073
  value: newTag.label,
@@ -3806,7 +4077,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3806
4077
  className: "w-full bg-black/40 border border-white/10 rounded px-2 py-1.5 text-[12px] text-white outline-none focus:border-white/20"
3807
4078
  }
3808
4079
  ),
3809
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4080
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3810
4081
  "textarea",
3811
4082
  {
3812
4083
  value: newTag.value,
@@ -3816,14 +4087,14 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3816
4087
  className: "w-full bg-black/40 border border-white/10 rounded px-2 py-1 text-[11px] text-white/60 outline-none focus:border-white/20 resize-none"
3817
4088
  }
3818
4089
  ),
3819
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4090
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3820
4091
  "button",
3821
4092
  {
3822
4093
  onClick: handleCreate,
3823
4094
  disabled: !newTag.label.trim(),
3824
4095
  className: "w-full py-1.5 bg-white/5 border border-white/10 text-white/60 text-[10px] font-bold rounded hover:bg-white/10 hover:text-white transition disabled:opacity-30 flex items-center justify-center gap-1.5",
3825
4096
  children: [
3826
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
4097
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
3827
4098
  "TAG ERSTELLEN"
3828
4099
  ]
3829
4100
  }
@@ -3833,8 +4104,8 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3833
4104
  }
3834
4105
 
3835
4106
  // src/components/HFTestTab.tsx
3836
- var import_react22 = require("react");
3837
- var import_jsx_runtime20 = require("react/jsx-runtime");
4107
+ var import_react23 = require("react");
4108
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3838
4109
  var HF_BASE2 = "https://huggingface.co";
3839
4110
  var HF_REPO2 = "RolandSch/fa-app-state";
3840
4111
  var TEST_DIR = "test";
@@ -4026,8 +4297,8 @@ function tryFmt(s) {
4026
4297
  }
4027
4298
  }
4028
4299
  function CopyBtn({ text }) {
4029
- const [done, setDone] = (0, import_react22.useState)(false);
4030
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4300
+ const [done, setDone] = (0, import_react23.useState)(false);
4301
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4031
4302
  "button",
4032
4303
  {
4033
4304
  onClick: () => {
@@ -4038,7 +4309,7 @@ function CopyBtn({ text }) {
4038
4309
  },
4039
4310
  style: { background: "none", border: "1px solid rgba(255,255,255,0.15)", borderRadius: 5, color: done ? "#4ade80" : "rgba(255,255,255,0.45)", fontSize: 10, padding: "3px 8px", cursor: "pointer", fontFamily: "inherit", display: "flex", alignItems: "center", gap: 3 },
4040
4311
  children: [
4041
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
4312
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
4042
4313
  done ? "Kopiert" : "Copy"
4043
4314
  ]
4044
4315
  }
@@ -4046,35 +4317,35 @@ function CopyBtn({ text }) {
4046
4317
  }
4047
4318
  function StepView({ step }) {
4048
4319
  const isSpecial = step.method === "-" || step.method === "import()" || step.method === "import()+call";
4049
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 6, background: "rgba(0,0,0,0.3)", borderRadius: 7, padding: "7px 9px", border: `1px solid ${step.ok === false ? "rgba(248,113,113,0.2)" : "rgba(255,255,255,0.05)"}` }, children: [
4050
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
4051
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
4052
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
4053
- step.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4320
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 6, background: "rgba(0,0,0,0.3)", borderRadius: 7, padding: "7px 9px", border: `1px solid ${step.ok === false ? "rgba(248,113,113,0.2)" : "rgba(255,255,255,0.05)"}` }, children: [
4321
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
4322
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
4323
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
4324
+ step.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4054
4325
  step.durationMs,
4055
4326
  "ms"
4056
4327
  ] }),
4057
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CopyBtn, { text: JSON.stringify(step, null, 2) })
4328
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyBtn, { text: JSON.stringify(step, null, 2) })
4058
4329
  ] }),
4059
- !isSpecial && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 5 }, children: [
4060
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
4330
+ !isSpecial && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 5 }, children: [
4331
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
4061
4332
  "\u2192 ",
4062
4333
  step.method,
4063
4334
  " ",
4064
4335
  step.url
4065
4336
  ] }),
4066
- Object.keys(step.reqHeaders).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 60, overflow: "auto" }, children: Object.entries(step.reqHeaders).map(([k, v]) => `${k}: ${v}`).join("\n") }),
4067
- step.reqBody && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 80, overflow: "auto" }, children: step.reqBody })
4337
+ Object.keys(step.reqHeaders).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 60, overflow: "auto" }, children: Object.entries(step.reqHeaders).map(([k, v]) => `${k}: ${v}`).join("\n") }),
4338
+ step.reqBody && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 80, overflow: "auto" }, children: step.reqBody })
4068
4339
  ] }),
4069
- step.error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 11, color: "#f87171", margin: 0, padding: "3px 5px", background: "rgba(248,113,113,0.05)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all" }, children: step.error }),
4070
- !step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
4071
- step.resStatus !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 11, fontWeight: 700, color: (step.resStatus || 0) < 300 ? "#4ade80" : "#f87171", marginBottom: 3 }, children: [
4340
+ step.error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: { fontSize: 11, color: "#f87171", margin: 0, padding: "3px 5px", background: "rgba(248,113,113,0.05)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all" }, children: step.error }),
4341
+ !step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
4342
+ step.resStatus !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 11, fontWeight: 700, color: (step.resStatus || 0) < 300 ? "#4ade80" : "#f87171", marginBottom: 3 }, children: [
4072
4343
  "\u2190 ",
4073
4344
  step.resStatus,
4074
4345
  " ",
4075
4346
  step.resStatusText
4076
4347
  ] }),
4077
- step.resBody && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.55)", margin: 0, padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 180, overflow: "auto" }, children: tryFmt(step.resBody) })
4348
+ step.resBody && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.55)", margin: 0, padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 180, overflow: "auto" }, children: tryFmt(step.resBody) })
4078
4349
  ] })
4079
4350
  ] });
4080
4351
  }
@@ -4090,15 +4361,15 @@ function TestCard({
4090
4361
  onToggle
4091
4362
  }) {
4092
4363
  const hasResult = state && state.status !== "idle";
4093
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 8, background: "rgba(255,255,255,0.03)", borderRadius: 10, border: `1px solid ${state?.status === "ok" ? "rgba(74,222,128,0.15)" : state?.status === "error" ? "rgba(248,113,113,0.15)" : "rgba(255,255,255,0.07)"}`, overflow: "hidden" }, children: [
4094
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
4095
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: state?.status === "ok" ? "#4ade80" : state?.status === "error" ? "#f87171" : state?.status === "running" ? "#60a5fa" : "rgba(255,255,255,0.35)", flexShrink: 0 }, children: state?.status === "ok" ? "check_circle" : state?.status === "error" ? "error" : state?.status === "running" ? "hourglass_top" : icon }),
4096
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4097
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
4098
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: desc })
4364
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 8, background: "rgba(255,255,255,0.03)", borderRadius: 10, border: `1px solid ${state?.status === "ok" ? "rgba(74,222,128,0.15)" : state?.status === "error" ? "rgba(248,113,113,0.15)" : "rgba(255,255,255,0.07)"}`, overflow: "hidden" }, children: [
4365
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
4366
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: state?.status === "ok" ? "#4ade80" : state?.status === "error" ? "#f87171" : state?.status === "running" ? "#60a5fa" : "rgba(255,255,255,0.35)", flexShrink: 0 }, children: state?.status === "ok" ? "check_circle" : state?.status === "error" ? "error" : state?.status === "running" ? "hourglass_top" : icon }),
4367
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4368
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
4369
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: desc })
4099
4370
  ] }),
4100
- hasResult && state?.status !== "running" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onToggle, style: { background: "none", border: "none", color: "rgba(255,255,255,0.3)", cursor: "pointer", padding: 2, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: expanded ? "expand_less" : "expand_more" }) }),
4101
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4371
+ hasResult && state?.status !== "running" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: onToggle, style: { background: "none", border: "none", color: "rgba(255,255,255,0.3)", cursor: "pointer", padding: 2, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: expanded ? "expand_less" : "expand_more" }) }),
4372
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4102
4373
  "button",
4103
4374
  {
4104
4375
  onClick: onRun,
@@ -4108,20 +4379,20 @@ function TestCard({
4108
4379
  }
4109
4380
  )
4110
4381
  ] }),
4111
- hasResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
4112
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
4113
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: state.status === "ok" ? "#4ade80" : "#f87171" }, children: state.status === "ok" ? "\u2713 OK" : state.status === "running" ? "\u2026" : "\u2717 Fehler" }),
4114
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4382
+ hasResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
4383
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
4384
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: state.status === "ok" ? "#4ade80" : "#f87171" }, children: state.status === "ok" ? "\u2713 OK" : state.status === "running" ? "\u2026" : "\u2717 Fehler" }),
4385
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4115
4386
  state.totalMs,
4116
4387
  "ms \xB7 ",
4117
4388
  state.steps.length,
4118
4389
  " Step",
4119
4390
  state.steps.length !== 1 ? "s" : ""
4120
4391
  ] }),
4121
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1 } }),
4122
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CopyBtn, { text: JSON.stringify(state, null, 2) })
4392
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
4393
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyBtn, { text: JSON.stringify(state, null, 2) })
4123
4394
  ] }),
4124
- expanded && state.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: "0 10px 4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StepView, { step }) }, i))
4395
+ expanded && state.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "0 10px 4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StepView, { step }) }, i))
4125
4396
  ] })
4126
4397
  ] });
4127
4398
  }
@@ -4133,10 +4404,10 @@ var EVENT_TYPE_COLORS = {
4133
4404
  };
4134
4405
  function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadStatus }) {
4135
4406
  if (!events.length) {
4136
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: "12px 14px", fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Events geladen." });
4407
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "12px 14px", fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Events geladen." });
4137
4408
  }
4138
4409
  const sorted = [...events].sort((a, b) => b.ts - a.ts).slice(0, 30);
4139
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "6px 8px 4px" }, children: [
4410
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "6px 8px 4px" }, children: [
4140
4411
  sorted.map((e, i) => {
4141
4412
  const eKey = `${e.ts}_${e.clientId}`;
4142
4413
  const isConfirmed = confirmedEventKeys.has(eKey);
@@ -4149,47 +4420,47 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
4149
4420
  const uploadStatus = imgId ? imageUploadStatus.get(imgId) : void 0;
4150
4421
  const payloadStr = JSON.stringify(e.payload ?? {});
4151
4422
  const payloadPreview = payloadStr.length > 70 ? payloadStr.slice(0, 70) + "\u2026" : payloadStr;
4152
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 7, alignItems: "flex-start", padding: "6px 2px", borderBottom: "1px solid rgba(255,255,255,0.05)" }, children: [
4153
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { width: 36, height: 36, flexShrink: 0, borderRadius: 4, overflow: "hidden", background: "rgba(255,255,255,0.05)", display: "flex", alignItems: "center", justifyContent: "center" }, children: isImageEvent ? galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: galleryItem.base64, style: { width: "100%", height: "100%", objectFit: "cover" } }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: "rgba(255,255,255,0.2)" }, children: "image" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16, color: "rgba(255,255,255,0.15)" }, children: e.type === "tag_upserted" ? "label" : e.type === "metadata_updated" ? "edit_note" : "data_object" }) }),
4154
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4155
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3 }, children: [
4156
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: typeColor }, children: e.type }),
4157
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", fontVariantNumeric: "tabular-nums" }, children: timeStr }),
4158
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1 } }),
4159
- isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4160
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "check_circle" }),
4423
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 7, alignItems: "flex-start", padding: "6px 2px", borderBottom: "1px solid rgba(255,255,255,0.05)" }, children: [
4424
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: 36, height: 36, flexShrink: 0, borderRadius: 4, overflow: "hidden", background: "rgba(255,255,255,0.05)", display: "flex", alignItems: "center", justifyContent: "center" }, children: isImageEvent ? galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: galleryItem.base64, style: { width: "100%", height: "100%", objectFit: "cover" } }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: "rgba(255,255,255,0.2)" }, children: "image" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16, color: "rgba(255,255,255,0.15)" }, children: e.type === "tag_upserted" ? "label" : e.type === "metadata_updated" ? "edit_note" : "data_object" }) }),
4425
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4426
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3 }, children: [
4427
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: typeColor }, children: e.type }),
4428
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", fontVariantNumeric: "tabular-nums" }, children: timeStr }),
4429
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
4430
+ isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4431
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "check_circle" }),
4161
4432
  "HF"
4162
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#fbbf24", display: "flex", alignItems: "center", gap: 2 }, children: [
4163
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "schedule" }),
4433
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#fbbf24", display: "flex", alignItems: "center", gap: 2 }, children: [
4434
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "schedule" }),
4164
4435
  "lokal"
4165
4436
  ] })
4166
4437
  ] }),
4167
- isImageEvent && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3, flexWrap: "wrap" }, children: [
4168
- uploadStatus === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4169
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_done" }),
4438
+ isImageEvent && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3, flexWrap: "wrap" }, children: [
4439
+ uploadStatus === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4440
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_done" }),
4170
4441
  "Upload \u2713"
4171
4442
  ] }),
4172
- uploadStatus === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, color: "#60a5fa", display: "flex", alignItems: "center", gap: 2 }, children: [
4173
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_upload" }),
4443
+ uploadStatus === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#60a5fa", display: "flex", alignItems: "center", gap: 2 }, children: [
4444
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_upload" }),
4174
4445
  "l\xE4dt hoch\u2026"
4175
4446
  ] }),
4176
- uploadStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4177
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_off" }),
4447
+ uploadStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4448
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_off" }),
4178
4449
  "Upload fehlgeschlagen"
4179
4450
  ] }),
4180
- galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4181
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "photo" }),
4451
+ galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4452
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "photo" }),
4182
4453
  uploadStatus ? "lokal" : "von HF geladen"
4183
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4184
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "broken_image" }),
4454
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4455
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "broken_image" }),
4185
4456
  uploadStatus === "failed" ? "Binary nicht auf HF" : "wird geladen\u2026"
4186
4457
  ] })
4187
4458
  ] }),
4188
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: payloadPreview })
4459
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: payloadPreview })
4189
4460
  ] })
4190
4461
  ] }, `${eKey}_${i}`);
4191
4462
  }),
4192
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "6px 0 2px", fontSize: 9, color: "rgba(255,255,255,0.2)", textAlign: "right" }, children: [
4463
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "6px 0 2px", fontSize: 9, color: "rgba(255,255,255,0.2)", textAlign: "right" }, children: [
4193
4464
  events.length,
4194
4465
  " Events gesamt \xB7 ",
4195
4466
  [...confirmedEventKeys].length,
@@ -4198,9 +4469,9 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
4198
4469
  ] });
4199
4470
  }
4200
4471
  function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map() }) {
4201
- const [selected, setSelected] = (0, import_react22.useState)(null);
4202
- const [results, setResults] = (0, import_react22.useState)({});
4203
- const [expanded, setExpanded] = (0, import_react22.useState)({});
4472
+ const [selected, setSelected] = (0, import_react23.useState)(null);
4473
+ const [results, setResults] = (0, import_react23.useState)({});
4474
+ const [expanded, setExpanded] = (0, import_react23.useState)({});
4204
4475
  const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
4205
4476
  const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
4206
4477
  const setDone = (id, steps, t0) => {
@@ -4248,15 +4519,15 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4248
4519
  { id: "img-hub", label: "Upload hub lib", icon: "package_2", desc: "uploadFile() via @huggingface/hub" },
4249
4520
  { id: "img-cdn", label: "Upload CDN lib", icon: "language", desc: "uploadFile() via esm.sh hub lib" }
4250
4521
  ];
4251
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflowY: "auto", padding: "12px 10px 80px", boxSizing: "border-box", fontFamily: "inherit" }, children: [
4252
- noToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: 10, padding: "8px 12px", background: "rgba(248,113,113,0.08)", borderRadius: 8, border: "1px solid rgba(248,113,113,0.2)", fontSize: 12, color: "#f87171" }, children: "Kein HF-Token geladen \u2014 bitte zuerst Token im Sync-Tab eingeben." }),
4253
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4522
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflowY: "auto", padding: "12px 10px 80px", boxSizing: "border-box", fontFamily: "inherit" }, children: [
4523
+ noToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 10, padding: "8px 12px", background: "rgba(248,113,113,0.08)", borderRadius: 8, border: "1px solid rgba(248,113,113,0.2)", fontSize: 12, color: "#f87171" }, children: "Kein HF-Token geladen \u2014 bitte zuerst Token im Sync-Tab eingeben." }),
4524
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4254
4525
  CollapsibleCard,
4255
4526
  {
4256
4527
  title: "Event Monitor",
4257
- icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "bolt" }),
4528
+ icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "bolt" }),
4258
4529
  defaultOpen: true,
4259
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4530
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4260
4531
  EventMonitor,
4261
4532
  {
4262
4533
  events: allEvents,
@@ -4267,25 +4538,25 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4267
4538
  )
4268
4539
  }
4269
4540
  ) }),
4270
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4541
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4271
4542
  CollapsibleCard,
4272
4543
  {
4273
4544
  title: "Upload Tests",
4274
- icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "science" }),
4545
+ icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "science" }),
4275
4546
  defaultOpen: false,
4276
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "10px 10px 4px" }, children: [
4277
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 14 }, children: [
4278
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }, children: [
4547
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "10px 10px 4px" }, children: [
4548
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 14 }, children: [
4549
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }, children: [
4279
4550
  "Bild ausw\xE4hlen (",
4280
4551
  withResults.length,
4281
4552
  " verf\xFCgbar)"
4282
4553
  ] }),
4283
- withResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Bilder in der Galerie. Generiere zuerst ein Bild oder lade von HF." }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }, children: withResults.slice(0, 12).map((g) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4554
+ withResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Bilder in der Galerie. Generiere zuerst ein Bild oder lade von HF." }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }, children: withResults.slice(0, 12).map((g) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4284
4555
  "button",
4285
4556
  {
4286
4557
  onClick: () => setSelected(g),
4287
4558
  style: { padding: 0, border: `2px solid ${selected?.id === g.id ? "#0284c7" : "transparent"}`, borderRadius: 6, cursor: "pointer", overflow: "hidden", background: "none", lineHeight: 0 },
4288
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4559
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4289
4560
  "img",
4290
4561
  {
4291
4562
  src: g.base64,
@@ -4296,38 +4567,38 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4296
4567
  },
4297
4568
  g.id
4298
4569
  )) }),
4299
- selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
4300
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4570
+ selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
4571
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4301
4572
  "img",
4302
4573
  {
4303
4574
  src: selected.base64,
4304
4575
  style: { width: 80, height: 80, objectFit: "cover", borderRadius: 8, border: "1px solid rgba(255,255,255,0.1)", flexShrink: 0 }
4305
4576
  }
4306
4577
  ),
4307
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4308
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
4309
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
4578
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4579
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
4580
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
4310
4581
  "ID: ",
4311
4582
  selected.id
4312
4583
  ] }),
4313
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 2 }, children: [
4584
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 2 }, children: [
4314
4585
  "Ziel: test/",
4315
4586
  selected.id,
4316
4587
  ".jpg"
4317
4588
  ] }),
4318
- selected.prompt && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selected.prompt })
4589
+ selected.prompt && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selected.prompt })
4319
4590
  ] })
4320
4591
  ] })
4321
4592
  ] }),
4322
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 14 }, children: [
4323
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4593
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 14 }, children: [
4594
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4324
4595
  "Bild hochladen \u2192 test/",
4325
4596
  "{",
4326
4597
  "id",
4327
4598
  "}",
4328
4599
  ".jpg"
4329
4600
  ] }),
4330
- imgTests.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4601
+ imgTests.map((t) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4331
4602
  TestCard,
4332
4603
  {
4333
4604
  id: t.id,
@@ -4343,13 +4614,13 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4343
4614
  t.id
4344
4615
  ))
4345
4616
  ] }),
4346
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 4 }, children: [
4347
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4617
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 4 }, children: [
4618
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4348
4619
  "Event schreiben \u2192 ",
4349
4620
  namespace || "(kein namespace)",
4350
4621
  "test/events/"
4351
4622
  ] }),
4352
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4623
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4353
4624
  TestCard,
4354
4625
  {
4355
4626
  id: "event",
@@ -4370,10 +4641,236 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4370
4641
  ] });
4371
4642
  }
4372
4643
 
4644
+ // src/components/ServerTab.tsx
4645
+ var import_react24 = require("react");
4646
+
4647
+ // src/lib/faHfServerService.ts
4648
+ init_hfStateService();
4649
+ var FA_APP_SPACE = "https://rslsp1-fa-app.hf.space";
4650
+ async function request(method, path, env = "prod", body) {
4651
+ const token = getHFToken();
4652
+ if (!token) throw new Error("fa-app gateway: kein HF Token gesetzt");
4653
+ const res = await fetch(`${FA_APP_SPACE}/${path.replace(/^\//, "")}`, {
4654
+ method,
4655
+ headers: {
4656
+ "Authorization": `Bearer ${token}`,
4657
+ "X-Env": env,
4658
+ ...body !== void 0 ? { "Content-Type": "application/json" } : {}
4659
+ },
4660
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
4661
+ });
4662
+ if (!res.ok) {
4663
+ const text = await res.text().catch(() => "");
4664
+ throw new Error(`fa-app gateway ${method} /${path} [${env}] \u2192 ${res.status}: ${text.slice(0, 200)}`);
4665
+ }
4666
+ return res.json();
4667
+ }
4668
+ function faServerGet(path, env = "prod") {
4669
+ return request("GET", path, env);
4670
+ }
4671
+ function faServerPost(path, body, env = "prod") {
4672
+ return request("POST", path, env, body);
4673
+ }
4674
+ function faServerPut(path, body, env = "prod") {
4675
+ return request("PUT", path, env, body);
4676
+ }
4677
+ function faServerDelete(path, env = "prod") {
4678
+ return request("DELETE", path, env);
4679
+ }
4680
+
4681
+ // src/components/ServerTab.tsx
4682
+ init_hfStateService();
4683
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4684
+ function StarRating({ rating = 0 }) {
4685
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
4686
+ }
4687
+ function ServerTab() {
4688
+ const hasToken = !!getHFToken();
4689
+ const [env, setEnv] = (0, import_react24.useState)("prod");
4690
+ const [step, setStep] = (0, import_react24.useState)("user");
4691
+ const [users, setUsers] = (0, import_react24.useState)([]);
4692
+ const [usersLoading, setUsersLoading] = (0, import_react24.useState)(false);
4693
+ const [usersError, setUsersError] = (0, import_react24.useState)(null);
4694
+ const [selectedUser, setSelectedUser] = (0, import_react24.useState)(null);
4695
+ const [contexts, setContexts] = (0, import_react24.useState)([]);
4696
+ const [contextsLoading, setContextsLoading] = (0, import_react24.useState)(false);
4697
+ const [selectedContext, setSelectedContext] = (0, import_react24.useState)(null);
4698
+ const [tags, setTags] = (0, import_react24.useState)([]);
4699
+ const [items, setItems] = (0, import_react24.useState)([]);
4700
+ const [libLoading, setLibLoading] = (0, import_react24.useState)(false);
4701
+ const [libError, setLibError] = (0, import_react24.useState)(null);
4702
+ const [activeTag, setActiveTag] = (0, import_react24.useState)(null);
4703
+ const [preview, setPreview] = (0, import_react24.useState)(null);
4704
+ (0, import_react24.useEffect)(() => {
4705
+ if (!hasToken) return;
4706
+ setUsersLoading(true);
4707
+ setUsersError(null);
4708
+ faServerGet("/api/v2/users", env).then(setUsers).catch((e) => setUsersError(String(e))).finally(() => setUsersLoading(false));
4709
+ }, [env, hasToken]);
4710
+ const selectUser = async (user) => {
4711
+ setSelectedUser(user);
4712
+ setContextsLoading(true);
4713
+ try {
4714
+ const data = await faServerGet(`/api/v2/contexts?user_id=${user.id}`, env);
4715
+ if (data.length === 1) {
4716
+ await loadLibrary(user, data[0]);
4717
+ } else {
4718
+ setContexts(data);
4719
+ setStep("context");
4720
+ }
4721
+ } catch (e) {
4722
+ setUsersError(String(e));
4723
+ } finally {
4724
+ setContextsLoading(false);
4725
+ }
4726
+ };
4727
+ const loadLibrary = async (user, ctx) => {
4728
+ setSelectedContext(ctx);
4729
+ setStep("library");
4730
+ setLibLoading(true);
4731
+ setLibError(null);
4732
+ try {
4733
+ const [tagsRes, libRes] = await Promise.all([
4734
+ faServerGet(`/api/v2/tags?user_id=${user.id}`, env),
4735
+ faServerGet(`/api/v2/library?user_id=${user.id}&context_id=${ctx.id}&limit=100`, env)
4736
+ ]);
4737
+ setTags(Array.isArray(tagsRes) ? tagsRes : []);
4738
+ const raw = Array.isArray(libRes) ? libRes : libRes.data ?? [];
4739
+ setItems(raw);
4740
+ } catch (e) {
4741
+ setLibError(String(e));
4742
+ } finally {
4743
+ setLibLoading(false);
4744
+ }
4745
+ };
4746
+ const reset = () => {
4747
+ setStep("user");
4748
+ setSelectedUser(null);
4749
+ setSelectedContext(null);
4750
+ setContexts([]);
4751
+ setTags([]);
4752
+ setItems([]);
4753
+ setActiveTag(null);
4754
+ setPreview(null);
4755
+ setLibError(null);
4756
+ };
4757
+ const filteredItems = activeTag ? items.filter((item) => item.tags?.some((t) => t.l === activeTag)) : items;
4758
+ if (!hasToken) {
4759
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex items-center justify-center h-full p-6", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "text-white/30 text-[12px] text-center", children: [
4760
+ "Kein HF Token gesetzt.",
4761
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("br", {}),
4762
+ "Bitte zuerst im Setup-Tab einrichten."
4763
+ ] }) });
4764
+ }
4765
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
4766
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
4767
+ step !== "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: reset, className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "arrow_back" }) }),
4768
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-[11px] font-medium text-white/40 tracking-wide flex-1", children: [
4769
+ step === "user" && "Server Browser",
4770
+ step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
4771
+ step === "library" && `${selectedUser?.username} / ${selectedContext?.label || selectedContext?.name || selectedContext?.id}`
4772
+ ] }),
4773
+ step === "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex gap-1", children: ["prod", "dev"].map((e) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4774
+ "button",
4775
+ {
4776
+ onClick: () => setEnv(e),
4777
+ className: `text-[10px] font-bold px-2 py-0.5 rounded-lg transition-colors ${env === e ? "bg-white/15 text-white" : "text-white/30 hover:text-white/60"}`,
4778
+ children: e
4779
+ },
4780
+ e
4781
+ )) })
4782
+ ] }),
4783
+ step === "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: [
4784
+ usersLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
4785
+ usersError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-red-400 text-[11px] text-center py-4", children: usersError }),
4786
+ !usersLoading && users.map((u) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4787
+ "button",
4788
+ {
4789
+ onClick: () => selectUser(u),
4790
+ className: "flex items-center gap-3 px-3 py-2.5 rounded-xl border border-white/8 hover:border-white/20 hover:bg-white/5 transition-all text-left",
4791
+ children: [
4792
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "person" }),
4793
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
4794
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[12px] font-medium text-white", children: u.username }),
4795
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] text-white/30", children: u.id })
4796
+ ] }),
4797
+ contextsLoading && selectedUser?.id === u.id ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/30 animate-spin", children: "progress_activity" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/20", children: "chevron_right" })
4798
+ ]
4799
+ },
4800
+ u.id
4801
+ ))
4802
+ ] }),
4803
+ step === "context" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: contexts.map((ctx) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4804
+ "button",
4805
+ {
4806
+ onClick: () => loadLibrary(selectedUser, ctx),
4807
+ className: "flex items-center gap-3 px-3 py-2.5 rounded-xl border border-white/8 hover:border-white/20 hover:bg-white/5 transition-all text-left",
4808
+ children: [
4809
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "folder" }),
4810
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
4811
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[12px] font-medium text-white", children: ctx.label || ctx.name || ctx.id }),
4812
+ ctx.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] text-white/30 truncate", children: ctx.description })
4813
+ ] }),
4814
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/20", children: "chevron_right" })
4815
+ ]
4816
+ },
4817
+ ctx.id
4818
+ )) }),
4819
+ step === "library" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
4820
+ tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex gap-1.5 px-3 py-2 overflow-x-auto border-b border-white/8", style: { scrollbarWidth: "none" }, children: [
4821
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4822
+ "button",
4823
+ {
4824
+ onClick: () => setActiveTag(null),
4825
+ className: `shrink-0 text-[10px] font-medium px-2.5 py-1 rounded-lg transition-colors ${!activeTag ? "bg-white/20 text-white" : "bg-white/5 text-white/40 hover:bg-white/10"}`,
4826
+ children: "Alle"
4827
+ }
4828
+ ),
4829
+ tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4830
+ "button",
4831
+ {
4832
+ onClick: () => setActiveTag(activeTag === t.label ? null : t.label),
4833
+ className: `shrink-0 text-[10px] font-medium px-2.5 py-1 rounded-lg transition-colors whitespace-nowrap ${activeTag === t.label ? "bg-white/20 text-white" : "bg-white/5 text-white/40 hover:bg-white/10"}`,
4834
+ children: t.label
4835
+ },
4836
+ t.id
4837
+ ))
4838
+ ] }),
4839
+ libLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-8", children: "Lade Library\u2026" }),
4840
+ libError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-red-400 text-[11px] text-center py-8", children: libError }),
4841
+ !libLoading && !libError && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex-1 min-h-0 overflow-y-auto p-3 grid grid-cols-2 gap-2 content-start", children: [
4842
+ filteredItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "col-span-2 text-white/30 text-[11px] text-center py-8", children: "Keine Eintr\xE4ge." }),
4843
+ filteredItems.map((item) => {
4844
+ const imgUrl = item.images?.[0]?.url;
4845
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4846
+ "button",
4847
+ {
4848
+ onClick: () => imgUrl && setPreview(imgUrl),
4849
+ className: "flex flex-col rounded-xl overflow-hidden border border-white/8 hover:border-white/25 transition-all bg-white/3 text-left",
4850
+ children: [
4851
+ imgUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: imgUrl, alt: "", className: "w-full aspect-square object-cover bg-white/5" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "w-full aspect-square bg-white/5 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[24px] text-white/15", children: "image" }) }),
4852
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "p-1.5 flex flex-col gap-0.5", children: [
4853
+ item.title && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] font-medium text-white/70 truncate", children: item.title }),
4854
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StarRating, { rating: item.rating })
4855
+ ] })
4856
+ ]
4857
+ },
4858
+ item.ref_id
4859
+ );
4860
+ })
4861
+ ] })
4862
+ ] }),
4863
+ preview && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "absolute inset-0 z-50 bg-black/90 flex items-center justify-center", onClick: () => setPreview(null), children: [
4864
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: preview, alt: "", className: "max-w-full max-h-full object-contain" }),
4865
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { className: "absolute top-3 right-3 text-white/60 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: "close" }) })
4866
+ ] })
4867
+ ] });
4868
+ }
4869
+
4373
4870
  // src/components/AvatarArchitectApp.tsx
4374
- var import_jsx_runtime21 = require("react/jsx-runtime");
4871
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4375
4872
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
4376
- (0, import_react23.useEffect)(() => {
4873
+ (0, import_react25.useEffect)(() => {
4377
4874
  const id = "flow-styles";
4378
4875
  if (!document.getElementById(id)) {
4379
4876
  const style = document.createElement("style");
@@ -4382,19 +4879,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4382
4879
  document.head.appendChild(style);
4383
4880
  }
4384
4881
  }, []);
4385
- const [showStart, setShowStart] = (0, import_react23.useState)(true);
4386
- const [layoutChoice, setLayoutChoice] = (0, import_react23.useState)(() => {
4882
+ const [showStart, setShowStart] = (0, import_react25.useState)(true);
4883
+ const [layoutChoice, setLayoutChoice] = (0, import_react25.useState)(() => {
4387
4884
  try {
4388
4885
  return localStorage.getItem("aa-layout") || null;
4389
4886
  } catch {
4390
4887
  return null;
4391
4888
  }
4392
4889
  });
4393
- const [projectLoaded, setProjectLoaded] = (0, import_react23.useState)(false);
4394
- const [hfToken, setHfToken] = (0, import_react23.useState)(initialHfToken || "");
4395
- const [hfTokenInput, setHfTokenInput] = (0, import_react23.useState)(initialHfToken || "");
4396
- const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react23.useState)(false);
4397
- const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react23.useState)(() => {
4890
+ const [projectLoaded, setProjectLoaded] = (0, import_react25.useState)(false);
4891
+ const [hfToken, setHfToken] = (0, import_react25.useState)(initialHfToken || "");
4892
+ const [hfTokenInput, setHfTokenInput] = (0, import_react25.useState)(initialHfToken || "");
4893
+ const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react25.useState)(false);
4894
+ const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react25.useState)(() => {
4398
4895
  try {
4399
4896
  const stored = localStorage.getItem("aa-hf-namespace");
4400
4897
  if (stored !== null) return stored;
@@ -4403,8 +4900,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4403
4900
  return "";
4404
4901
  }
4405
4902
  });
4406
- const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react23.useState)(null);
4407
- (0, import_react23.useEffect)(() => {
4903
+ const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react25.useState)(null);
4904
+ (0, import_react25.useEffect)(() => {
4408
4905
  if (hfNamespace !== void 0) return;
4409
4906
  const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
4410
4907
  if (!backendUrl) return;
@@ -4426,35 +4923,35 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4426
4923
  refresh: refreshHF,
4427
4924
  hasStateZip
4428
4925
  } = useHFState(hfToken, effectiveNamespace);
4429
- const [imageUploadStatus, setImageUploadStatus] = (0, import_react23.useState)(/* @__PURE__ */ new Map());
4430
- const [bootstrapLog, setBootstrapLog] = (0, import_react23.useState)([]);
4431
- const [isBootstrapping, setIsBootstrapping] = (0, import_react23.useState)(false);
4432
- const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4433
- localOnlyCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "rgba(234,179,8,0.15)", border: "1px solid rgba(234,179,8,0.3)", padding: "4px 10px", fontSize: 11, color: "#fbbf24", borderRadius: 4, marginBottom: 4 }, children: [
4926
+ const [imageUploadStatus, setImageUploadStatus] = (0, import_react25.useState)(/* @__PURE__ */ new Map());
4927
+ const [bootstrapLog, setBootstrapLog] = (0, import_react25.useState)([]);
4928
+ const [isBootstrapping, setIsBootstrapping] = (0, import_react25.useState)(false);
4929
+ const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4930
+ localOnlyCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "rgba(234,179,8,0.15)", border: "1px solid rgba(234,179,8,0.3)", padding: "4px 10px", fontSize: 11, color: "#fbbf24", borderRadius: 4, marginBottom: 4 }, children: [
4434
4931
  "\u26A0 ",
4435
4932
  localOnlyCount,
4436
4933
  " lokale Event",
4437
4934
  localOnlyCount > 1 ? "s" : "",
4438
4935
  " noch nicht auf HF best\xE4tigt"
4439
4936
  ] }),
4440
- pendingBufferCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
4937
+ pendingBufferCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
4441
4938
  pendingBufferCount,
4442
4939
  " \xC4nderung",
4443
4940
  pendingBufferCount > 1 ? "en" : "",
4444
4941
  " lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
4445
4942
  ] }),
4446
- eventCount > 100 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
4943
+ eventCount > 100 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
4447
4944
  "\u26A0 ",
4448
4945
  eventCount,
4449
4946
  " Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
4450
4947
  ] }),
4451
- eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
4948
+ eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
4452
4949
  eventCount,
4453
4950
  " Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
4454
4951
  ] }),
4455
- hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
4456
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 12, color: "#a8a29e", marginBottom: 6 }, children: effectiveNamespace ? `Kein State-Snapshot in HF (${effectiveNamespace}) \u2014 aus Legacy-Daten (tags.json + metadata.json) migrieren?` : "Namespace wird geladen\u2026" }),
4457
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4952
+ hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
4953
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { fontSize: 12, color: "#a8a29e", marginBottom: 6 }, children: effectiveNamespace ? `Kein State-Snapshot in HF (${effectiveNamespace}) \u2014 aus Legacy-Daten (tags.json + metadata.json) migrieren?` : "Namespace wird geladen\u2026" }),
4954
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4458
4955
  "button",
4459
4956
  {
4460
4957
  disabled: isBootstrapping || !effectiveNamespace,
@@ -4475,10 +4972,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4475
4972
  children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
4476
4973
  }
4477
4974
  ),
4478
- bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: l }, i)) })
4975
+ bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: l }, i)) })
4479
4976
  ] })
4480
4977
  ] });
4481
- const wsInputRef = (0, import_react23.useRef)(null);
4978
+ const wsInputRef = (0, import_react25.useRef)(null);
4482
4979
  const startApp = (choice) => {
4483
4980
  try {
4484
4981
  localStorage.setItem("aa-layout", choice);
@@ -4487,16 +4984,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4487
4984
  setLayoutChoice(choice);
4488
4985
  setShowStart(false);
4489
4986
  };
4490
- const [nodes, setNodes] = (0, import_react23.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
4491
- const [edges, setEdges] = (0, import_react23.useState)([]);
4492
- const [history, setHistory] = (0, import_react23.useState)([]);
4493
- const [galleryItems, setGalleryItems] = (0, import_react23.useState)([]);
4494
- const galleryItemsRef = (0, import_react23.useRef)([]);
4495
- (0, import_react23.useEffect)(() => {
4987
+ const [nodes, setNodes] = (0, import_react25.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
4988
+ const [edges, setEdges] = (0, import_react25.useState)([]);
4989
+ const [history, setHistory] = (0, import_react25.useState)([]);
4990
+ const [galleryItems, setGalleryItems] = (0, import_react25.useState)([]);
4991
+ const galleryItemsRef = (0, import_react25.useRef)([]);
4992
+ (0, import_react25.useEffect)(() => {
4496
4993
  galleryItemsRef.current = galleryItems;
4497
4994
  }, [galleryItems]);
4498
- const hfImageNotFoundRef = (0, import_react23.useRef)(/* @__PURE__ */ new Map());
4499
- (0, import_react23.useEffect)(() => {
4995
+ const hfImageNotFoundRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
4996
+ (0, import_react25.useEffect)(() => {
4500
4997
  if (!hfState) return;
4501
4998
  if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
4502
4999
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
@@ -4538,62 +5035,62 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4538
5035
  });
4539
5036
  }
4540
5037
  }, [hfState]);
4541
- const [activePrompt, setActivePrompt] = (0, import_react23.useState)("");
4542
- const [isSynthesizing, setIsSynthesizing] = (0, import_react23.useState)(false);
4543
- const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react23.useState)(0);
4544
- const [currentResult, setCurrentResult] = (0, import_react23.useState)(null);
4545
- const [focusedNodeId, setFocusedNodeId] = (0, import_react23.useState)(null);
4546
- const [leftTab, setLeftTab] = (0, import_react23.useState)("prompt");
4547
- const [promptFeedback, setPromptFeedback] = (0, import_react23.useState)(null);
4548
- const [lastPromptPayload, setLastPromptPayload] = (0, import_react23.useState)(null);
4549
- const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react23.useState)(false);
4550
- const [activeTab, setActiveTab] = (0, import_react23.useState)("history");
4551
- const [mobileTab, setMobileTab] = (0, import_react23.useState)("stage");
4552
- const [middlePanel, setMiddlePanel] = (0, import_react23.useState)("stage");
4553
- const [recentLabItems, setRecentLabItems] = (0, import_react23.useState)([]);
4554
- const [aspectRatio, setAspectRatio] = (0, import_react23.useState)("1:1");
4555
- const [selectedModel, setSelectedModel] = (0, import_react23.useState)("\u{1F34C} Nano Banana Pro");
4556
- const [seed, setSeed] = (0, import_react23.useState)(Math.floor(Math.random() * 1e6));
4557
- const [seedMode, setSeedMode] = (0, import_react23.useState)("random");
4558
- const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react23.useState)(false);
4559
- const [isRightCollapsed, setIsRightCollapsed] = (0, import_react23.useState)(false);
4560
- const [leftPanelWidth, setLeftPanelWidth] = (0, import_react23.useState)(() => {
5038
+ const [activePrompt, setActivePrompt] = (0, import_react25.useState)("");
5039
+ const [isSynthesizing, setIsSynthesizing] = (0, import_react25.useState)(false);
5040
+ const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react25.useState)(0);
5041
+ const [currentResult, setCurrentResult] = (0, import_react25.useState)(null);
5042
+ const [focusedNodeId, setFocusedNodeId] = (0, import_react25.useState)(null);
5043
+ const [leftTab, setLeftTab] = (0, import_react25.useState)("prompt");
5044
+ const [promptFeedback, setPromptFeedback] = (0, import_react25.useState)(null);
5045
+ const [lastPromptPayload, setLastPromptPayload] = (0, import_react25.useState)(null);
5046
+ const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react25.useState)(false);
5047
+ const [activeTab, setActiveTab] = (0, import_react25.useState)("history");
5048
+ const [mobileTab, setMobileTab] = (0, import_react25.useState)("stage");
5049
+ const [middlePanel, setMiddlePanel] = (0, import_react25.useState)("stage");
5050
+ const [recentLabItems, setRecentLabItems] = (0, import_react25.useState)([]);
5051
+ const [aspectRatio, setAspectRatio] = (0, import_react25.useState)("1:1");
5052
+ const [selectedModel, setSelectedModel] = (0, import_react25.useState)("\u{1F34C} Nano Banana Pro");
5053
+ const [seed, setSeed] = (0, import_react25.useState)(Math.floor(Math.random() * 1e6));
5054
+ const [seedMode, setSeedMode] = (0, import_react25.useState)("random");
5055
+ const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react25.useState)(false);
5056
+ const [isRightCollapsed, setIsRightCollapsed] = (0, import_react25.useState)(false);
5057
+ const [leftPanelWidth, setLeftPanelWidth] = (0, import_react25.useState)(() => {
4561
5058
  try {
4562
5059
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
4563
5060
  } catch {
4564
5061
  return 260;
4565
5062
  }
4566
5063
  });
4567
- const [rightPanelWidth, setRightPanelWidth] = (0, import_react23.useState)(() => {
5064
+ const [rightPanelWidth, setRightPanelWidth] = (0, import_react25.useState)(() => {
4568
5065
  try {
4569
5066
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
4570
5067
  } catch {
4571
5068
  return 320;
4572
5069
  }
4573
5070
  });
4574
- const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react23.useState)(false);
4575
- const [projectActionState, setProjectActionState] = (0, import_react23.useState)("idle");
4576
- const syncServerDataRef = (0, import_react23.useRef)(null);
4577
- const [workspaceTags, setWorkspaceTags] = (0, import_react23.useState)(null);
4578
- const [serverProjects, setServerProjects] = (0, import_react23.useState)([]);
4579
- const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react23.useState)(false);
4580
- const [highContrast, setHighContrast] = (0, import_react23.useState)(() => {
5071
+ const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react25.useState)(false);
5072
+ const [projectActionState, setProjectActionState] = (0, import_react25.useState)("idle");
5073
+ const syncServerDataRef = (0, import_react25.useRef)(null);
5074
+ const [workspaceTags, setWorkspaceTags] = (0, import_react25.useState)(null);
5075
+ const [serverProjects, setServerProjects] = (0, import_react25.useState)([]);
5076
+ const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react25.useState)(false);
5077
+ const [highContrast, setHighContrast] = (0, import_react25.useState)(() => {
4581
5078
  try {
4582
5079
  return localStorage.getItem("aa-contrast") === "high";
4583
5080
  } catch {
4584
5081
  return false;
4585
5082
  }
4586
5083
  });
4587
- const [activeReferenceId, setActiveReferenceId] = (0, import_react23.useState)(null);
4588
- const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react23.useState)(null);
4589
- const [isScanningImage, setIsScanningImage] = (0, import_react23.useState)(false);
4590
- const [touchStartX, setTouchStartX] = (0, import_react23.useState)(null);
4591
- const [isFullscreen, setIsFullscreen] = (0, import_react23.useState)(false);
4592
- const [zoomScale, setZoomScale] = (0, import_react23.useState)(1);
4593
- const [zoomOffset, setZoomOffset] = (0, import_react23.useState)({ x: 0, y: 0 });
4594
- const lastPinchDist = (0, import_react23.useRef)(null);
4595
- const lastTapTime = (0, import_react23.useRef)(0);
4596
- const dragStart = (0, import_react23.useRef)(null);
5084
+ const [activeReferenceId, setActiveReferenceId] = (0, import_react25.useState)(null);
5085
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react25.useState)(null);
5086
+ const [isScanningImage, setIsScanningImage] = (0, import_react25.useState)(false);
5087
+ const [touchStartX, setTouchStartX] = (0, import_react25.useState)(null);
5088
+ const [isFullscreen, setIsFullscreen] = (0, import_react25.useState)(false);
5089
+ const [zoomScale, setZoomScale] = (0, import_react25.useState)(1);
5090
+ const [zoomOffset, setZoomOffset] = (0, import_react25.useState)({ x: 0, y: 0 });
5091
+ const lastPinchDist = (0, import_react25.useRef)(null);
5092
+ const lastTapTime = (0, import_react25.useRef)(0);
5093
+ const dragStart = (0, import_react25.useRef)(null);
4597
5094
  const openFullscreen = () => {
4598
5095
  setIsFullscreen(true);
4599
5096
  setZoomScale(1);
@@ -4656,7 +5153,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4656
5153
  setActiveReferenceId(null);
4657
5154
  setActiveReferenceThumbnail(null);
4658
5155
  };
4659
- const labServices = (0, import_react23.useMemo)(() => {
5156
+ const labServices = (0, import_react25.useMemo)(() => {
4660
5157
  const available = groupGenerationsToLabItems([...galleryItems, ...history]);
4661
5158
  return {
4662
5159
  availableItems: available,
@@ -4736,17 +5233,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4736
5233
  setIsScanningImage(false);
4737
5234
  }
4738
5235
  };
4739
- const currentIndex = (0, import_react23.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
4740
- const goToPrev = (0, import_react23.useCallback)(() => {
5236
+ const currentIndex = (0, import_react25.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
5237
+ const goToPrev = (0, import_react25.useCallback)(() => {
4741
5238
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
4742
5239
  }, [currentIndex, history]);
4743
- const goToNext = (0, import_react23.useCallback)(() => {
5240
+ const goToNext = (0, import_react25.useCallback)(() => {
4744
5241
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
4745
5242
  }, [currentIndex, history]);
4746
5243
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
4747
5244
  const isGenerating = activeGenerationsCount > 0;
4748
5245
  useKeyboardNavigation(history, currentResult, setCurrentResult);
4749
- const getSubtreeFormat = (0, import_react23.useCallback)((nodeId, depth = 0) => {
5246
+ const getSubtreeFormat = (0, import_react25.useCallback)((nodeId, depth = 0) => {
4750
5247
  const node = nodes.find((n) => n.id === nodeId);
4751
5248
  if (!node) return "";
4752
5249
  const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
@@ -4754,7 +5251,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4754
5251
  return `${indent}- ${node.data.label || "(unbenannt)"}
4755
5252
  ` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
4756
5253
  }, [nodes, edges]);
4757
- const activePath = (0, import_react23.useMemo)(() => {
5254
+ const activePath = (0, import_react25.useMemo)(() => {
4758
5255
  if (!focusedNodeId) return /* @__PURE__ */ new Set();
4759
5256
  const path = /* @__PURE__ */ new Set([focusedNodeId]);
4760
5257
  let currId = focusedNodeId;
@@ -5102,7 +5599,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5102
5599
  setTimeout(() => setProjectActionState("idle"), 4e3);
5103
5600
  }
5104
5601
  };
5105
- (0, import_react23.useEffect)(() => {
5602
+ (0, import_react25.useEffect)(() => {
5106
5603
  if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
5107
5604
  }, [activeTab]);
5108
5605
  const mergeWorkspaceTags = (local, remote) => {
@@ -5126,7 +5623,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5126
5623
  };
5127
5624
  if (isFullscreen && currentResult?.base64) {
5128
5625
  const fsBase64 = currentResult.base64.startsWith("data:") ? currentResult.base64 : `data:image/png;base64,${currentResult.base64}`;
5129
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5626
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5130
5627
  "div",
5131
5628
  {
5132
5629
  className: "fixed inset-0 bg-black z-50 flex items-center justify-center overflow-hidden touch-none",
@@ -5134,7 +5631,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5134
5631
  onTouchMove: handleFsTouchMove,
5135
5632
  onTouchEnd: handleFsTouchEnd,
5136
5633
  children: [
5137
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5634
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5138
5635
  "img",
5139
5636
  {
5140
5637
  src: fsBase64,
@@ -5151,77 +5648,77 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5151
5648
  }
5152
5649
  }
5153
5650
  ),
5154
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: closeFullscreen, className: "absolute top-4 right-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
5155
- zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
5651
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: closeFullscreen, className: "absolute top-4 right-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
5652
+ zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5156
5653
  setZoomScale(1);
5157
5654
  setZoomOffset({ x: 0, y: 0 });
5158
- }, className: "absolute top-4 left-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
5159
- history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5160
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
5655
+ }, className: "absolute top-4 left-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
5656
+ history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5657
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5161
5658
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
5162
- }, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5163
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
5659
+ }, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5660
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5164
5661
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
5165
- }, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5166
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5662
+ }, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5663
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5167
5664
  currentIndex + 1,
5168
5665
  " / ",
5169
5666
  history.length
5170
5667
  ] })
5171
5668
  ] }),
5172
- zoomScale === 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
5669
+ zoomScale === 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
5173
5670
  ]
5174
5671
  }
5175
5672
  );
5176
5673
  }
5177
5674
  if (showStart) {
5178
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
5179
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
5675
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
5676
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
5180
5677
  const f = e.target.files?.[0];
5181
5678
  if (f) handleProjectImport(f);
5182
5679
  e.target.value = "";
5183
5680
  } }),
5184
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
5185
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
5186
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
5187
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
5681
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
5682
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
5683
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
5684
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
5188
5685
  "v",
5189
5686
  LIB_VERSION
5190
5687
  ] })
5191
5688
  ] }),
5192
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5689
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5193
5690
  "button",
5194
5691
  {
5195
5692
  onClick: toggleContrast,
5196
5693
  className: "flex items-center gap-3 px-5 py-3 rounded-2xl border transition-colors",
5197
5694
  style: { borderColor: highContrast ? "rgba(255,255,255,0.3)" : "rgba(255,255,255,0.08)", background: highContrast ? "rgba(255,255,255,0.08)" : "transparent" },
5198
5695
  children: [
5199
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
5200
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-start", children: [
5201
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
5202
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
5696
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
5697
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-start", children: [
5698
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
5699
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
5203
5700
  ] })
5204
5701
  ]
5205
5702
  }
5206
5703
  ),
5207
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5208
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5704
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5705
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5209
5706
  "button",
5210
5707
  {
5211
5708
  onClick: () => wsInputRef.current?.click(),
5212
5709
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform",
5213
5710
  style: { height: 56, background: projectLoaded ? "#16a34a" : "#0284c7" },
5214
5711
  children: [
5215
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
5712
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
5216
5713
  projectLoaded ? "Projekt geladen \u2713" : "Projekt laden (.zip)"
5217
5714
  ]
5218
5715
  }
5219
5716
  ),
5220
- !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
5717
+ !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
5221
5718
  ] }),
5222
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5223
- !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2 w-full", children: [
5224
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5719
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5720
+ !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 w-full", children: [
5721
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5225
5722
  "input",
5226
5723
  {
5227
5724
  type: "password",
@@ -5237,7 +5734,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5237
5734
  style: { height: 44, background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.7)" }
5238
5735
  }
5239
5736
  ),
5240
- hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5737
+ hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5241
5738
  "button",
5242
5739
  {
5243
5740
  type: "button",
@@ -5248,9 +5745,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5248
5745
  }
5249
5746
  )
5250
5747
  ] }),
5251
- !hfNamespace && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
5252
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
5253
- ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5748
+ !hfNamespace && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
5749
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
5750
+ ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5254
5751
  "button",
5255
5752
  {
5256
5753
  onClick: () => {
@@ -5270,7 +5767,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5270
5767
  ns
5271
5768
  ))
5272
5769
  ] }),
5273
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5770
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5274
5771
  "button",
5275
5772
  {
5276
5773
  disabled: isLoadingFromHF,
@@ -5292,15 +5789,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5292
5789
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
5293
5790
  style: { height: 56, background: "#f59e0b" },
5294
5791
  children: [
5295
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
5792
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
5296
5793
  isLoadingFromHF ? "Laden\u2026" : "Von HF laden"
5297
5794
  ]
5298
5795
  }
5299
5796
  ),
5300
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
5797
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
5301
5798
  ] }),
5302
- onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5303
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5799
+ onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5800
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5304
5801
  "button",
5305
5802
  {
5306
5803
  disabled: isLoadingFromServer,
@@ -5321,35 +5818,35 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5321
5818
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
5322
5819
  style: { height: 56, background: "#7c3aed" },
5323
5820
  children: [
5324
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
5821
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
5325
5822
  isLoadingFromServer ? "Laden\u2026" : "Vom Server laden"
5326
5823
  ]
5327
5824
  }
5328
5825
  ),
5329
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
5826
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
5330
5827
  ] }),
5331
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5332
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
5333
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
5828
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5829
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
5830
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
5334
5831
  { id: "mobile", icon: "smartphone", label: "Mobile" },
5335
5832
  { id: "mobile-desktop", icon: "phonelink", label: "Mobile+" },
5336
5833
  { id: "desktop", icon: "desktop_windows", label: "Desktop" },
5337
5834
  { id: "tablet-landscape", icon: "tablet", label: "Landscape" }
5338
- ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5835
+ ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5339
5836
  "button",
5340
5837
  {
5341
5838
  onClick: () => startApp(opt.id),
5342
5839
  className: "flex flex-col items-center gap-2 py-4 rounded-2xl border transition-colors",
5343
5840
  style: { borderColor: layoutChoice === opt.id ? "rgba(255,255,255,0.35)" : "rgba(255,255,255,0.08)", background: layoutChoice === opt.id ? "rgba(255,255,255,0.07)" : "transparent" },
5344
5841
  children: [
5345
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
5346
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
5842
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
5843
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
5347
5844
  ]
5348
5845
  },
5349
5846
  opt.id
5350
5847
  )) }),
5351
- layoutChoice === "mobile-desktop" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
5352
- layoutChoice === "tablet-landscape" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
5848
+ layoutChoice === "mobile-desktop" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
5849
+ layoutChoice === "tablet-landscape" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
5353
5850
  ] })
5354
5851
  ] });
5355
5852
  }
@@ -5358,21 +5855,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5358
5855
  const mdScale = mdMode ? window.innerWidth / 430 : 1;
5359
5856
  const mdW = mdMode ? 430 : void 0;
5360
5857
  const mdH = mdMode ? Math.ceil(window.innerHeight / mdScale) : void 0;
5361
- const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
5858
+ const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
5362
5859
  width: mdMode ? mdW : "100vw",
5363
5860
  height: mdMode ? mdH : "100dvh",
5364
5861
  transform: mdMode ? `scale(${mdScale})` : void 0,
5365
5862
  transformOrigin: mdMode ? "top left" : void 0,
5366
5863
  ...hcStyle || {}
5367
5864
  }, children: [
5368
- mobileTab === "labs" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5865
+ mobileTab === "labs" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5369
5866
  const frame = item.frames[0];
5370
5867
  if (frame?.base64) {
5371
5868
  setCurrentResult(frameToGeneration(frame, item));
5372
5869
  setMobileTab("stage");
5373
5870
  }
5374
5871
  } }) }),
5375
- mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5872
+ mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5376
5873
  TagManagerPanel,
5377
5874
  {
5378
5875
  workspaceTags,
@@ -5383,21 +5880,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5383
5880
  onTagMove: handleTagMove
5384
5881
  }
5385
5882
  ) }),
5386
- mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5387
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
5388
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
5389
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
5390
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1" }),
5391
- activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
5392
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5393
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5394
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5395
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
5396
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
5397
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
5883
+ mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5884
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
5885
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
5886
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
5887
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1" }),
5888
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
5889
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5890
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5891
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5892
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
5893
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
5894
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
5398
5895
  ] }),
5399
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5400
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5896
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5897
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5401
5898
  "textarea",
5402
5899
  {
5403
5900
  value: activePrompt,
@@ -5407,26 +5904,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5407
5904
  placeholder: "Prompt eingeben..."
5408
5905
  }
5409
5906
  ),
5410
- activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center text-white/20 active:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
5907
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center text-white/20 active:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
5411
5908
  ] }) }),
5412
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5909
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5413
5910
  "button",
5414
5911
  {
5415
5912
  onClick: () => handleGenerateImage(),
5416
5913
  disabled: !activePrompt.trim() || isGenerating,
5417
5914
  className: "w-full flex items-center justify-center gap-2 rounded-xl font-bold text-[14px] uppercase tracking-wide transition-all disabled:opacity-30 active:scale-95",
5418
5915
  style: { height: 48, background: activePrompt.trim() && !isGenerating ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
5419
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5420
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
5421
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generiere..." })
5422
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5423
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
5424
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generieren" })
5916
+ children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5917
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
5918
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
5919
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5920
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
5921
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
5425
5922
  ] })
5426
5923
  }
5427
5924
  ) }),
5428
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
5429
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5925
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
5926
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5430
5927
  "div",
5431
5928
  {
5432
5929
  className: "w-full rounded-2xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center",
@@ -5440,25 +5937,25 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5440
5937
  setTouchStartX(null);
5441
5938
  },
5442
5939
  children: [
5443
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
5444
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5445
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5940
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
5941
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5942
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5446
5943
  ] }),
5447
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
5448
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
5449
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
5450
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
5944
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
5945
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
5946
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
5947
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
5451
5948
  ] }),
5452
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
5453
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5454
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
5455
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5949
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
5950
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5951
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
5952
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5456
5953
  ] }),
5457
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
5458
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5459
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: goToPrev, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5460
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5461
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute bottom-2 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5954
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
5955
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5956
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: goToPrev, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5957
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5958
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-2 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5462
5959
  currentIndex + 1,
5463
5960
  " / ",
5464
5961
  history.length
@@ -5467,33 +5964,33 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5467
5964
  ]
5468
5965
  }
5469
5966
  ),
5470
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2 mt-3", children: [
5471
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
5472
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
5473
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
5967
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 mt-3", children: [
5968
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
5969
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
5970
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
5474
5971
  ] }),
5475
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-white/10 active:bg-white/15 transition-colors", style: { height: 44 }, children: [
5476
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
5477
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
5972
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-white/10 active:bg-white/15 transition-colors", style: { height: 44 }, children: [
5973
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
5974
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
5478
5975
  ] }),
5479
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleDownloadSingle, className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
5480
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
5481
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
5976
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: handleDownloadSingle, className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
5977
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
5978
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
5482
5979
  ] })
5483
5980
  ] })
5484
5981
  ] })
5485
5982
  ] }),
5486
- mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5487
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5488
- ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab(tab), className: `flex-1 flex items-center justify-center gap-1.5 transition-colors text-[11px] font-bold uppercase tracking-wide ${activeTab === tab ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
5489
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-12 flex items-center justify-center text-white/20 active:text-white transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
5983
+ mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5984
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5985
+ ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab(tab), className: `flex-1 flex items-center justify-center gap-1.5 transition-colors text-[11px] font-bold uppercase tracking-wide ${activeTab === tab ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
5986
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-12 flex items-center justify-center text-white/20 active:text-white transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
5490
5987
  ] }),
5491
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5492
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
5988
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5989
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
5493
5990
  setCurrentResult(g);
5494
5991
  setMobileTab("stage");
5495
5992
  }, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
5496
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5993
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5497
5994
  MediaLibrary,
5498
5995
  {
5499
5996
  items: galleryItems,
@@ -5513,43 +6010,44 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5513
6010
  }
5514
6011
  }
5515
6012
  ),
5516
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
6013
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
5517
6014
  setCurrentResult(g);
5518
6015
  } })
5519
6016
  ] })
5520
6017
  ] }),
5521
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
5522
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5523
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => {
6018
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
6019
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6020
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => {
5524
6021
  setLeftTab("prompt");
5525
6022
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
5526
6023
  }, className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5527
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
6024
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
5528
6025
  "Prompt"
5529
6026
  ] }),
5530
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => {
6027
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => {
5531
6028
  setLeftTab("hierarchy");
5532
6029
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
5533
6030
  }, className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5534
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
6031
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
5535
6032
  "Hierarchie"
5536
6033
  ] }),
5537
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("setup"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "setup" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5538
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
6034
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActiveTab("setup"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "setup" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
6035
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
5539
6036
  "Setup"
5540
6037
  ] }),
5541
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("sync"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5542
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
6038
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActiveTab("sync"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
6039
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
5543
6040
  "Sync"
5544
6041
  ] }),
5545
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("hftest"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "hftest" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5546
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
6042
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActiveTab("hftest"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "hftest" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
6043
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
5547
6044
  "HF"
5548
6045
  ] }),
5549
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
6046
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("server"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "server" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
6047
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5550
6048
  ] }),
5551
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5552
- leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6049
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6050
+ leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5553
6051
  ListView,
5554
6052
  {
5555
6053
  nodes,
@@ -5580,12 +6078,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5580
6078
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
5581
6079
  }
5582
6080
  ) }),
5583
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
6081
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
5584
6082
  handleGenerateImage(prompt);
5585
6083
  setMobileTab("stage");
5586
6084
  }, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
5587
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5588
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6085
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6086
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5589
6087
  ProjectSyncTab,
5590
6088
  {
5591
6089
  topSlot: syncTopSlot,
@@ -5609,7 +6107,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5609
6107
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
5610
6108
  }
5611
6109
  ),
5612
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6110
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5613
6111
  TagManagerPanel,
5614
6112
  {
5615
6113
  workspaceTags,
@@ -5620,7 +6118,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5620
6118
  onTagMove: handleTagMove
5621
6119
  }
5622
6120
  ),
5623
- activeTab === "hftest" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6121
+ activeTab === "hftest" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5624
6122
  HFTestTab,
5625
6123
  {
5626
6124
  token: hfToken,
@@ -5630,22 +6128,23 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5630
6128
  confirmedEventKeys: hfConfirmedKeys,
5631
6129
  imageUploadStatus
5632
6130
  }
5633
- ) })
6131
+ ) }),
6132
+ activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {}) })
5634
6133
  ] })
5635
6134
  ] }),
5636
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
6135
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
5637
6136
  { id: "tools", icon: "auto_fix_high", label: "Prompt" },
5638
6137
  { id: "stage", icon: "palette", label: "Stage" },
5639
6138
  { id: "labs", icon: "science", label: "Labs" },
5640
6139
  ...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
5641
6140
  { id: "browse", icon: "photo_library", label: "Galerie" }
5642
- ].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
5643
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
5644
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
6141
+ ].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
6142
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
6143
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
5645
6144
  ] }, tab.id)) })
5646
6145
  ] });
5647
6146
  if (mdMode) {
5648
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
6147
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
5649
6148
  }
5650
6149
  return mobileRoot;
5651
6150
  }
@@ -5653,17 +6152,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5653
6152
  const tlScale = Math.min(window.innerWidth / 920, window.innerHeight / 520);
5654
6153
  const tlW = 920;
5655
6154
  const tlH = 520;
5656
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
5657
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
5658
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { height: 52, borderBottom: "1px solid rgba(255,255,255,0.05)", display: "flex", alignItems: "center", gap: 8, padding: "0 12px", flexShrink: 0 }, children: [
5659
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
5660
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
5661
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
5662
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
5663
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
6155
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
6156
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
6157
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: 52, borderBottom: "1px solid rgba(255,255,255,0.05)", display: "flex", alignItems: "center", gap: 8, padding: "0 12px", flexShrink: 0 }, children: [
6158
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6159
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6160
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1 } }),
6161
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
6162
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
5664
6163
  ] }),
5665
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "relative", borderRadius: 12, border: `1px solid ${isSynthesizing ? "rgba(255,255,255,0.2)" : "rgba(255,255,255,0.1)"}`, background: "rgba(255,255,255,0.05)" }, children: [
5666
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6164
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", borderRadius: 12, border: `1px solid ${isSynthesizing ? "rgba(255,255,255,0.2)" : "rgba(255,255,255,0.1)"}`, background: "rgba(255,255,255,0.05)" }, children: [
6165
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5667
6166
  "textarea",
5668
6167
  {
5669
6168
  value: activePrompt,
@@ -5672,27 +6171,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5672
6171
  placeholder: "Prompt eingeben..."
5673
6172
  }
5674
6173
  ),
5675
- activePrompt && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActivePrompt(""), style: { position: "absolute", top: 6, right: 6, width: 22, height: 22, display: "flex", alignItems: "center", justifyContent: "center", color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
6174
+ activePrompt && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), style: { position: "absolute", top: 6, right: 6, width: 22, height: 22, display: "flex", alignItems: "center", justifyContent: "center", color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
5676
6175
  ] }) }),
5677
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6176
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5678
6177
  "button",
5679
6178
  {
5680
6179
  onClick: () => handleGenerateImage(),
5681
6180
  disabled: !activePrompt.trim() || isGenerating,
5682
6181
  style: { width: "100%", height: 42, display: "flex", alignItems: "center", justifyContent: "center", gap: 8, borderRadius: 10, fontWeight: "bold", fontSize: 13, textTransform: "uppercase", letterSpacing: "0.05em", border: "1px solid rgba(255,255,255,0.1)", background: activePrompt.trim() && !isGenerating ? "#0284c7" : "transparent", color: "#fff", cursor: activePrompt.trim() && !isGenerating ? "pointer" : "default", opacity: !activePrompt.trim() || isGenerating ? 0.3 : 1, fontFamily: "inherit", transition: "background 0.2s" },
5683
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5684
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5685
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generiere..." })
5686
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5687
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
5688
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generieren" })
6182
+ children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6183
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
6184
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
6185
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6186
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
6187
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
5689
6188
  ] })
5690
6189
  }
5691
6190
  ) }),
5692
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
6191
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
5693
6192
  ] }),
5694
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
5695
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6193
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
6194
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5696
6195
  "div",
5697
6196
  {
5698
6197
  style: { flex: 1, padding: 16, display: "flex", alignItems: "center", justifyContent: "center", position: "relative" },
@@ -5704,26 +6203,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5704
6203
  else if (dx > 50) goToPrev();
5705
6204
  setTouchStartX(null);
5706
6205
  },
5707
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { height: "100%", width: "100%", borderRadius: 20, border: "1px solid rgba(255,255,255,0.05)", background: "rgba(0,0,0,0.4)", position: "relative", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center" }, children: [
5708
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5709
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5710
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6206
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: "100%", width: "100%", borderRadius: 20, border: "1px solid rgba(255,255,255,0.05)", background: "rgba(0,0,0,0.4)", position: "relative", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center" }, children: [
6207
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6208
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
6209
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
5711
6210
  ] }),
5712
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5713
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
5714
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
5715
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
6211
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6212
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
6213
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
6214
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
5716
6215
  ] }),
5717
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
5718
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
5719
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
5720
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
6216
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
6217
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
6218
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
6219
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
5721
6220
  ] }),
5722
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
5723
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5724
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: goToPrev, disabled: currentIndex <= 0, style: { position: "absolute", left: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex <= 0 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
5725
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, style: { position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex >= history.length - 1 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
5726
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "absolute", bottom: 8, left: "50%", transform: "translateX(-50%)", background: "rgba(0,0,0,0.6)", borderRadius: 999, padding: "2px 12px", fontSize: 10, color: "rgba(255,255,255,0.4)", fontFamily: "monospace" }, children: [
6221
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
6222
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6223
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: goToPrev, disabled: currentIndex <= 0, style: { position: "absolute", left: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex <= 0 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
6224
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, style: { position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex >= history.length - 1 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
6225
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "absolute", bottom: 8, left: "50%", transform: "translateX(-50%)", background: "rgba(0,0,0,0.6)", borderRadius: 999, padding: "2px 12px", fontSize: 10, color: "rgba(255,255,255,0.4)", fontFamily: "monospace" }, children: [
5727
6226
  currentIndex + 1,
5728
6227
  " / ",
5729
6228
  history.length
@@ -5732,42 +6231,42 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5732
6231
  ] })
5733
6232
  }
5734
6233
  ),
5735
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
5736
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
5737
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
5738
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Prompt" })
6234
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
6235
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
6236
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
6237
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Prompt" })
5739
6238
  ] }),
5740
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "none", background: "rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.8)", fontSize: 11, fontWeight: "bold", cursor: "pointer", fontFamily: "inherit" }, children: [
5741
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
5742
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Referenz" })
6239
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "none", background: "rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.8)", fontSize: 11, fontWeight: "bold", cursor: "pointer", fontFamily: "inherit" }, children: [
6240
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
6241
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Referenz" })
5743
6242
  ] }),
5744
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleDownloadSingle, style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
5745
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
5746
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Laden" })
6243
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: handleDownloadSingle, style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
6244
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
6245
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Laden" })
5747
6246
  ] })
5748
6247
  ] })
5749
6248
  ] })
5750
6249
  ] }) });
5751
6250
  }
5752
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
5753
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
5754
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
5755
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
5756
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-1 gap-1", children: [
5757
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5758
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
6251
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
6252
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
6253
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
6254
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
6255
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-1 gap-1", children: [
6256
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
6257
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
5759
6258
  "Prompt"
5760
6259
  ] }),
5761
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setLeftTab("hierarchy"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5762
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
6260
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setLeftTab("hierarchy"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
6261
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
5763
6262
  "Hierarchie"
5764
6263
  ] }),
5765
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
6264
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5766
6265
  ] }),
5767
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsLeftCollapsed(!isLeftCollapsed), className: "material-symbols-outlined text-[18px] text-white/40 hover:text-white transition-all w-10 flex items-center justify-center", children: isLeftCollapsed ? "chevron_right" : "chevron_left" })
6266
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setIsLeftCollapsed(!isLeftCollapsed), className: "material-symbols-outlined text-[18px] text-white/40 hover:text-white transition-all w-10 flex items-center justify-center", children: isLeftCollapsed ? "chevron_right" : "chevron_left" })
5768
6267
  ] }),
5769
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5770
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6268
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6269
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5771
6270
  TagManagerPanel,
5772
6271
  {
5773
6272
  workspaceTags,
@@ -5778,11 +6277,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5778
6277
  onTagMove: handleTagMove
5779
6278
  }
5780
6279
  ),
5781
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
5782
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5783
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6280
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
6281
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6282
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5784
6283
  ] }) }),
5785
- leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6284
+ leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5786
6285
  ListView,
5787
6286
  {
5788
6287
  nodes,
@@ -5807,18 +6306,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5807
6306
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
5808
6307
  }
5809
6308
  ) }),
5810
- leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
6309
+ leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
5811
6310
  ] })
5812
6311
  ] }),
5813
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
5814
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
5815
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
5816
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5", children: [
5817
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
5818
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
6312
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
6313
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
6314
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
6315
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1.5", children: [
6316
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6317
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
5819
6318
  ] }),
5820
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
5821
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6319
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
6320
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5822
6321
  "button",
5823
6322
  {
5824
6323
  onClick: () => setMiddlePanel("stage"),
@@ -5826,7 +6325,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5826
6325
  children: "Stage"
5827
6326
  }
5828
6327
  ),
5829
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6328
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5830
6329
  "button",
5831
6330
  {
5832
6331
  onClick: () => setMiddlePanel("labs"),
@@ -5835,68 +6334,68 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5835
6334
  }
5836
6335
  )
5837
6336
  ] }),
5838
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
5839
- activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
5840
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5841
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5842
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5843
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
5844
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
5845
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Ref" })
6337
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
6338
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
6339
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6340
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6341
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6342
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
6343
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
6344
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Ref" })
5846
6345
  ] }),
5847
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
5848
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
6346
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
6347
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
5849
6348
  ] })
5850
6349
  ] }),
5851
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
5852
- !isPromptCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5853
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("textarea", { value: activePrompt, onChange: (e) => setActivePrompt(e.target.value), className: "w-full bg-transparent border-none outline-none text-[12px] leading-relaxed text-white/80 resize-none h-20 dark-scrollbar", placeholder: "W\xE4hle einen Knoten oder tippe einen Prompt..." }),
5854
- activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-6 h-6 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-colors text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6350
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
6351
+ !isPromptCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
6352
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("textarea", { value: activePrompt, onChange: (e) => setActivePrompt(e.target.value), className: "w-full bg-transparent border-none outline-none text-[12px] leading-relaxed text-white/80 resize-none h-20 dark-scrollbar", placeholder: "W\xE4hle einen Knoten oder tippe einen Prompt..." }),
6353
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-6 h-6 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-colors text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5855
6354
  ] }) }),
5856
- middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LabsTab, { services: labServices, onResult: (item) => {
6355
+ middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5857
6356
  const frame = item.frames[0];
5858
6357
  if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
5859
- } }) }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: [
5860
- isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute top-6 right-6 z-30 bg-black/60 backdrop-blur-md px-4 py-2 rounded-full border border-white/10 flex items-center gap-3", children: [
5861
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
5862
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
6358
+ } }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: [
6359
+ isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute top-6 right-6 z-30 bg-black/60 backdrop-blur-md px-4 py-2 rounded-full border border-white/10 flex items-center gap-3", children: [
6360
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
6361
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
5863
6362
  ] }),
5864
- currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
5865
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5866
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5867
- ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
5868
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
5869
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col gap-2", children: [
5870
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
5871
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
6363
+ currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
6364
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
6365
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6366
+ ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
6367
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
6368
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
6369
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
6370
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
5872
6371
  ] }),
5873
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
5874
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
5875
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
5876
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
5877
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
5878
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
5879
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
6372
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
6373
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
6374
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
6375
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
6376
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
6377
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
6378
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
5880
6379
  ] })
5881
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5882
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
5883
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6380
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6381
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
6382
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5884
6383
  ] })
5885
6384
  ] }) })
5886
6385
  ] })
5887
6386
  ] }),
5888
- !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
5889
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
5890
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
5891
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
6387
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
6388
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
6389
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
6390
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync", "tags", "server"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5892
6391
  setActiveTab(tab);
5893
6392
  setIsRightCollapsed(false);
5894
- }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : "label" }) }, tab)) }),
5895
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-10 flex items-center justify-center text-white/20 hover:text-white/60 transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
5896
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
6393
+ }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : tab === "tags" ? "label" : "storage" }) }, tab)) }),
6394
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-10 flex items-center justify-center text-white/20 hover:text-white/60 transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
6395
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
5897
6396
  ] }),
5898
- !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5899
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6397
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6398
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5900
6399
  TagManagerPanel,
5901
6400
  {
5902
6401
  workspaceTags,
@@ -5907,12 +6406,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5907
6406
  onTagMove: handleTagMove
5908
6407
  }
5909
6408
  ),
5910
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
5911
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5912
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6409
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
6410
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6411
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5913
6412
  ] }) }),
5914
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
5915
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6413
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
6414
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5916
6415
  MediaLibrary,
5917
6416
  {
5918
6417
  items: galleryItems,
@@ -5926,9 +6425,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5926
6425
  onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
5927
6426
  }
5928
6427
  ),
5929
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
5930
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5931
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6428
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
6429
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6430
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5932
6431
  ProjectSyncTab,
5933
6432
  {
5934
6433
  topSlot: syncTopSlot,
@@ -5951,15 +6450,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5951
6450
  },
5952
6451
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
5953
6452
  }
5954
- )
6453
+ ),
6454
+ activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {})
5955
6455
  ] })
5956
6456
  ] })
5957
6457
  ] });
5958
6458
  }
5959
6459
 
5960
6460
  // src/components/FaApp.tsx
5961
- var import_react24 = require("react");
5962
- var import_jsx_runtime22 = require("react/jsx-runtime");
6461
+ var import_react26 = require("react");
6462
+ var import_jsx_runtime24 = require("react/jsx-runtime");
5963
6463
  function FaApp({
5964
6464
  onGenerateImage,
5965
6465
  onGeneratePrompt,
@@ -5978,8 +6478,8 @@ function FaApp({
5978
6478
  onServerDelete,
5979
6479
  buildInfo
5980
6480
  }) {
5981
- const [hfNamespace, setHfNamespace] = (0, import_react24.useState)(void 0);
5982
- (0, import_react24.useEffect)(() => {
6481
+ const [hfNamespace, setHfNamespace] = (0, import_react26.useState)(void 0);
6482
+ (0, import_react26.useEffect)(() => {
5983
6483
  if (!serverBaseUrl) return;
5984
6484
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
5985
6485
  if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
@@ -5990,7 +6490,7 @@ function FaApp({
5990
6490
  const result = await onGeneratePrompt(text, options);
5991
6491
  return result.text;
5992
6492
  };
5993
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6493
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5994
6494
  AvatarArchitectApp,
5995
6495
  {
5996
6496
  onGenerateImage,
@@ -6012,7 +6512,7 @@ function FaApp({
6012
6512
  // src/index.ts
6013
6513
  init_hfStateService();
6014
6514
  init_hfStateService();
6015
- var LIB_VERSION = "2.0.22";
6515
+ var LIB_VERSION = "2.0.24";
6016
6516
  // Annotate the CommonJS export names for ESM import in node:
6017
6517
  0 && (module.exports = {
6018
6518
  AvatarArchitectApp,
@@ -6026,6 +6526,7 @@ var LIB_VERSION = "2.0.22";
6026
6526
  LIB_VERSION,
6027
6527
  LabBlend,
6028
6528
  LabCompare,
6529
+ LabFrameExtractor,
6029
6530
  LabImagePicker,
6030
6531
  LabLoop,
6031
6532
  LabRemix,
@@ -6036,6 +6537,7 @@ var LIB_VERSION = "2.0.22";
6036
6537
  ProjectSyncTab,
6037
6538
  PromptTab,
6038
6539
  SectionLabel,
6540
+ ServerTab,
6039
6541
  SetupPanel,
6040
6542
  TagManagerPanel,
6041
6543
  applyEvent,
@@ -6055,6 +6557,10 @@ var LIB_VERSION = "2.0.22";
6055
6557
  cleanAiResponse,
6056
6558
  createFlowServices,
6057
6559
  exportProjectToZip,
6560
+ faServerDelete,
6561
+ faServerGet,
6562
+ faServerPost,
6563
+ faServerPut,
6058
6564
  findForks,
6059
6565
  findTips,
6060
6566
  formatTreeToMarkdown,