@rslsp1/fa-app-tools 2.0.61 → 2.0.62

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
@@ -1540,7 +1540,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
1540
1540
  }
1541
1541
 
1542
1542
  // src/components/AvatarArchitectApp.tsx
1543
- var import_react25 = require("react");
1543
+ var import_react26 = require("react");
1544
1544
 
1545
1545
  // src/components/PromptTab.tsx
1546
1546
  var import_react12 = require("react");
@@ -2849,10 +2849,10 @@ function useHFState(token, namespace) {
2849
2849
  }
2850
2850
 
2851
2851
  // src/components/labs/LabsTab.tsx
2852
- var import_react21 = require("react");
2852
+ var import_react22 = require("react");
2853
2853
 
2854
2854
  // src/components/labs/LabRemix.tsx
2855
- var import_react16 = require("react");
2855
+ var import_react17 = require("react");
2856
2856
 
2857
2857
  // src/components/labs/LabImagePicker.tsx
2858
2858
  var import_react15 = require("react");
@@ -2964,16 +2964,120 @@ var LabImagePicker = ({
2964
2964
  ] });
2965
2965
  };
2966
2966
 
2967
- // src/components/labs/LabRemix.tsx
2967
+ // src/components/GenerationControls.tsx
2968
2968
  var import_jsx_runtime14 = require("react/jsx-runtime");
2969
+ var ASPECT_OPTIONS = [
2970
+ { label: "1:1", value: "1:1" },
2971
+ { label: "16:9", value: "16:9" },
2972
+ { label: "9:16", value: "9:16" }
2973
+ ];
2974
+ var MODEL_OPTIONS = [
2975
+ { value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" },
2976
+ { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" },
2977
+ { value: "Imagen 4", label: "Imagen 4" }
2978
+ ];
2979
+ var COUNT_OPTIONS = [
2980
+ { label: "1 Bild", value: "1" },
2981
+ { label: "2 Bilder", value: "2" },
2982
+ { label: "4 Bilder", value: "4" },
2983
+ { label: "8 Bilder", value: "8" }
2984
+ ];
2985
+ var GenerationControls = ({
2986
+ aspectRatio,
2987
+ onAspectRatioChange,
2988
+ model,
2989
+ onModelChange,
2990
+ imageCount,
2991
+ onImageCountChange,
2992
+ runningCount = 0,
2993
+ className
2994
+ }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `flex items-center gap-2 flex-wrap ${className || ""}`, children: [
2995
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CompactDropdown, { value: aspectRatio, onChange: onAspectRatioChange, options: ASPECT_OPTIONS }),
2996
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CompactDropdown, { value: model, onChange: onModelChange, options: MODEL_OPTIONS }),
2997
+ imageCount !== void 0 && onImageCountChange && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2998
+ CompactDropdown,
2999
+ {
3000
+ value: String(imageCount),
3001
+ displayValue: `${imageCount}\xD7`,
3002
+ onChange: onImageCountChange,
3003
+ options: COUNT_OPTIONS
3004
+ }
3005
+ ),
3006
+ runningCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3007
+ "div",
3008
+ {
3009
+ className: "flex items-center gap-1 rounded-full bg-sky-500/15 border border-sky-400/30 px-2 shrink-0",
3010
+ style: { height: 24 },
3011
+ title: `${runningCount} Generierung${runningCount === 1 ? "" : "en"} l\xE4uft`,
3012
+ children: [
3013
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
3014
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: runningCount })
3015
+ ]
3016
+ }
3017
+ )
3018
+ ] });
3019
+
3020
+ // src/hooks/useGenerationSettings.ts
3021
+ var import_react16 = require("react");
3022
+ function useGenerationSettings() {
3023
+ const [aspectRatio, setAspectRatio] = (0, import_react16.useState)(() => {
3024
+ try {
3025
+ return localStorage.getItem("aa-lab-aspect") || "1:1";
3026
+ } catch {
3027
+ return "1:1";
3028
+ }
3029
+ });
3030
+ const [model, setModel] = (0, import_react16.useState)(() => {
3031
+ try {
3032
+ return localStorage.getItem("aa-lab-model") || "\u{1F34C} Nano Banana Pro";
3033
+ } catch {
3034
+ return "\u{1F34C} Nano Banana Pro";
3035
+ }
3036
+ });
3037
+ const [imageCount, setImageCount] = (0, import_react16.useState)(() => {
3038
+ try {
3039
+ const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
3040
+ return v >= 1 && v <= 8 ? v : 4;
3041
+ } catch {
3042
+ return 4;
3043
+ }
3044
+ });
3045
+ const updateAspectRatio = (v) => {
3046
+ setAspectRatio(v);
3047
+ try {
3048
+ localStorage.setItem("aa-lab-aspect", v);
3049
+ } catch {
3050
+ }
3051
+ };
3052
+ const updateModel = (v) => {
3053
+ setModel(v);
3054
+ try {
3055
+ localStorage.setItem("aa-lab-model", v);
3056
+ } catch {
3057
+ }
3058
+ };
3059
+ const updateImageCount = (v) => {
3060
+ const n = Math.max(1, Math.min(8, parseInt(v, 10) || 4));
3061
+ setImageCount(n);
3062
+ try {
3063
+ localStorage.setItem("aa-image-count", String(n));
3064
+ } catch {
3065
+ }
3066
+ };
3067
+ return { aspectRatio, model, imageCount, updateAspectRatio, updateModel, updateImageCount };
3068
+ }
3069
+
3070
+ // src/components/labs/LabRemix.tsx
3071
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2969
3072
  var LabRemix = ({ services, onResult }) => {
2970
- const [showPicker, setShowPicker] = (0, import_react16.useState)(false);
2971
- const [selected, setSelected] = (0, import_react16.useState)(null);
2972
- const [instruction, setInstruction] = (0, import_react16.useState)("");
2973
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react16.useState)("");
2974
- const [resultImage, setResultImage] = (0, import_react16.useState)(null);
2975
- const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react16.useState)(false);
2976
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react16.useState)(false);
3073
+ const [showPicker, setShowPicker] = (0, import_react17.useState)(false);
3074
+ const [selected, setSelected] = (0, import_react17.useState)(null);
3075
+ const [instruction, setInstruction] = (0, import_react17.useState)("");
3076
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react17.useState)("");
3077
+ const [resultImages, setResultImages] = (0, import_react17.useState)([]);
3078
+ const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react17.useState)(false);
3079
+ const [runningCount, setRunningCount] = (0, import_react17.useState)(0);
3080
+ const { aspectRatio, model, imageCount, updateAspectRatio, updateModel, updateImageCount } = useGenerationSettings();
2977
3081
  const handleSelectImage = (item, frame) => {
2978
3082
  services.onItemUsed(item);
2979
3083
  setSelected({
@@ -2986,7 +3090,7 @@ var LabRemix = ({ services, onResult }) => {
2986
3090
  roleForImage: ""
2987
3091
  });
2988
3092
  setGeneratedPrompt("");
2989
- setResultImage(null);
3093
+ setResultImages([]);
2990
3094
  };
2991
3095
  const handleGeneratePrompt = async () => {
2992
3096
  if (!selected || !instruction.trim()) return;
@@ -3005,34 +3109,40 @@ var LabRemix = ({ services, onResult }) => {
3005
3109
  setIsGeneratingPrompt(false);
3006
3110
  }
3007
3111
  };
3008
- const handleGenerateImage = async () => {
3112
+ const handleGenerateBatch = async () => {
3009
3113
  if (!generatedPrompt) return;
3010
- setIsGeneratingImage(true);
3011
- try {
3012
- const refIds = buildReferenceImageMediaIds(selected ? [selected] : []);
3013
- const { base64, mediaId } = await services.generateImage({
3014
- prompt: generatedPrompt,
3015
- aspectRatio: selected?.frame.aspectRatio || "1:1",
3016
- modelDisplayName: selected?.frame.model || "\u{1F34C} Nano Banana Pro",
3017
- ...refIds.length ? { referenceImageMediaIds: refIds } : {}
3018
- });
3019
- const newBase64 = `data:image/png;base64,${base64}`;
3020
- setResultImage(newBase64);
3021
- const frameId = crypto.randomUUID();
3022
- const newItem = {
3023
- id: frameId,
3024
- prompt: generatedPrompt,
3025
- tags: selected?.item.tags || [],
3026
- frames: [{ id: frameId, base64: newBase64, mediaId, source: "generated" }]
3027
- };
3028
- services.saveResult?.(newItem);
3029
- onResult?.(newItem);
3030
- } finally {
3031
- setIsGeneratingImage(false);
3114
+ const count = Math.max(1, Math.min(8, imageCount));
3115
+ const refIds = buildReferenceImageMediaIds(selected ? [selected] : []);
3116
+ const options = {
3117
+ prompt: generatedPrompt,
3118
+ aspectRatio,
3119
+ modelDisplayName: model,
3120
+ ...refIds.length ? { referenceImageMediaIds: refIds } : {}
3121
+ };
3122
+ setRunningCount((c) => c + count);
3123
+ const results = await Promise.allSettled(
3124
+ Array.from({ length: count }, () => services.generateImage(options))
3125
+ );
3126
+ setRunningCount((c) => c - count);
3127
+ for (const r of results) {
3128
+ if (r.status === "fulfilled") {
3129
+ const { base64, mediaId } = r.value;
3130
+ const newBase64 = `data:image/png;base64,${base64}`;
3131
+ setResultImages((prev) => [newBase64, ...prev]);
3132
+ const frameId = crypto.randomUUID();
3133
+ const newItem = {
3134
+ id: frameId,
3135
+ prompt: generatedPrompt,
3136
+ tags: selected?.item.tags || [],
3137
+ frames: [{ id: frameId, base64: newBase64, mediaId, source: "generated" }]
3138
+ };
3139
+ services.saveResult?.(newItem);
3140
+ onResult?.(newItem);
3141
+ }
3032
3142
  }
3033
3143
  };
3034
3144
  if (showPicker) {
3035
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3145
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3036
3146
  LabImagePicker,
3037
3147
  {
3038
3148
  availableItems: services.availableItems,
@@ -3043,15 +3153,15 @@ var LabRemix = ({ services, onResult }) => {
3043
3153
  }
3044
3154
  );
3045
3155
  }
3046
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3047
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3048
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Basis-Bild" }),
3049
- selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3050
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: selected.frame.base64, className: "w-16 h-16 object-cover rounded-lg shrink-0" }),
3051
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [
3052
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-[10px] text-white/60 leading-tight line-clamp-2", children: selected.item.prompt }),
3053
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 text-[10px] text-white/50", children: [
3054
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3156
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3157
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3158
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Basis-Bild" }),
3159
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3160
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src: selected.frame.base64, className: "w-16 h-16 object-cover rounded-lg shrink-0" }),
3161
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [
3162
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[10px] text-white/60 leading-tight line-clamp-2", children: selected.item.prompt }),
3163
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-[10px] text-white/50", children: [
3164
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3055
3165
  "input",
3056
3166
  {
3057
3167
  type: "checkbox",
@@ -3061,8 +3171,8 @@ var LabRemix = ({ services, onResult }) => {
3061
3171
  ),
3062
3172
  "Bild an KI (Prompt)"
3063
3173
  ] }),
3064
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 text-[10px] text-white/50", children: [
3065
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3174
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-[10px] text-white/50", children: [
3175
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3066
3176
  "input",
3067
3177
  {
3068
3178
  type: "checkbox",
@@ -3072,7 +3182,7 @@ var LabRemix = ({ services, onResult }) => {
3072
3182
  ),
3073
3183
  "Bild als Referenz (Generierung)"
3074
3184
  ] }),
3075
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3185
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3076
3186
  "input",
3077
3187
  {
3078
3188
  value: selected.roleForPrompt || "",
@@ -3082,22 +3192,22 @@ var LabRemix = ({ services, onResult }) => {
3082
3192
  }
3083
3193
  )
3084
3194
  ] }),
3085
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: () => setShowPicker(true), className: "text-white/30 active:text-white self-start", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "swap_horiz" }) })
3086
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3195
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: () => setShowPicker(true), className: "text-white/30 active:text-white self-start", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "swap_horiz" }) })
3196
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3087
3197
  "button",
3088
3198
  {
3089
3199
  onClick: () => setShowPicker(true),
3090
3200
  className: "w-full py-6 rounded-xl border border-dashed border-white/20 text-[11px] text-white/30 active:bg-white/5 flex items-center justify-center gap-2",
3091
3201
  children: [
3092
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }),
3202
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }),
3093
3203
  "Bild w\xE4hlen"
3094
3204
  ]
3095
3205
  }
3096
3206
  )
3097
3207
  ] }),
3098
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3099
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Anweisung" }),
3100
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3208
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3209
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Anweisung" }),
3210
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3101
3211
  "textarea",
3102
3212
  {
3103
3213
  value: instruction,
@@ -3108,25 +3218,24 @@ var LabRemix = ({ services, onResult }) => {
3108
3218
  }
3109
3219
  )
3110
3220
  ] }),
3111
- services.workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-[9px] text-white/20 italic", children: "Tags: Workspace-Tags k\xF6nnen unter der Anweisung erg\xE4nzt werden (folgt in n\xE4chstem Update)" }),
3112
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3221
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3113
3222
  "button",
3114
3223
  {
3115
3224
  onClick: handleGeneratePrompt,
3116
3225
  disabled: !selected || !instruction.trim() || isGeneratingPrompt,
3117
3226
  className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
3118
- children: isGeneratingPrompt ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3119
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3120
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Generiere Prompt..." })
3121
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3122
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "auto_fix_high" }),
3123
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Prompt generieren" })
3227
+ children: isGeneratingPrompt ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3228
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3229
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Generiere Prompt..." })
3230
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3231
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "auto_fix_high" }),
3232
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Prompt generieren" })
3124
3233
  ] })
3125
3234
  }
3126
3235
  ),
3127
- generatedPrompt && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3128
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Generierter Prompt" }),
3129
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3236
+ generatedPrompt && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-2", children: [
3237
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Generierter Prompt" }),
3238
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3130
3239
  "textarea",
3131
3240
  {
3132
3241
  value: generatedPrompt,
@@ -3135,37 +3244,46 @@ var LabRemix = ({ services, onResult }) => {
3135
3244
  rows: 4
3136
3245
  }
3137
3246
  ),
3138
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3247
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3248
+ GenerationControls,
3249
+ {
3250
+ aspectRatio,
3251
+ onAspectRatioChange: updateAspectRatio,
3252
+ model,
3253
+ onModelChange: updateModel,
3254
+ imageCount,
3255
+ onImageCountChange: updateImageCount,
3256
+ runningCount
3257
+ }
3258
+ ),
3259
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3139
3260
  "button",
3140
3261
  {
3141
- onClick: handleGenerateImage,
3142
- disabled: isGeneratingImage,
3143
- className: "w-full mt-2 py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-blue-600 flex items-center justify-center gap-2",
3144
- children: isGeneratingImage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3145
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3146
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Generiere Bild..." })
3147
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3148
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3149
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Bild generieren" })
3150
- ] })
3262
+ onClick: handleGenerateBatch,
3263
+ className: "w-full py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide active:bg-blue-600 flex items-center justify-center gap-2",
3264
+ children: [
3265
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3266
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Bilder generieren" })
3267
+ ]
3151
3268
  }
3152
3269
  )
3153
3270
  ] }),
3154
- resultImage && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: resultImage, className: "w-full object-cover" }) })
3271
+ resultImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `grid gap-2 ${resultImages.length > 1 ? "grid-cols-2" : "grid-cols-1"}`, children: resultImages.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src, className: "w-full object-cover" }) }, i)) })
3155
3272
  ] });
3156
3273
  };
3157
3274
 
3158
3275
  // src/components/labs/LabBlend.tsx
3159
- var import_react17 = require("react");
3160
- var import_jsx_runtime15 = require("react/jsx-runtime");
3276
+ var import_react18 = require("react");
3277
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3161
3278
  var LabBlend = ({ services, onResult }) => {
3162
- const [showPickerFor, setShowPickerFor] = (0, import_react17.useState)(null);
3163
- const [selectedImages, setSelectedImages] = (0, import_react17.useState)([]);
3164
- const [instruction, setInstruction] = (0, import_react17.useState)("");
3165
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react17.useState)("");
3166
- const [resultImage, setResultImage] = (0, import_react17.useState)(null);
3167
- const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react17.useState)(false);
3168
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react17.useState)(false);
3279
+ const [showPickerFor, setShowPickerFor] = (0, import_react18.useState)(null);
3280
+ const [selectedImages, setSelectedImages] = (0, import_react18.useState)([]);
3281
+ const [instruction, setInstruction] = (0, import_react18.useState)("");
3282
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
3283
+ const [resultImages, setResultImages] = (0, import_react18.useState)([]);
3284
+ const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react18.useState)(false);
3285
+ const [runningCount, setRunningCount] = (0, import_react18.useState)(0);
3286
+ const { aspectRatio, model, imageCount, updateAspectRatio, updateModel, updateImageCount } = useGenerationSettings();
3169
3287
  const handleSelectImage = (index, item, frame) => {
3170
3288
  services.onItemUsed(item);
3171
3289
  const newImg = {
@@ -3184,7 +3302,7 @@ var LabBlend = ({ services, onResult }) => {
3184
3302
  });
3185
3303
  setShowPickerFor(null);
3186
3304
  setGeneratedPrompt("");
3187
- setResultImage(null);
3305
+ setResultImages([]);
3188
3306
  };
3189
3307
  const addSlot = () => setSelectedImages((prev) => [...prev, null]);
3190
3308
  const removeSlot = (i) => setSelectedImages((prev) => prev.filter((_, idx) => idx !== i));
@@ -3202,35 +3320,41 @@ var LabBlend = ({ services, onResult }) => {
3202
3320
  setIsGeneratingPrompt(false);
3203
3321
  }
3204
3322
  };
3205
- const handleGenerateImage = async () => {
3323
+ const handleGenerateBatch = async () => {
3206
3324
  if (!generatedPrompt) return;
3207
- setIsGeneratingImage(true);
3208
- try {
3209
- const filled = selectedImages.filter(Boolean);
3210
- const refIds = buildReferenceImageMediaIds(filled);
3211
- const { base64, mediaId } = await services.generateImage({
3212
- prompt: generatedPrompt,
3213
- aspectRatio: "1:1",
3214
- modelDisplayName: "\u{1F34C} Nano Banana Pro",
3215
- ...refIds.length ? { referenceImageMediaIds: refIds } : {}
3216
- });
3217
- const newBase64 = `data:image/png;base64,${base64}`;
3218
- setResultImage(newBase64);
3219
- const frameId = crypto.randomUUID();
3220
- const newItem = {
3221
- id: frameId,
3222
- prompt: generatedPrompt,
3223
- tags: [],
3224
- frames: [{ id: frameId, base64: newBase64, mediaId, source: "generated" }]
3225
- };
3226
- services.saveResult?.(newItem);
3227
- onResult?.(newItem);
3228
- } finally {
3229
- setIsGeneratingImage(false);
3325
+ const count = Math.max(1, Math.min(8, imageCount));
3326
+ const filled = selectedImages.filter(Boolean);
3327
+ const refIds = buildReferenceImageMediaIds(filled);
3328
+ const options = {
3329
+ prompt: generatedPrompt,
3330
+ aspectRatio,
3331
+ modelDisplayName: model,
3332
+ ...refIds.length ? { referenceImageMediaIds: refIds } : {}
3333
+ };
3334
+ setRunningCount((c) => c + count);
3335
+ const results = await Promise.allSettled(
3336
+ Array.from({ length: count }, () => services.generateImage(options))
3337
+ );
3338
+ setRunningCount((c) => c - count);
3339
+ for (const r of results) {
3340
+ if (r.status === "fulfilled") {
3341
+ const { base64, mediaId } = r.value;
3342
+ const newBase64 = `data:image/png;base64,${base64}`;
3343
+ setResultImages((prev) => [newBase64, ...prev]);
3344
+ const frameId = crypto.randomUUID();
3345
+ const newItem = {
3346
+ id: frameId,
3347
+ prompt: generatedPrompt,
3348
+ tags: [],
3349
+ frames: [{ id: frameId, base64: newBase64, mediaId, source: "generated" }]
3350
+ };
3351
+ services.saveResult?.(newItem);
3352
+ onResult?.(newItem);
3353
+ }
3230
3354
  }
3231
3355
  };
3232
3356
  if (showPickerFor !== null) {
3233
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3357
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3234
3358
  LabImagePicker,
3235
3359
  {
3236
3360
  availableItems: services.availableItems,
@@ -3241,25 +3365,25 @@ var LabBlend = ({ services, onResult }) => {
3241
3365
  }
3242
3366
  );
3243
3367
  }
3244
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3245
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder" }),
3246
- selectedImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3247
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
3248
- img ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3249
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0", onClick: () => setShowPickerFor(i) }),
3250
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
3251
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
3252
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-3", children: [
3253
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3254
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updateImg(i, { sendToPromptAI: e.target.checked }) }),
3368
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3369
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder" }),
3370
+ selectedImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3371
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
3372
+ img ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3373
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0", onClick: () => setShowPickerFor(i) }),
3374
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
3375
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
3376
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-3", children: [
3377
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3378
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updateImg(i, { sendToPromptAI: e.target.checked }) }),
3255
3379
  "KI-Prompt"
3256
3380
  ] }),
3257
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3258
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("input", { type: "checkbox", checked: img.sendToImageGen, onChange: (e) => updateImg(i, { sendToImageGen: e.target.checked }) }),
3381
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3382
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("input", { type: "checkbox", checked: img.sendToImageGen, onChange: (e) => updateImg(i, { sendToImageGen: e.target.checked }) }),
3259
3383
  "Referenz"
3260
3384
  ] })
3261
3385
  ] }),
3262
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3386
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3263
3387
  "input",
3264
3388
  {
3265
3389
  value: img.roleForPrompt || "",
@@ -3268,7 +3392,7 @@ var LabBlend = ({ services, onResult }) => {
3268
3392
  className: "bg-black/30 border border-white/10 rounded px-2 py-0.5 text-[10px] text-white/60 outline-none"
3269
3393
  }
3270
3394
  ),
3271
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3395
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3272
3396
  "input",
3273
3397
  {
3274
3398
  value: img.roleForImage || "",
@@ -3278,23 +3402,23 @@ var LabBlend = ({ services, onResult }) => {
3278
3402
  }
3279
3403
  )
3280
3404
  ] })
3281
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: () => setShowPickerFor(i), className: "flex-1 py-3 border border-dashed border-white/20 rounded-lg text-[10px] text-white/30 active:bg-white/5", children: "Bild w\xE4hlen" }),
3282
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: () => removeSlot(i), className: "text-white/20 active:text-red-400 self-start", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "close" }) })
3405
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: () => setShowPickerFor(i), className: "flex-1 py-3 border border-dashed border-white/20 rounded-lg text-[10px] text-white/30 active:bg-white/5", children: "Bild w\xE4hlen" }),
3406
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: () => removeSlot(i), className: "text-white/20 active:text-red-400 self-start", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "close" }) })
3283
3407
  ] }, i)),
3284
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3408
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3285
3409
  "button",
3286
3410
  {
3287
3411
  onClick: addSlot,
3288
3412
  className: "w-full py-2 border border-dashed border-white/10 rounded-xl text-[10px] text-white/30 active:bg-white/5 flex items-center justify-center gap-1",
3289
3413
  children: [
3290
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
3414
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
3291
3415
  "Bild hinzuf\xFCgen"
3292
3416
  ]
3293
3417
  }
3294
3418
  ),
3295
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3296
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Blend-Anweisung" }),
3297
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3419
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
3420
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Blend-Anweisung" }),
3421
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3298
3422
  "textarea",
3299
3423
  {
3300
3424
  value: instruction,
@@ -3305,24 +3429,24 @@ var LabBlend = ({ services, onResult }) => {
3305
3429
  }
3306
3430
  )
3307
3431
  ] }),
3308
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3432
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3309
3433
  "button",
3310
3434
  {
3311
3435
  onClick: handleGeneratePrompt,
3312
3436
  disabled: selectedImages.filter(Boolean).length < 2 || !instruction.trim() || isGeneratingPrompt,
3313
3437
  className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
3314
- children: isGeneratingPrompt ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3315
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3316
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Blend l\xE4uft..." })
3317
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3318
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "merge" }),
3319
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Prompts blenden" })
3438
+ children: isGeneratingPrompt ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3439
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3440
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Blend l\xE4uft..." })
3441
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3442
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "merge" }),
3443
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Prompts blenden" })
3320
3444
  ] })
3321
3445
  }
3322
3446
  ),
3323
- generatedPrompt && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3324
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Blend-Prompt" }),
3325
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3447
+ generatedPrompt && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-2", children: [
3448
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Blend-Prompt" }),
3449
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3326
3450
  "textarea",
3327
3451
  {
3328
3452
  value: generatedPrompt,
@@ -3331,38 +3455,46 @@ var LabBlend = ({ services, onResult }) => {
3331
3455
  rows: 4
3332
3456
  }
3333
3457
  ),
3334
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3458
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3459
+ GenerationControls,
3460
+ {
3461
+ aspectRatio,
3462
+ onAspectRatioChange: updateAspectRatio,
3463
+ model,
3464
+ onModelChange: updateModel,
3465
+ imageCount,
3466
+ onImageCountChange: updateImageCount,
3467
+ runningCount
3468
+ }
3469
+ ),
3470
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3335
3471
  "button",
3336
3472
  {
3337
- onClick: handleGenerateImage,
3338
- disabled: isGeneratingImage,
3339
- className: "w-full mt-2 py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-blue-600 flex items-center justify-center gap-2",
3340
- children: isGeneratingImage ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3341
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3342
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Generiere..." })
3343
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3344
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3345
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Bild generieren" })
3346
- ] })
3473
+ onClick: handleGenerateBatch,
3474
+ className: "w-full py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide active:bg-blue-600 flex items-center justify-center gap-2",
3475
+ children: [
3476
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3477
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Bilder generieren" })
3478
+ ]
3347
3479
  }
3348
3480
  )
3349
3481
  ] }),
3350
- resultImage && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src: resultImage, className: "w-full object-cover" }) })
3482
+ resultImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: `grid gap-2 ${resultImages.length > 1 ? "grid-cols-2" : "grid-cols-1"}`, children: resultImages.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { src, className: "w-full object-cover" }) }, i)) })
3351
3483
  ] });
3352
3484
  };
3353
3485
 
3354
3486
  // src/components/labs/LabCompare.tsx
3355
- var import_react18 = require("react");
3356
- var import_jsx_runtime16 = require("react/jsx-runtime");
3487
+ var import_react19 = require("react");
3488
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3357
3489
  var LabCompare = ({ services, onResult }) => {
3358
- const [showPickerFor, setShowPickerFor] = (0, import_react18.useState)(null);
3359
- const [selectedImages, setSelectedImages] = (0, import_react18.useState)([]);
3360
- const [instruction, setInstruction] = (0, import_react18.useState)("");
3361
- const [analysis, setAnalysis] = (0, import_react18.useState)("");
3362
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
3363
- const [resultImage, setResultImage] = (0, import_react18.useState)(null);
3364
- const [isAnalyzing, setIsAnalyzing] = (0, import_react18.useState)(false);
3365
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
3490
+ const [showPickerFor, setShowPickerFor] = (0, import_react19.useState)(null);
3491
+ const [selectedImages, setSelectedImages] = (0, import_react19.useState)([]);
3492
+ const [instruction, setInstruction] = (0, import_react19.useState)("");
3493
+ const [analysis, setAnalysis] = (0, import_react19.useState)("");
3494
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react19.useState)("");
3495
+ const [resultImage, setResultImage] = (0, import_react19.useState)(null);
3496
+ const [isAnalyzing, setIsAnalyzing] = (0, import_react19.useState)(false);
3497
+ const [isGeneratingImage, setIsGeneratingImage] = (0, import_react19.useState)(false);
3366
3498
  const handleSelectImage = (index, item, frame) => {
3367
3499
  services.onItemUsed(item);
3368
3500
  const newImg = {
@@ -3420,7 +3552,7 @@ var LabCompare = ({ services, onResult }) => {
3420
3552
  }
3421
3553
  };
3422
3554
  if (showPickerFor !== null) {
3423
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3555
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3424
3556
  LabImagePicker,
3425
3557
  {
3426
3558
  availableItems: services.availableItems,
@@ -3431,19 +3563,19 @@ var LabCompare = ({ services, onResult }) => {
3431
3563
  }
3432
3564
  );
3433
3565
  }
3434
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3435
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder zum Vergleichen" }),
3436
- selectedImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3437
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
3438
- img ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3439
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0 cursor-pointer", onClick: () => setShowPickerFor(i) }),
3440
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
3441
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
3442
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3443
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updateImg(i, { sendToPromptAI: e.target.checked }) }),
3566
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3567
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder zum Vergleichen" }),
3568
+ selectedImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3569
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
3570
+ img ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3571
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0 cursor-pointer", onClick: () => setShowPickerFor(i) }),
3572
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
3573
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
3574
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-1 text-[10px] text-white/40", children: [
3575
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updateImg(i, { sendToPromptAI: e.target.checked }) }),
3444
3576
  "Bild an KI mitgeben"
3445
3577
  ] }),
3446
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3578
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3447
3579
  "input",
3448
3580
  {
3449
3581
  value: img.roleForPrompt || "",
@@ -3453,16 +3585,16 @@ var LabCompare = ({ services, onResult }) => {
3453
3585
  }
3454
3586
  )
3455
3587
  ] })
3456
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: () => setShowPickerFor(i), className: "flex-1 py-3 border border-dashed border-white/20 rounded-lg text-[10px] text-white/30 active:bg-white/5", children: "Bild w\xE4hlen" }),
3457
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: () => removeSlot(i), className: "text-white/20 active:text-red-400 self-start", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "close" }) })
3588
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { onClick: () => setShowPickerFor(i), className: "flex-1 py-3 border border-dashed border-white/20 rounded-lg text-[10px] text-white/30 active:bg-white/5", children: "Bild w\xE4hlen" }),
3589
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { onClick: () => removeSlot(i), className: "text-white/20 active:text-red-400 self-start", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "close" }) })
3458
3590
  ] }, i)),
3459
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("button", { onClick: addSlot, className: "w-full py-2 border border-dashed border-white/10 rounded-xl text-[10px] text-white/30 active:bg-white/5 flex items-center justify-center gap-1", children: [
3460
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
3591
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { onClick: addSlot, className: "w-full py-2 border border-dashed border-white/10 rounded-xl text-[10px] text-white/30 active:bg-white/5 flex items-center justify-center gap-1", children: [
3592
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
3461
3593
  "Bild hinzuf\xFCgen"
3462
3594
  ] }),
3463
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
3464
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Analyse-Anweisung" }),
3465
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3595
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3596
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Analyse-Anweisung" }),
3597
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3466
3598
  "textarea",
3467
3599
  {
3468
3600
  value: instruction,
@@ -3473,27 +3605,27 @@ var LabCompare = ({ services, onResult }) => {
3473
3605
  }
3474
3606
  )
3475
3607
  ] }),
3476
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3608
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3477
3609
  "button",
3478
3610
  {
3479
3611
  onClick: handleAnalyze,
3480
3612
  disabled: selectedImages.filter(Boolean).length < 1 || !instruction.trim() || isAnalyzing,
3481
3613
  className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
3482
- children: isAnalyzing ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3483
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3484
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Analysiere..." })
3485
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3486
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "compare" }),
3487
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Analysieren" })
3614
+ children: isAnalyzing ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3615
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3616
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Analysiere..." })
3617
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3618
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "compare" }),
3619
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Analysieren" })
3488
3620
  ] })
3489
3621
  }
3490
3622
  ),
3491
- analysis && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
3492
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Analyse" }),
3493
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "bg-white/5 border border-white/10 rounded-xl px-3 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[12px] text-white/70 leading-relaxed whitespace-pre-wrap", children: analysis }) }),
3494
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "mt-3", children: [
3495
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Als Prompt nutzen" }),
3496
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3623
+ analysis && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3624
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Analyse" }),
3625
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "bg-white/5 border border-white/10 rounded-xl px-3 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[12px] text-white/70 leading-relaxed whitespace-pre-wrap", children: analysis }) }),
3626
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "mt-3", children: [
3627
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40 mb-2", children: "Als Prompt nutzen" }),
3628
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3497
3629
  "textarea",
3498
3630
  {
3499
3631
  value: generatedPrompt,
@@ -3503,36 +3635,37 @@ var LabCompare = ({ services, onResult }) => {
3503
3635
  rows: 3
3504
3636
  }
3505
3637
  ),
3506
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3638
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3507
3639
  "button",
3508
3640
  {
3509
3641
  onClick: handleGenerateImage,
3510
3642
  disabled: !generatedPrompt.trim() || isGeneratingImage,
3511
3643
  className: "w-full mt-2 py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-blue-600 flex items-center justify-center gap-2",
3512
- children: isGeneratingImage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3513
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3514
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Generiere..." })
3515
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3516
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3517
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Bild generieren" })
3644
+ children: isGeneratingImage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3645
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3646
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Generiere..." })
3647
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3648
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
3649
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Bild generieren" })
3518
3650
  ] })
3519
3651
  }
3520
3652
  )
3521
3653
  ] })
3522
3654
  ] }),
3523
- resultImage && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { src: resultImage, className: "w-full object-cover" }) })
3655
+ resultImage && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "rounded-xl overflow-hidden border border-white/10", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { src: resultImage, className: "w-full object-cover" }) })
3524
3656
  ] });
3525
3657
  };
3526
3658
 
3527
3659
  // src/components/labs/LabLoop.tsx
3528
- var import_react19 = require("react");
3529
- var import_jsx_runtime17 = require("react/jsx-runtime");
3660
+ var import_react20 = require("react");
3661
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3530
3662
  var LabLoop = ({ services, onResult }) => {
3531
- const [rounds, setRounds] = (0, import_react19.useState)([]);
3532
- const [currentInstruction, setCurrentInstruction] = (0, import_react19.useState)("");
3533
- const [showPickerForRound, setShowPickerForRound] = (0, import_react19.useState)(null);
3534
- const [pendingImages, setPendingImages] = (0, import_react19.useState)([]);
3535
- const [isGenerating, setIsGenerating] = (0, import_react19.useState)(false);
3663
+ const [rounds, setRounds] = (0, import_react20.useState)([]);
3664
+ const [currentInstruction, setCurrentInstruction] = (0, import_react20.useState)("");
3665
+ const [showPickerForRound, setShowPickerForRound] = (0, import_react20.useState)(null);
3666
+ const [pendingImages, setPendingImages] = (0, import_react20.useState)([]);
3667
+ const [isGenerating, setIsGenerating] = (0, import_react20.useState)(false);
3668
+ const { aspectRatio, model, updateAspectRatio, updateModel } = useGenerationSettings();
3536
3669
  const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
3537
3670
  const handleAddImage = (item, frame) => {
3538
3671
  services.onItemUsed(item);
@@ -3566,8 +3699,8 @@ var LabLoop = ({ services, onResult }) => {
3566
3699
  });
3567
3700
  const { base64, mediaId } = await services.generateImage({
3568
3701
  prompt: newPrompt,
3569
- aspectRatio: "1:1",
3570
- modelDisplayName: "\u{1F34C} Nano Banana Pro"
3702
+ aspectRatio,
3703
+ modelDisplayName: model
3571
3704
  });
3572
3705
  const newBase64 = `data:image/png;base64,${base64}`;
3573
3706
  const newFrame = { id: crypto.randomUUID(), base64: newBase64, mediaId, source: "generated" };
@@ -3593,7 +3726,7 @@ var LabLoop = ({ services, onResult }) => {
3593
3726
  }
3594
3727
  };
3595
3728
  if (showPickerForRound !== null) {
3596
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3729
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3597
3730
  LabImagePicker,
3598
3731
  {
3599
3732
  availableItems: services.availableItems,
@@ -3604,32 +3737,32 @@ var LabLoop = ({ services, onResult }) => {
3604
3737
  }
3605
3738
  );
3606
3739
  }
3607
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3608
- rounds.map((round, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3609
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center gap-1 shrink-0", children: [
3610
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-[9px] font-bold text-white/30", children: [
3740
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-3 p-4 overflow-y-auto dark-scrollbar", children: [
3741
+ rounds.map((round, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
3742
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col items-center gap-1 shrink-0", children: [
3743
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-[9px] font-bold text-white/30", children: [
3611
3744
  "R",
3612
3745
  i + 1
3613
3746
  ] }),
3614
- round.frame && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { src: round.frame.base64, className: "w-12 h-12 object-cover rounded-lg" })
3747
+ round.frame && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { src: round.frame.base64, className: "w-12 h-12 object-cover rounded-lg" })
3615
3748
  ] }),
3616
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex-1 min-w-0", children: [
3617
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { className: "text-[9px] text-white/30 italic mb-1", children: [
3749
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 min-w-0", children: [
3750
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "text-[9px] text-white/30 italic mb-1", children: [
3618
3751
  '"',
3619
3752
  round.instruction,
3620
3753
  '"'
3621
3754
  ] }),
3622
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[10px] text-white/60 leading-tight line-clamp-3", children: round.prompt })
3755
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[10px] text-white/60 leading-tight line-clamp-3", children: round.prompt })
3623
3756
  ] })
3624
3757
  ] }, i)),
3625
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "rounded-xl border border-white/20 bg-white/5 p-3 flex flex-col gap-3", children: [
3626
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: rounds.length === 0 ? "Runde 1 \u2014 Erster Prompt" : `Runde ${rounds.length + 1}` }),
3627
- currentPrompt && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { className: "text-[10px] text-white/40 italic line-clamp-2", children: [
3758
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "rounded-xl border border-white/20 bg-white/5 p-3 flex flex-col gap-3", children: [
3759
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: rounds.length === 0 ? "Runde 1 \u2014 Erster Prompt" : `Runde ${rounds.length + 1}` }),
3760
+ currentPrompt && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "text-[10px] text-white/40 italic line-clamp-2", children: [
3628
3761
  'Letzter Prompt: "',
3629
3762
  currentPrompt,
3630
3763
  '"'
3631
3764
  ] }),
3632
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3765
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3633
3766
  "textarea",
3634
3767
  {
3635
3768
  value: currentInstruction,
@@ -3639,10 +3772,10 @@ var LabLoop = ({ services, onResult }) => {
3639
3772
  rows: 3
3640
3773
  }
3641
3774
  ),
3642
- pendingImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-2 items-center", children: [
3643
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { src: img.frame.base64, className: "w-8 h-8 object-cover rounded" }),
3644
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-white/40", children: img.label }),
3645
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3775
+ pendingImages.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-2 items-center", children: [
3776
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { src: img.frame.base64, className: "w-8 h-8 object-cover rounded" }),
3777
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-[10px] text-white/40", children: img.label }),
3778
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3646
3779
  "input",
3647
3780
  {
3648
3781
  value: img.roleForPrompt || "",
@@ -3651,36 +3784,43 @@ var LabLoop = ({ services, onResult }) => {
3651
3784
  className: "flex-1 bg-black/30 border border-white/10 rounded px-2 py-0.5 text-[10px] text-white/60 outline-none"
3652
3785
  }
3653
3786
  ),
3654
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-1 text-[9px] text-white/30", children: [
3655
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updatePendingImage(i, { sendToPromptAI: e.target.checked }) }),
3787
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "flex items-center gap-1 text-[9px] text-white/30", children: [
3788
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("input", { type: "checkbox", checked: img.sendToPromptAI, onChange: (e) => updatePendingImage(i, { sendToPromptAI: e.target.checked }) }),
3656
3789
  "KI"
3657
3790
  ] }),
3658
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { onClick: () => setPendingImages((prev) => prev.filter((_, idx) => idx !== i)), className: "text-white/20 active:text-red-400", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
3791
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: () => setPendingImages((prev) => prev.filter((_, idx) => idx !== i)), className: "text-white/20 active:text-red-400", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
3659
3792
  ] }, i)),
3660
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3793
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3661
3794
  "button",
3662
3795
  {
3663
3796
  onClick: () => setShowPickerForRound(rounds.length),
3664
3797
  className: "text-[10px] text-white/30 active:text-white/60 flex items-center gap-1 self-start",
3665
3798
  children: [
3666
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
3799
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
3667
3800
  "Referenzbild hinzuf\xFCgen"
3668
3801
  ]
3669
3802
  }
3670
3803
  ),
3671
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3804
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3805
+ GenerationControls,
3806
+ {
3807
+ aspectRatio,
3808
+ onAspectRatioChange: updateAspectRatio,
3809
+ model,
3810
+ onModelChange: updateModel,
3811
+ runningCount: isGenerating ? 1 : 0
3812
+ }
3813
+ ),
3814
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3672
3815
  "button",
3673
3816
  {
3674
3817
  onClick: handleRunRound,
3675
- disabled: !currentInstruction.trim() || isGenerating,
3818
+ disabled: !currentInstruction.trim(),
3676
3819
  className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
3677
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3678
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
3679
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Runde l\xE4uft..." })
3680
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3681
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "loop" }),
3682
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: "Runde starten" })
3683
- ] })
3820
+ children: [
3821
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "loop" }),
3822
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Runde starten" })
3823
+ ]
3684
3824
  }
3685
3825
  )
3686
3826
  ] })
@@ -3688,8 +3828,8 @@ var LabLoop = ({ services, onResult }) => {
3688
3828
  };
3689
3829
 
3690
3830
  // src/components/labs/LabFrameExtractor.tsx
3691
- var import_react20 = require("react");
3692
- var import_jsx_runtime18 = require("react/jsx-runtime");
3831
+ var import_react21 = require("react");
3832
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3693
3833
  var formatTime = (s) => {
3694
3834
  const m = Math.floor(s / 60);
3695
3835
  const sec = (s % 60).toFixed(1);
@@ -3702,15 +3842,15 @@ var LabFrameExtractor = ({
3702
3842
  onResult,
3703
3843
  resolveVideoUrl
3704
3844
  }) => {
3705
- const videoRef = (0, import_react20.useRef)(null);
3706
- const canvasRef = (0, import_react20.useRef)(null);
3707
- const cancelledRef = (0, import_react20.useRef)(false);
3708
- const [selectedItem, setSelectedItem] = (0, import_react20.useState)(null);
3709
- const [videoSrc, setVideoSrc] = (0, import_react20.useState)(null);
3710
- const [videoReady, setVideoReady] = (0, import_react20.useState)(false);
3711
- const [frames, setFrames] = (0, import_react20.useState)([]);
3712
- const [isExtracting, setIsExtracting] = (0, import_react20.useState)(false);
3713
- const [intervalSec, setIntervalSec] = (0, import_react20.useState)("1");
3845
+ const videoRef = (0, import_react21.useRef)(null);
3846
+ const canvasRef = (0, import_react21.useRef)(null);
3847
+ const cancelledRef = (0, import_react21.useRef)(false);
3848
+ const [selectedItem, setSelectedItem] = (0, import_react21.useState)(null);
3849
+ const [videoSrc, setVideoSrc] = (0, import_react21.useState)(null);
3850
+ const [videoReady, setVideoReady] = (0, import_react21.useState)(false);
3851
+ const [frames, setFrames] = (0, import_react21.useState)([]);
3852
+ const [isExtracting, setIsExtracting] = (0, import_react21.useState)(false);
3853
+ const [intervalSec, setIntervalSec] = (0, import_react21.useState)("1");
3714
3854
  const handleVideoSelect = (item) => {
3715
3855
  const mediaId = item.frames[0]?.mediaId;
3716
3856
  if (!mediaId) return;
@@ -3720,7 +3860,7 @@ var LabFrameExtractor = ({
3720
3860
  setVideoReady(false);
3721
3861
  cancelledRef.current = false;
3722
3862
  };
3723
- const captureAt = (0, import_react20.useCallback)(
3863
+ const captureAt = (0, import_react21.useCallback)(
3724
3864
  (t, label) => new Promise((resolve) => {
3725
3865
  const video = videoRef.current;
3726
3866
  const canvas = canvasRef.current;
@@ -3790,10 +3930,10 @@ var LabFrameExtractor = ({
3790
3930
  frames: [labFrame]
3791
3931
  });
3792
3932
  };
3793
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 12, padding: 12, height: "100%", overflow: "auto" }, children: [
3794
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
3795
- videoItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: 11, color: "#666", fontStyle: "italic" }, children: "No video items available" }),
3796
- videoItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3933
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 12, padding: 12, height: "100%", overflow: "auto" }, children: [
3934
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
3935
+ videoItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { fontSize: 11, color: "#666", fontStyle: "italic" }, children: "No video items available" }),
3936
+ videoItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3797
3937
  "button",
3798
3938
  {
3799
3939
  onClick: () => handleVideoSelect(item),
@@ -3811,7 +3951,7 @@ var LabFrameExtractor = ({
3811
3951
  item.id
3812
3952
  ))
3813
3953
  ] }),
3814
- videoSrc && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3954
+ videoSrc && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3815
3955
  "video",
3816
3956
  {
3817
3957
  ref: videoRef,
@@ -3822,9 +3962,9 @@ var LabFrameExtractor = ({
3822
3962
  style: { width: "100%", maxHeight: 280, background: "#000", borderRadius: 6, display: "block" }
3823
3963
  }
3824
3964
  ),
3825
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
3826
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center" }, children: [
3827
- ["start", "current", "end"].map((mode) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3965
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
3966
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center" }, children: [
3967
+ ["start", "current", "end"].map((mode) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3828
3968
  "button",
3829
3969
  {
3830
3970
  disabled: !videoReady,
@@ -3843,21 +3983,21 @@ var LabFrameExtractor = ({
3843
3983
  },
3844
3984
  mode
3845
3985
  )),
3846
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: 11, color: "#aaa" }, children: "every" }),
3847
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3986
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { fontSize: 11, color: "#aaa" }, children: "every" }),
3987
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3848
3988
  "select",
3849
3989
  {
3850
3990
  value: intervalSec,
3851
3991
  onChange: (e) => setIntervalSec(e.target.value),
3852
3992
  disabled: !videoReady || isExtracting,
3853
3993
  style: { fontSize: 11, background: "#111", border: "1px solid #333", color: "#fff", borderRadius: 4, padding: "2px 4px" },
3854
- children: INTERVAL_OPTIONS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("option", { value: v, children: [
3994
+ children: INTERVAL_OPTIONS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("option", { value: v, children: [
3855
3995
  v,
3856
3996
  "s"
3857
3997
  ] }, v))
3858
3998
  }
3859
3999
  ),
3860
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4000
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3861
4001
  "button",
3862
4002
  {
3863
4003
  disabled: !videoReady,
@@ -3878,8 +4018,8 @@ var LabFrameExtractor = ({
3878
4018
  }
3879
4019
  )
3880
4020
  ] }),
3881
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 8, overflowX: "auto", paddingBottom: 4 }, children: [
3882
- frames.map((frame) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4021
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 8, overflowX: "auto", paddingBottom: 4 }, children: [
4022
+ frames.map((frame) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3883
4023
  "div",
3884
4024
  {
3885
4025
  style: {
@@ -3891,10 +4031,10 @@ var LabFrameExtractor = ({
3891
4031
  background: "rgba(255,255,255,0.03)"
3892
4032
  },
3893
4033
  children: [
3894
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { src: frame.dataUrl, style: { width: "100%", aspectRatio: "16/9", objectFit: "cover", display: "block" }, alt: frame.label }),
3895
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 9, color: "#888", textAlign: "center", padding: "2px 4px", fontFamily: "monospace" }, children: frame.label }),
3896
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: 2, padding: "0 4px 4px", justifyContent: "center" }, children: [
3897
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4034
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("img", { src: frame.dataUrl, style: { width: "100%", aspectRatio: "16/9", objectFit: "cover", display: "block" }, alt: frame.label }),
4035
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontSize: 9, color: "#888", textAlign: "center", padding: "2px 4px", fontFamily: "monospace" }, children: frame.label }),
4036
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 2, padding: "0 4px 4px", justifyContent: "center" }, children: [
4037
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3898
4038
  "button",
3899
4039
  {
3900
4040
  onClick: () => useFrame(frame),
@@ -3911,7 +4051,7 @@ var LabFrameExtractor = ({
3911
4051
  children: "Use"
3912
4052
  }
3913
4053
  ),
3914
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4054
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3915
4055
  "button",
3916
4056
  {
3917
4057
  onClick: () => setFrames((prev) => prev.filter((f) => f.id !== frame.id)),
@@ -3932,13 +4072,13 @@ var LabFrameExtractor = ({
3932
4072
  },
3933
4073
  frame.id
3934
4074
  )),
3935
- 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" })
4075
+ frames.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { fontSize: 11, color: "#444", fontStyle: "italic", padding: "16px 0" }, children: isExtracting ? "Extracting frames\u2026" : "No frames yet" })
3936
4076
  ] })
3937
4077
  ] });
3938
4078
  };
3939
4079
 
3940
4080
  // src/components/labs/LabsTab.tsx
3941
- var import_jsx_runtime19 = require("react/jsx-runtime");
4081
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3942
4082
  var BASE_TABS = [
3943
4083
  { key: "remix", label: "Remix", icon: "auto_fix_high" },
3944
4084
  { key: "blend", label: "Blend", icon: "merge" },
@@ -3947,28 +4087,28 @@ var BASE_TABS = [
3947
4087
  ];
3948
4088
  var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
3949
4089
  var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
3950
- const [activeTab, setActiveTab] = (0, import_react21.useState)("remix");
4090
+ const [activeTab, setActiveTab] = (0, import_react22.useState)("remix");
3951
4091
  const showFrames = !!(videoItems && resolveVideoUrl);
3952
4092
  const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
3953
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
3954
- /* @__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)(
4093
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
4094
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex border-b border-white/5 shrink-0", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3955
4095
  "button",
3956
4096
  {
3957
4097
  onClick: () => setActiveTab(tab.key),
3958
4098
  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"}`,
3959
4099
  children: [
3960
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: tab.icon }),
4100
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: tab.icon }),
3961
4101
  tab.label
3962
4102
  ]
3963
4103
  },
3964
4104
  tab.key
3965
4105
  )) }),
3966
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 overflow-hidden", children: [
3967
- activeTab === "remix" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabRemix, { services, onResult }),
3968
- activeTab === "blend" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabBlend, { services, onResult }),
3969
- activeTab === "compare" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabCompare, { services, onResult }),
3970
- activeTab === "loop" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LabLoop, { services, onResult }),
3971
- activeTab === "frames" && showFrames && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4106
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-hidden", children: [
4107
+ activeTab === "remix" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabRemix, { services, onResult }),
4108
+ activeTab === "blend" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabBlend, { services, onResult }),
4109
+ activeTab === "compare" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabCompare, { services, onResult }),
4110
+ activeTab === "loop" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabLoop, { services, onResult }),
4111
+ activeTab === "frames" && showFrames && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3972
4112
  LabFrameExtractor,
3973
4113
  {
3974
4114
  videoItems,
@@ -3981,19 +4121,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
3981
4121
  };
3982
4122
 
3983
4123
  // src/components/TagManagerPanel.tsx
3984
- var import_react22 = require("react");
3985
- var import_jsx_runtime20 = require("react/jsx-runtime");
4124
+ var import_react23 = require("react");
4125
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3986
4126
  function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
3987
4127
  const categories = Object.keys(workspaceTags.by_category).filter(
3988
4128
  (cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
3989
4129
  );
3990
- const [selectedCategory, setSelectedCategory] = (0, import_react22.useState)(categories[0] || "");
4130
+ const [selectedCategory, setSelectedCategory] = (0, import_react23.useState)(categories[0] || "");
3991
4131
  const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
3992
- const [editingLabel, setEditingLabel] = (0, import_react22.useState)(null);
3993
- const [editState, setEditState] = (0, import_react22.useState)({ label: "", value: "" });
3994
- const [newTag, setNewTag] = (0, import_react22.useState)({ label: "", value: "" });
3995
- const [movingLabel, setMovingLabel] = (0, import_react22.useState)(null);
3996
- const [moveTarget, setMoveTarget] = (0, import_react22.useState)("");
4132
+ const [editingLabel, setEditingLabel] = (0, import_react23.useState)(null);
4133
+ const [editState, setEditState] = (0, import_react23.useState)({ label: "", value: "" });
4134
+ const [newTag, setNewTag] = (0, import_react23.useState)({ label: "", value: "" });
4135
+ const [movingLabel, setMovingLabel] = (0, import_react23.useState)(null);
4136
+ const [moveTarget, setMoveTarget] = (0, import_react23.useState)("");
3997
4137
  const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
3998
4138
  const otherCategories = categories.filter((c) => c !== effectiveCategory);
3999
4139
  const startEdit = (tag) => {
@@ -4036,10 +4176,10 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4036
4176
  if (!confirm(`Tag "${tag.label}" l\xF6schen?`)) return;
4037
4177
  onTagDelete(tag.label, effectiveCategory);
4038
4178
  };
4039
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
4040
- /* @__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" }) }),
4041
- /* @__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: [
4042
- categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4179
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
4180
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 py-2 border-b border-white/5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-white/40", children: "Tag Manager" }) }),
4181
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 py-2 shrink-0 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-1.5 flex-nowrap", children: [
4182
+ categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4043
4183
  "button",
4044
4184
  {
4045
4185
  onClick: () => {
@@ -4051,17 +4191,17 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4051
4191
  children: [
4052
4192
  cat,
4053
4193
  " ",
4054
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ml-1 opacity-50", children: (workspaceTags.by_category[cat] || []).filter((t) => !t.is_deleted).length })
4194
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ml-1 opacity-50", children: (workspaceTags.by_category[cat] || []).filter((t) => !t.is_deleted).length })
4055
4195
  ]
4056
4196
  },
4057
4197
  cat
4058
4198
  )),
4059
- categories.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/20", children: "Erst Workspace importieren" })
4199
+ categories.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/20", children: "Erst Workspace importieren" })
4060
4200
  ] }) }),
4061
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-y-auto dark-scrollbar px-3 pb-2 space-y-1", children: [
4062
- tags.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
4063
- 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: [
4064
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4201
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-y-auto dark-scrollbar px-3 pb-2 space-y-1", children: [
4202
+ tags.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
4203
+ editingLabel === tag.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-white/5 border border-blue-600/40 rounded-lg p-2.5 space-y-1.5", children: [
4204
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4065
4205
  "input",
4066
4206
  {
4067
4207
  value: editState.label,
@@ -4072,7 +4212,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4072
4212
  onKeyDown: (e) => e.key === "Enter" && saveEdit(tag.label)
4073
4213
  }
4074
4214
  ),
4075
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4215
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4076
4216
  "textarea",
4077
4217
  {
4078
4218
  value: editState.value,
@@ -4082,24 +4222,24 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4082
4222
  placeholder: "Prompt-Wert (leer = Label)"
4083
4223
  }
4084
4224
  ),
4085
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4086
- /* @__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" }),
4087
- /* @__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" })
4225
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4226
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }),
4227
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" })
4088
4228
  ] })
4089
- ] }) : /* @__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: [
4090
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-0 shrink-0", children: [
4091
- /* @__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" }) }),
4092
- /* @__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" }) })
4229
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.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: [
4230
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col gap-0 shrink-0", children: [
4231
+ /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_up" }) }),
4232
+ /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "arrow_drop_down" }) })
4093
4233
  ] }),
4094
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 min-w-0", children: [
4095
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "text-[12px] text-white/80 font-medium truncate", children: tag.label }),
4096
- tag.value && tag.value !== tag.label && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-[10px] text-white/30 truncate", children: [
4234
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 min-w-0", children: [
4235
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-[12px] text-white/80 font-medium truncate", children: tag.label }),
4236
+ tag.value && tag.value !== tag.label && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-[10px] text-white/30 truncate", children: [
4097
4237
  tag.value.slice(0, 60),
4098
4238
  tag.value.length > 60 ? "\u2026" : ""
4099
4239
  ] })
4100
4240
  ] }),
4101
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition shrink-0", children: [
4102
- otherCategories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4241
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition shrink-0", children: [
4242
+ otherCategories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4103
4243
  "button",
4104
4244
  {
4105
4245
  onClick: () => {
@@ -4109,29 +4249,29 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4109
4249
  },
4110
4250
  className: "p-1 rounded text-white/30 hover:text-purple-400 transition",
4111
4251
  title: "Kategorie wechseln",
4112
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "drive_file_move" })
4252
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "drive_file_move" })
4113
4253
  }
4114
4254
  ),
4115
- /* @__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" }) }),
4116
- /* @__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" }) })
4255
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => startEdit(tag), className: "p-1 rounded text-white/30 hover:text-blue-400 transition", title: "Bearbeiten", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "edit" }) }),
4256
+ /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined text-[16px]", children: "delete" }) })
4117
4257
  ] })
4118
4258
  ] }),
4119
- 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: [
4120
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-purple-400/70", children: "Verschieben nach Kategorie" }),
4121
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4259
+ movingLabel === tag.label && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-1 bg-purple-900/20 border border-purple-700/30 rounded-lg p-2.5 space-y-1.5", children: [
4260
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-purple-400/70", children: "Verschieben nach Kategorie" }),
4261
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4122
4262
  "select",
4123
4263
  {
4124
4264
  value: moveTarget,
4125
4265
  onChange: (e) => setMoveTarget(e.target.value),
4126
4266
  className: "w-full bg-black/40 border border-white/10 rounded px-2 py-1 text-[11px] text-white/70 outline-none",
4127
4267
  children: [
4128
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { value: "", children: "\u2014 Kategorie w\xE4hlen \u2014" }),
4129
- otherCategories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { value: cat, children: cat }, cat))
4268
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: "", children: "\u2014 Kategorie w\xE4hlen \u2014" }),
4269
+ otherCategories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: cat, children: cat }, cat))
4130
4270
  ]
4131
4271
  }
4132
4272
  ),
4133
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4134
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4273
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-1.5 justify-end", children: [
4274
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4135
4275
  "button",
4136
4276
  {
4137
4277
  onClick: () => handleMove(tag),
@@ -4140,19 +4280,19 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4140
4280
  children: "VERSCHIEBEN"
4141
4281
  }
4142
4282
  ),
4143
- /* @__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" })
4283
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" })
4144
4284
  ] })
4145
4285
  ] })
4146
4286
  ] }, `${effectiveCategory}-${i}`)),
4147
- 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." })
4287
+ tags.length === 0 && effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-center text-[11px] text-white/20 py-6", children: "Keine Tags in dieser Kategorie." })
4148
4288
  ] }),
4149
- 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: [
4150
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30", children: [
4289
+ effectiveCategory && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "px-3 py-2 border-t border-white/5 shrink-0 space-y-1.5", children: [
4290
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30", children: [
4151
4291
  "Neuer Tag in \u201E",
4152
4292
  effectiveCategory,
4153
4293
  '"'
4154
4294
  ] }),
4155
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4295
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4156
4296
  "input",
4157
4297
  {
4158
4298
  value: newTag.label,
@@ -4162,7 +4302,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4162
4302
  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"
4163
4303
  }
4164
4304
  ),
4165
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4305
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4166
4306
  "textarea",
4167
4307
  {
4168
4308
  value: newTag.value,
@@ -4172,14 +4312,14 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4172
4312
  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"
4173
4313
  }
4174
4314
  ),
4175
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4315
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4176
4316
  "button",
4177
4317
  {
4178
4318
  onClick: handleCreate,
4179
4319
  disabled: !newTag.label.trim(),
4180
4320
  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",
4181
4321
  children: [
4182
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
4322
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add" }),
4183
4323
  "TAG ERSTELLEN"
4184
4324
  ]
4185
4325
  }
@@ -4189,8 +4329,8 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4189
4329
  }
4190
4330
 
4191
4331
  // src/components/HFTestTab.tsx
4192
- var import_react23 = require("react");
4193
- var import_jsx_runtime21 = require("react/jsx-runtime");
4332
+ var import_react24 = require("react");
4333
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4194
4334
  var HF_BASE2 = "https://huggingface.co";
4195
4335
  var HF_REPO2 = "RolandSch/fa-app-state";
4196
4336
  var TEST_DIR = "test";
@@ -4382,8 +4522,8 @@ function tryFmt(s) {
4382
4522
  }
4383
4523
  }
4384
4524
  function CopyBtn({ text }) {
4385
- const [done, setDone] = (0, import_react23.useState)(false);
4386
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4525
+ const [done, setDone] = (0, import_react24.useState)(false);
4526
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4387
4527
  "button",
4388
4528
  {
4389
4529
  onClick: () => {
@@ -4394,7 +4534,7 @@ function CopyBtn({ text }) {
4394
4534
  },
4395
4535
  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 },
4396
4536
  children: [
4397
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
4537
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
4398
4538
  done ? "Kopiert" : "Copy"
4399
4539
  ]
4400
4540
  }
@@ -4402,35 +4542,35 @@ function CopyBtn({ text }) {
4402
4542
  }
4403
4543
  function StepView({ step }) {
4404
4544
  const isSpecial = step.method === "-" || step.method === "import()" || step.method === "import()+call";
4405
- 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: [
4406
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
4407
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
4408
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
4409
- step.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4545
+ return /* @__PURE__ */ (0, import_jsx_runtime22.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: [
4546
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
4547
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
4548
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
4549
+ step.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4410
4550
  step.durationMs,
4411
4551
  "ms"
4412
4552
  ] }),
4413
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyBtn, { text: JSON.stringify(step, null, 2) })
4553
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopyBtn, { text: JSON.stringify(step, null, 2) })
4414
4554
  ] }),
4415
- !isSpecial && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 5 }, children: [
4416
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
4555
+ !isSpecial && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: 5 }, children: [
4556
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
4417
4557
  "\u2192 ",
4418
4558
  step.method,
4419
4559
  " ",
4420
4560
  step.url
4421
4561
  ] }),
4422
- 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") }),
4423
- 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 })
4562
+ Object.keys(step.reqHeaders).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.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") }),
4563
+ step.reqBody && /* @__PURE__ */ (0, import_jsx_runtime22.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 })
4424
4564
  ] }),
4425
- 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 }),
4426
- !step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
4427
- 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: [
4565
+ step.error && /* @__PURE__ */ (0, import_jsx_runtime22.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 }),
4566
+ !step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
4567
+ step.resStatus !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 11, fontWeight: 700, color: (step.resStatus || 0) < 300 ? "#4ade80" : "#f87171", marginBottom: 3 }, children: [
4428
4568
  "\u2190 ",
4429
4569
  step.resStatus,
4430
4570
  " ",
4431
4571
  step.resStatusText
4432
4572
  ] }),
4433
- 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) })
4573
+ step.resBody && /* @__PURE__ */ (0, import_jsx_runtime22.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) })
4434
4574
  ] })
4435
4575
  ] });
4436
4576
  }
@@ -4446,15 +4586,15 @@ function TestCard({
4446
4586
  onToggle
4447
4587
  }) {
4448
4588
  const hasResult = state && state.status !== "idle";
4449
- 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: [
4450
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
4451
- /* @__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 }),
4452
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4453
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
4454
- /* @__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 })
4589
+ return /* @__PURE__ */ (0, import_jsx_runtime22.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: [
4590
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
4591
+ /* @__PURE__ */ (0, import_jsx_runtime22.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 }),
4592
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4593
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
4594
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: desc })
4455
4595
  ] }),
4456
- 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" }) }),
4457
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4596
+ hasResult && state?.status !== "running" && /* @__PURE__ */ (0, import_jsx_runtime22.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_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: expanded ? "expand_less" : "expand_more" }) }),
4597
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4458
4598
  "button",
4459
4599
  {
4460
4600
  onClick: onRun,
@@ -4464,20 +4604,20 @@ function TestCard({
4464
4604
  }
4465
4605
  )
4466
4606
  ] }),
4467
- hasResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
4468
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
4469
- /* @__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" }),
4470
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4607
+ hasResult && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
4608
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
4609
+ /* @__PURE__ */ (0, import_jsx_runtime22.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" }),
4610
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4471
4611
  state.totalMs,
4472
4612
  "ms \xB7 ",
4473
4613
  state.steps.length,
4474
4614
  " Step",
4475
4615
  state.steps.length !== 1 ? "s" : ""
4476
4616
  ] }),
4477
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
4478
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyBtn, { text: JSON.stringify(state, null, 2) })
4617
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1 } }),
4618
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopyBtn, { text: JSON.stringify(state, null, 2) })
4479
4619
  ] }),
4480
- 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))
4620
+ expanded && state.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { padding: "0 10px 4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StepView, { step }) }, i))
4481
4621
  ] })
4482
4622
  ] });
4483
4623
  }
@@ -4489,10 +4629,10 @@ var EVENT_TYPE_COLORS = {
4489
4629
  };
4490
4630
  function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadStatus }) {
4491
4631
  if (!events.length) {
4492
- 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." });
4632
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { padding: "12px 14px", fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Events geladen." });
4493
4633
  }
4494
4634
  const sorted = [...events].sort((a, b) => b.ts - a.ts).slice(0, 30);
4495
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "6px 8px 4px" }, children: [
4635
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "6px 8px 4px" }, children: [
4496
4636
  sorted.map((e, i) => {
4497
4637
  const eKey = `${e.ts}_${e.clientId}`;
4498
4638
  const isConfirmed = confirmedEventKeys.has(eKey);
@@ -4505,47 +4645,47 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
4505
4645
  const uploadStatus = imgId ? imageUploadStatus.get(imgId) : void 0;
4506
4646
  const payloadStr = JSON.stringify(e.payload ?? {});
4507
4647
  const payloadPreview = payloadStr.length > 70 ? payloadStr.slice(0, 70) + "\u2026" : payloadStr;
4508
- 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: [
4509
- /* @__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" }) }),
4510
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4511
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3 }, children: [
4512
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: typeColor }, children: e.type }),
4513
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", fontVariantNumeric: "tabular-nums" }, children: timeStr }),
4514
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
4515
- isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4516
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "check_circle" }),
4648
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 7, alignItems: "flex-start", padding: "6px 2px", borderBottom: "1px solid rgba(255,255,255,0.05)" }, children: [
4649
+ /* @__PURE__ */ (0, import_jsx_runtime22.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_runtime22.jsx)("img", { src: galleryItem.base64, style: { width: "100%", height: "100%", objectFit: "cover" } }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: "rgba(255,255,255,0.2)" }, children: "image" }) : /* @__PURE__ */ (0, import_jsx_runtime22.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" }) }),
4650
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4651
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3 }, children: [
4652
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: typeColor }, children: e.type }),
4653
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", fontVariantNumeric: "tabular-nums" }, children: timeStr }),
4654
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1 } }),
4655
+ isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "check_circle" }),
4517
4657
  "HF"
4518
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#fbbf24", display: "flex", alignItems: "center", gap: 2 }, children: [
4519
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "schedule" }),
4658
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, fontWeight: 700, color: "#fbbf24", display: "flex", alignItems: "center", gap: 2 }, children: [
4659
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "schedule" }),
4520
4660
  "lokal"
4521
4661
  ] })
4522
4662
  ] }),
4523
- isImageEvent && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3, flexWrap: "wrap" }, children: [
4524
- uploadStatus === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4525
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_done" }),
4663
+ isImageEvent && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 3, flexWrap: "wrap" }, children: [
4664
+ uploadStatus === "done" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4665
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_done" }),
4526
4666
  "Upload \u2713"
4527
4667
  ] }),
4528
- uploadStatus === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#60a5fa", display: "flex", alignItems: "center", gap: 2 }, children: [
4529
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_upload" }),
4668
+ uploadStatus === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, color: "#60a5fa", display: "flex", alignItems: "center", gap: 2 }, children: [
4669
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_upload" }),
4530
4670
  "l\xE4dt hoch\u2026"
4531
4671
  ] }),
4532
- uploadStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4533
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_off" }),
4672
+ uploadStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4673
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "cloud_off" }),
4534
4674
  "Upload fehlgeschlagen"
4535
4675
  ] }),
4536
- galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4537
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "photo" }),
4676
+ galleryItem?.base64 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, color: "#4ade80", display: "flex", alignItems: "center", gap: 2 }, children: [
4677
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "photo" }),
4538
4678
  uploadStatus ? "lokal" : "von HF geladen"
4539
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4540
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "broken_image" }),
4679
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 9, color: "#f87171", display: "flex", alignItems: "center", gap: 2 }, children: [
4680
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: "broken_image" }),
4541
4681
  uploadStatus === "failed" ? "Binary nicht auf HF" : "wird geladen\u2026"
4542
4682
  ] })
4543
4683
  ] }),
4544
- /* @__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 })
4684
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 9, color: "rgba(255,255,255,0.25)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: payloadPreview })
4545
4685
  ] })
4546
4686
  ] }, `${eKey}_${i}`);
4547
4687
  }),
4548
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "6px 0 2px", fontSize: 9, color: "rgba(255,255,255,0.2)", textAlign: "right" }, children: [
4688
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "6px 0 2px", fontSize: 9, color: "rgba(255,255,255,0.2)", textAlign: "right" }, children: [
4549
4689
  events.length,
4550
4690
  " Events gesamt \xB7 ",
4551
4691
  [...confirmedEventKeys].length,
@@ -4554,9 +4694,9 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
4554
4694
  ] });
4555
4695
  }
4556
4696
  function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
4557
- const [selected, setSelected] = (0, import_react23.useState)(null);
4558
- const [results, setResults] = (0, import_react23.useState)({});
4559
- const [expanded, setExpanded] = (0, import_react23.useState)({});
4697
+ const [selected, setSelected] = (0, import_react24.useState)(null);
4698
+ const [results, setResults] = (0, import_react24.useState)({});
4699
+ const [expanded, setExpanded] = (0, import_react24.useState)({});
4560
4700
  const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
4561
4701
  const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
4562
4702
  const setDone = (id, steps, t0) => {
@@ -4604,15 +4744,15 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4604
4744
  { id: "img-hub", label: "Upload hub lib", icon: "package_2", desc: "uploadFile() via @huggingface/hub" },
4605
4745
  { id: "img-cdn", label: "Upload CDN lib", icon: "language", desc: "uploadFile() via esm.sh hub lib" }
4606
4746
  ];
4607
- 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: [
4608
- 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." }),
4609
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4747
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflowY: "auto", padding: "12px 10px 80px", boxSizing: "border-box", fontFamily: "inherit" }, children: [
4748
+ noToken && /* @__PURE__ */ (0, import_jsx_runtime22.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." }),
4749
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4610
4750
  CollapsibleCard,
4611
4751
  {
4612
4752
  title: "Event Monitor",
4613
- icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "bolt" }),
4753
+ icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "bolt" }),
4614
4754
  defaultOpen: true,
4615
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4755
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4616
4756
  EventMonitor,
4617
4757
  {
4618
4758
  events: allEvents,
@@ -4623,52 +4763,52 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4623
4763
  )
4624
4764
  }
4625
4765
  ) }),
4626
- missingImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4766
+ missingImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4627
4767
  CollapsibleCard,
4628
4768
  {
4629
4769
  title: `Fehlende Bilder auf HF (${missingImages.length})`,
4630
- icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
4770
+ icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
4631
4771
  defaultOpen: false,
4632
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "8px 10px 4px" }, children: [
4633
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 11, color: "rgba(255,255,255,0.4)", marginBottom: 8 }, children: "Metadata-Eintr\xE4ge ohne Bild auf HuggingFace \u2014 Orphaned entries." }),
4634
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
4635
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
4772
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "8px 10px 4px" }, children: [
4773
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 11, color: "rgba(255,255,255,0.4)", marginBottom: 8 }, children: "Metadata-Eintr\xE4ge ohne Bild auf HuggingFace \u2014 Orphaned entries." }),
4774
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
4775
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
4636
4776
  "UUID (Flow-App): ",
4637
4777
  missingImages.filter((e) => !e.filename).length
4638
4778
  ] }),
4639
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "\xB7" }),
4640
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
4779
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "\xB7" }),
4780
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
4641
4781
  "Filename (Server-Upload): ",
4642
4782
  missingImages.filter((e) => !!e.filename).length
4643
4783
  ] })
4644
4784
  ] }),
4645
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { maxHeight: 300, overflowY: "auto", fontFamily: "monospace", fontSize: 10 }, children: missingImages.map((e) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "3px 0", borderBottom: "1px solid rgba(255,255,255,0.04)", color: "rgba(255,255,255,0.5)", display: "flex", gap: 8 }, children: [
4646
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
4647
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
4648
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
4785
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { maxHeight: 300, overflowY: "auto", fontFamily: "monospace", fontSize: 10 }, children: missingImages.map((e) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "3px 0", borderBottom: "1px solid rgba(255,255,255,0.04)", color: "rgba(255,255,255,0.5)", display: "flex", gap: 8 }, children: [
4786
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
4787
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
4788
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
4649
4789
  ] }, e.id)) })
4650
4790
  ] })
4651
4791
  }
4652
4792
  ) }),
4653
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4793
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4654
4794
  CollapsibleCard,
4655
4795
  {
4656
4796
  title: "Upload Tests",
4657
- icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "science" }),
4797
+ icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "science" }),
4658
4798
  defaultOpen: false,
4659
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "10px 10px 4px" }, children: [
4660
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 14 }, children: [
4661
- /* @__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: [
4799
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "10px 10px 4px" }, children: [
4800
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: 14 }, children: [
4801
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }, children: [
4662
4802
  "Bild ausw\xE4hlen (",
4663
4803
  withResults.length,
4664
4804
  " verf\xFCgbar)"
4665
4805
  ] }),
4666
- 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)(
4806
+ withResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.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_runtime22.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }, children: withResults.slice(0, 12).map((g) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4667
4807
  "button",
4668
4808
  {
4669
4809
  onClick: () => setSelected(g),
4670
4810
  style: { padding: 0, border: `2px solid ${selected?.id === g.id ? "#0284c7" : "transparent"}`, borderRadius: 6, cursor: "pointer", overflow: "hidden", background: "none", lineHeight: 0 },
4671
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4811
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4672
4812
  "img",
4673
4813
  {
4674
4814
  src: g.base64,
@@ -4679,38 +4819,38 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4679
4819
  },
4680
4820
  g.id
4681
4821
  )) }),
4682
- selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
4683
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4822
+ selected && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
4823
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4684
4824
  "img",
4685
4825
  {
4686
4826
  src: selected.base64,
4687
4827
  style: { width: 80, height: 80, objectFit: "cover", borderRadius: 8, border: "1px solid rgba(255,255,255,0.1)", flexShrink: 0 }
4688
4828
  }
4689
4829
  ),
4690
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4691
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
4692
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
4830
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4831
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
4832
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
4693
4833
  "ID: ",
4694
4834
  selected.id
4695
4835
  ] }),
4696
- /* @__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: [
4836
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 2 }, children: [
4697
4837
  "Ziel: test/",
4698
4838
  selected.id,
4699
4839
  ".jpg"
4700
4840
  ] }),
4701
- 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 })
4841
+ selected.prompt && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selected.prompt })
4702
4842
  ] })
4703
4843
  ] })
4704
4844
  ] }),
4705
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 14 }, children: [
4706
- /* @__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: [
4845
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: 14 }, children: [
4846
+ /* @__PURE__ */ (0, import_jsx_runtime22.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: [
4707
4847
  "Bild hochladen \u2192 test/",
4708
4848
  "{",
4709
4849
  "id",
4710
4850
  "}",
4711
4851
  ".jpg"
4712
4852
  ] }),
4713
- imgTests.map((t) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4853
+ imgTests.map((t) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4714
4854
  TestCard,
4715
4855
  {
4716
4856
  id: t.id,
@@ -4726,13 +4866,13 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4726
4866
  t.id
4727
4867
  ))
4728
4868
  ] }),
4729
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 4 }, children: [
4730
- /* @__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: [
4869
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: 4 }, children: [
4870
+ /* @__PURE__ */ (0, import_jsx_runtime22.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: [
4731
4871
  "Event schreiben \u2192 ",
4732
4872
  namespace || "(kein namespace)",
4733
4873
  "test/events/"
4734
4874
  ] }),
4735
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4875
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4736
4876
  TestCard,
4737
4877
  {
4738
4878
  id: "event",
@@ -4754,10 +4894,10 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4754
4894
  }
4755
4895
 
4756
4896
  // src/components/ServerTab.tsx
4757
- var import_react24 = require("react");
4758
- var import_jsx_runtime22 = require("react/jsx-runtime");
4897
+ var import_react25 = require("react");
4898
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4759
4899
  function StarRating({ rating = 0 }) {
4760
- 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)) });
4900
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
4761
4901
  }
4762
4902
  async function serverGet(baseUrl, path) {
4763
4903
  const url = `${baseUrl.replace(/\/$/, "")}${path}`;
@@ -4767,21 +4907,21 @@ async function serverGet(baseUrl, path) {
4767
4907
  return json && typeof json === "object" && "data" in json ? json.data : json;
4768
4908
  }
4769
4909
  function ServerTab({ serverBaseUrl }) {
4770
- const [step, setStep] = (0, import_react24.useState)("user");
4771
- const [users, setUsers] = (0, import_react24.useState)([]);
4772
- const [usersLoading, setUsersLoading] = (0, import_react24.useState)(false);
4773
- const [usersError, setUsersError] = (0, import_react24.useState)(null);
4774
- const [selectedUser, setSelectedUser] = (0, import_react24.useState)(null);
4775
- const [contexts, setContexts] = (0, import_react24.useState)([]);
4776
- const [contextsLoading, setContextsLoading] = (0, import_react24.useState)(false);
4777
- const [selectedContext, setSelectedContext] = (0, import_react24.useState)(null);
4778
- const [tags, setTags] = (0, import_react24.useState)([]);
4779
- const [items, setItems] = (0, import_react24.useState)([]);
4780
- const [libLoading, setLibLoading] = (0, import_react24.useState)(false);
4781
- const [libError, setLibError] = (0, import_react24.useState)(null);
4782
- const [activeTag, setActiveTag] = (0, import_react24.useState)(null);
4783
- const [preview, setPreview] = (0, import_react24.useState)(null);
4784
- (0, import_react24.useEffect)(() => {
4910
+ const [step, setStep] = (0, import_react25.useState)("user");
4911
+ const [users, setUsers] = (0, import_react25.useState)([]);
4912
+ const [usersLoading, setUsersLoading] = (0, import_react25.useState)(false);
4913
+ const [usersError, setUsersError] = (0, import_react25.useState)(null);
4914
+ const [selectedUser, setSelectedUser] = (0, import_react25.useState)(null);
4915
+ const [contexts, setContexts] = (0, import_react25.useState)([]);
4916
+ const [contextsLoading, setContextsLoading] = (0, import_react25.useState)(false);
4917
+ const [selectedContext, setSelectedContext] = (0, import_react25.useState)(null);
4918
+ const [tags, setTags] = (0, import_react25.useState)([]);
4919
+ const [items, setItems] = (0, import_react25.useState)([]);
4920
+ const [libLoading, setLibLoading] = (0, import_react25.useState)(false);
4921
+ const [libError, setLibError] = (0, import_react25.useState)(null);
4922
+ const [activeTag, setActiveTag] = (0, import_react25.useState)(null);
4923
+ const [preview, setPreview] = (0, import_react25.useState)(null);
4924
+ (0, import_react25.useEffect)(() => {
4785
4925
  if (!serverBaseUrl) return;
4786
4926
  setUsersLoading(true);
4787
4927
  setUsersError(null);
@@ -4835,54 +4975,54 @@ function ServerTab({ serverBaseUrl }) {
4835
4975
  };
4836
4976
  const filteredItems = activeTag ? items.filter((item) => item.tags?.some((t) => t.l === activeTag)) : items;
4837
4977
  if (!serverBaseUrl) return null;
4838
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
4839
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
4840
- 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" }) }),
4841
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-[11px] font-medium text-white/40 tracking-wide flex-1", children: [
4978
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
4979
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
4980
+ step !== "user" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: reset, className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "arrow_back" }) }),
4981
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "text-[11px] font-medium text-white/40 tracking-wide flex-1", children: [
4842
4982
  step === "user" && "Server Browser",
4843
4983
  step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
4844
4984
  step === "library" && `${selectedUser?.username} / ${selectedContext?.label || selectedContext?.name || selectedContext?.id}`
4845
4985
  ] })
4846
4986
  ] }),
4847
- 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: [
4848
- usersLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
4849
- usersError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-red-400 text-[11px] text-center py-4", children: usersError }),
4850
- !usersLoading && users.map((u) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4987
+ step === "user" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: [
4988
+ usersLoading && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
4989
+ usersError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-red-400 text-[11px] text-center py-4", children: usersError }),
4990
+ !usersLoading && users.map((u) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4851
4991
  "button",
4852
4992
  {
4853
4993
  onClick: () => selectUser(u),
4854
4994
  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",
4855
4995
  children: [
4856
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "person" }),
4857
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
4858
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[12px] font-medium text-white", children: u.username }),
4859
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] text-white/30", children: u.id })
4996
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "person" }),
4997
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
4998
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-medium text-white", children: u.username }),
4999
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/30", children: u.id })
4860
5000
  ] }),
4861
- 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" })
5001
+ contextsLoading && selectedUser?.id === u.id ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/30 animate-spin", children: "progress_activity" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/20", children: "chevron_right" })
4862
5002
  ]
4863
5003
  },
4864
5004
  u.id
4865
5005
  ))
4866
5006
  ] }),
4867
- 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)(
5007
+ step === "context" && /* @__PURE__ */ (0, import_jsx_runtime23.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_runtime23.jsxs)(
4868
5008
  "button",
4869
5009
  {
4870
5010
  onClick: () => loadLibrary(selectedUser, ctx),
4871
5011
  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",
4872
5012
  children: [
4873
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "folder" }),
4874
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
4875
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[12px] font-medium text-white", children: ctx.label || ctx.name || ctx.id }),
4876
- ctx.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] text-white/30 truncate", children: ctx.description })
5013
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px] text-white/40", children: "folder" }),
5014
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [
5015
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-medium text-white", children: ctx.label || ctx.name || ctx.id }),
5016
+ ctx.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/30 truncate", children: ctx.description })
4877
5017
  ] }),
4878
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/20", children: "chevron_right" })
5018
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[16px] text-white/20", children: "chevron_right" })
4879
5019
  ]
4880
5020
  },
4881
5021
  ctx.id
4882
5022
  )) }),
4883
- step === "library" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
4884
- 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: [
4885
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5023
+ step === "library" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5024
+ tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1.5 px-3 py-2 overflow-x-auto border-b border-white/8", style: { scrollbarWidth: "none" }, children: [
5025
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4886
5026
  "button",
4887
5027
  {
4888
5028
  onClick: () => setActiveTag(null),
@@ -4890,7 +5030,7 @@ function ServerTab({ serverBaseUrl }) {
4890
5030
  children: "Alle"
4891
5031
  }
4892
5032
  ),
4893
- tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5033
+ tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4894
5034
  "button",
4895
5035
  {
4896
5036
  onClick: () => setActiveTag(activeTag === t.label ? null : t.label),
@@ -4900,22 +5040,22 @@ function ServerTab({ serverBaseUrl }) {
4900
5040
  t.id
4901
5041
  ))
4902
5042
  ] }),
4903
- libLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-8", children: "Lade Library\u2026" }),
4904
- libError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-red-400 text-[11px] text-center py-8", children: libError }),
4905
- !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: [
4906
- 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." }),
5043
+ libLoading && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/30 text-[11px] text-center py-8", children: "Lade Library\u2026" }),
5044
+ libError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-red-400 text-[11px] text-center py-8", children: libError }),
5045
+ !libLoading && !libError && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-h-0 overflow-y-auto p-3 grid grid-cols-2 gap-2 content-start", children: [
5046
+ filteredItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "col-span-2 text-white/30 text-[11px] text-center py-8", children: "Keine Eintr\xE4ge." }),
4907
5047
  filteredItems.map((item, i) => {
4908
5048
  const imgUrl = item.images?.[0]?.url;
4909
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5049
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4910
5050
  "button",
4911
5051
  {
4912
5052
  onClick: () => imgUrl && setPreview(imgUrl),
4913
5053
  className: "flex flex-col rounded-xl overflow-hidden border border-white/8 hover:border-white/25 transition-all bg-white/3 text-left",
4914
5054
  children: [
4915
- 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" }) }),
4916
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "p-1.5 flex flex-col gap-0.5", children: [
4917
- item.title && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[10px] font-medium text-white/70 truncate", children: item.title }),
4918
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StarRating, { rating: item.rating })
5055
+ imgUrl ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: imgUrl, alt: "", className: "w-full aspect-square object-cover bg-white/5" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-full aspect-square bg-white/5 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px] text-white/15", children: "image" }) }),
5056
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-1.5 flex flex-col gap-0.5", children: [
5057
+ item.title && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-medium text-white/70 truncate", children: item.title }),
5058
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StarRating, { rating: item.rating })
4919
5059
  ] })
4920
5060
  ]
4921
5061
  },
@@ -4924,17 +5064,17 @@ function ServerTab({ serverBaseUrl }) {
4924
5064
  })
4925
5065
  ] })
4926
5066
  ] }),
4927
- 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: [
4928
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: preview, alt: "", className: "max-w-full max-h-full object-contain" }),
4929
- /* @__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" }) })
5067
+ preview && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute inset-0 z-50 bg-black/90 flex items-center justify-center", onClick: () => setPreview(null), children: [
5068
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: preview, alt: "", className: "max-w-full max-h-full object-contain" }),
5069
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { className: "absolute top-3 right-3 text-white/60 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: "close" }) })
4930
5070
  ] })
4931
5071
  ] });
4932
5072
  }
4933
5073
 
4934
5074
  // src/components/AvatarArchitectApp.tsx
4935
- var import_jsx_runtime23 = require("react/jsx-runtime");
5075
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4936
5076
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
4937
- (0, import_react25.useEffect)(() => {
5077
+ (0, import_react26.useEffect)(() => {
4938
5078
  const id = "flow-styles";
4939
5079
  if (!document.getElementById(id)) {
4940
5080
  const style = document.createElement("style");
@@ -4943,19 +5083,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4943
5083
  document.head.appendChild(style);
4944
5084
  }
4945
5085
  }, []);
4946
- const [showStart, setShowStart] = (0, import_react25.useState)(true);
4947
- const [layoutChoice, setLayoutChoice] = (0, import_react25.useState)(() => {
5086
+ const [showStart, setShowStart] = (0, import_react26.useState)(true);
5087
+ const [layoutChoice, setLayoutChoice] = (0, import_react26.useState)(() => {
4948
5088
  try {
4949
5089
  return localStorage.getItem("aa-layout") || null;
4950
5090
  } catch {
4951
5091
  return null;
4952
5092
  }
4953
5093
  });
4954
- const [projectLoaded, setProjectLoaded] = (0, import_react25.useState)(false);
4955
- const [hfToken, setHfToken] = (0, import_react25.useState)(initialHfToken || "");
4956
- const [hfTokenInput, setHfTokenInput] = (0, import_react25.useState)(initialHfToken || "");
4957
- const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react25.useState)(false);
4958
- const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react25.useState)(() => {
5094
+ const [projectLoaded, setProjectLoaded] = (0, import_react26.useState)(false);
5095
+ const [hfToken, setHfToken] = (0, import_react26.useState)(initialHfToken || "");
5096
+ const [hfTokenInput, setHfTokenInput] = (0, import_react26.useState)(initialHfToken || "");
5097
+ const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react26.useState)(false);
5098
+ const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react26.useState)(() => {
4959
5099
  const KNOWN = ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"];
4960
5100
  const DEFAULT = "app.art-by-rolands.de/";
4961
5101
  try {
@@ -4967,8 +5107,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4967
5107
  return DEFAULT;
4968
5108
  }
4969
5109
  });
4970
- const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react25.useState)(null);
4971
- (0, import_react25.useEffect)(() => {
5110
+ const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react26.useState)(null);
5111
+ (0, import_react26.useEffect)(() => {
4972
5112
  if (hfNamespace !== void 0) return;
4973
5113
  const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
4974
5114
  if (!backendUrl) return;
@@ -4990,36 +5130,36 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4990
5130
  refresh: refreshHF,
4991
5131
  hasStateZip
4992
5132
  } = useHFState(hfToken, effectiveNamespace);
4993
- const [imageUploadStatus, setImageUploadStatus] = (0, import_react25.useState)(/* @__PURE__ */ new Map());
4994
- const [bootstrapLog, setBootstrapLog] = (0, import_react25.useState)([]);
4995
- const [isBootstrapping, setIsBootstrapping] = (0, import_react25.useState)(false);
4996
- const [hfMissingImages, setHfMissingImages] = (0, import_react25.useState)([]);
4997
- const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4998
- 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: [
5133
+ const [imageUploadStatus, setImageUploadStatus] = (0, import_react26.useState)(/* @__PURE__ */ new Map());
5134
+ const [bootstrapLog, setBootstrapLog] = (0, import_react26.useState)([]);
5135
+ const [isBootstrapping, setIsBootstrapping] = (0, import_react26.useState)(false);
5136
+ const [hfMissingImages, setHfMissingImages] = (0, import_react26.useState)([]);
5137
+ const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
5138
+ localOnlyCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.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: [
4999
5139
  "\u26A0 ",
5000
5140
  localOnlyCount,
5001
5141
  " lokale Event",
5002
5142
  localOnlyCount > 1 ? "s" : "",
5003
5143
  " noch nicht auf HF best\xE4tigt"
5004
5144
  ] }),
5005
- 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: [
5145
+ pendingBufferCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
5006
5146
  pendingBufferCount,
5007
5147
  " \xC4nderung",
5008
5148
  pendingBufferCount > 1 ? "en" : "",
5009
5149
  " lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
5010
5150
  ] }),
5011
- 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: [
5151
+ eventCount > 100 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
5012
5152
  "\u26A0 ",
5013
5153
  eventCount,
5014
5154
  " Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
5015
5155
  ] }),
5016
- 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: [
5156
+ eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
5017
5157
  eventCount,
5018
5158
  " Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
5019
5159
  ] }),
5020
- hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
5021
- /* @__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" }),
5022
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5160
+ hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
5161
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }),
5162
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5023
5163
  "button",
5024
5164
  {
5025
5165
  disabled: isBootstrapping || !effectiveNamespace,
@@ -5040,10 +5180,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5040
5180
  children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
5041
5181
  }
5042
5182
  ),
5043
- 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)) })
5183
+ bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: l }, i)) })
5044
5184
  ] })
5045
5185
  ] });
5046
- const wsInputRef = (0, import_react25.useRef)(null);
5186
+ const wsInputRef = (0, import_react26.useRef)(null);
5047
5187
  const startApp = (choice) => {
5048
5188
  try {
5049
5189
  localStorage.setItem("aa-layout", choice);
@@ -5052,18 +5192,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5052
5192
  setLayoutChoice(choice);
5053
5193
  setShowStart(false);
5054
5194
  };
5055
- const [nodes, setNodes] = (0, import_react25.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
5056
- const [edges, setEdges] = (0, import_react25.useState)([]);
5057
- const [history, setHistory] = (0, import_react25.useState)([]);
5058
- const [galleryItems, setGalleryItems] = (0, import_react25.useState)([]);
5059
- const galleryItemsRef = (0, import_react25.useRef)([]);
5060
- (0, import_react25.useEffect)(() => {
5195
+ const [nodes, setNodes] = (0, import_react26.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
5196
+ const [edges, setEdges] = (0, import_react26.useState)([]);
5197
+ const [history, setHistory] = (0, import_react26.useState)([]);
5198
+ const [galleryItems, setGalleryItems] = (0, import_react26.useState)([]);
5199
+ const galleryItemsRef = (0, import_react26.useRef)([]);
5200
+ (0, import_react26.useEffect)(() => {
5061
5201
  galleryItemsRef.current = galleryItems;
5062
5202
  }, [galleryItems]);
5063
- const hfImageNotFoundRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
5064
- const [galleryVisibleCount, setGalleryVisibleCount] = (0, import_react25.useState)(20);
5065
- const [historyVisibleCount, setHistoryVisibleCount] = (0, import_react25.useState)(20);
5066
- const loadThumbnailsForEntries = (0, import_react25.useCallback)(async (entries) => {
5203
+ const hfImageNotFoundRef = (0, import_react26.useRef)(/* @__PURE__ */ new Map());
5204
+ const [galleryVisibleCount, setGalleryVisibleCount] = (0, import_react26.useState)(20);
5205
+ const [historyVisibleCount, setHistoryVisibleCount] = (0, import_react26.useState)(20);
5206
+ const loadThumbnailsForEntries = (0, import_react26.useCallback)(async (entries) => {
5067
5207
  for (const entry of entries) {
5068
5208
  if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
5069
5209
  if (hfImageNotFoundRef.current.has(entry.id)) continue;
@@ -5082,7 +5222,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5082
5222
  }
5083
5223
  }
5084
5224
  }, [hfToken, effectiveNamespace]);
5085
- (0, import_react25.useEffect)(() => {
5225
+ (0, import_react26.useEffect)(() => {
5086
5226
  if (!hfState) return;
5087
5227
  if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
5088
5228
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
@@ -5109,36 +5249,36 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5109
5249
  return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5110
5250
  });
5111
5251
  }, [hfState]);
5112
- (0, import_react25.useEffect)(() => {
5252
+ (0, import_react26.useEffect)(() => {
5113
5253
  if (!hfState) return;
5114
5254
  const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5115
5255
  const skeletons = sortedMeta.map((m) => ({ id: m.id, prompt: m.prompt, timestamp: m.timestamp, status: "done", nodeId: m.id, tags: m.tags || [] }));
5116
5256
  const repIds = new Set(groupByPrompt(skeletons).slice(0, galleryVisibleCount).map((g) => g.representative.id));
5117
5257
  loadThumbnailsForEntries(sortedMeta.filter((e) => repIds.has(e.id)));
5118
5258
  }, [hfState, galleryVisibleCount, loadThumbnailsForEntries]);
5119
- (0, import_react25.useEffect)(() => {
5259
+ (0, import_react26.useEffect)(() => {
5120
5260
  if (!hfState) return;
5121
5261
  const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5122
5262
  loadThumbnailsForEntries(sortedMeta.slice(0, historyVisibleCount));
5123
5263
  }, [hfState, historyVisibleCount, loadThumbnailsForEntries]);
5124
- const [activePrompt, setActivePrompt] = (0, import_react25.useState)("");
5125
- const [isSynthesizing, setIsSynthesizing] = (0, import_react25.useState)(false);
5126
- const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react25.useState)(0);
5127
- const [currentResult, setCurrentResult] = (0, import_react25.useState)(null);
5128
- const [focusedNodeId, setFocusedNodeId] = (0, import_react25.useState)(null);
5129
- const [leftTab, setLeftTab] = (0, import_react25.useState)("prompt");
5130
- const [promptFeedback, setPromptFeedback] = (0, import_react25.useState)(null);
5131
- const [lastPromptPayload, setLastPromptPayload] = (0, import_react25.useState)(null);
5132
- const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react25.useState)(false);
5133
- const [activeTab, setActiveTab] = (0, import_react25.useState)("history");
5134
- const [mobileTab, setMobileTab] = (0, import_react25.useState)("stage");
5135
- const [middlePanel, setMiddlePanel] = (0, import_react25.useState)("stage");
5136
- const [recentLabItems, setRecentLabItems] = (0, import_react25.useState)([]);
5137
- const [aspectRatio, setAspectRatio] = (0, import_react25.useState)("1:1");
5138
- const [selectedModel, setSelectedModel] = (0, import_react25.useState)("\u{1F34C} Nano Banana Pro");
5139
- const [seed, setSeed] = (0, import_react25.useState)(Math.floor(Math.random() * 1e6));
5140
- const [seedMode, setSeedMode] = (0, import_react25.useState)("random");
5141
- const [imageCount, setImageCount] = (0, import_react25.useState)(() => {
5264
+ const [activePrompt, setActivePrompt] = (0, import_react26.useState)("");
5265
+ const [isSynthesizing, setIsSynthesizing] = (0, import_react26.useState)(false);
5266
+ const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react26.useState)(0);
5267
+ const [currentResult, setCurrentResult] = (0, import_react26.useState)(null);
5268
+ const [focusedNodeId, setFocusedNodeId] = (0, import_react26.useState)(null);
5269
+ const [leftTab, setLeftTab] = (0, import_react26.useState)("prompt");
5270
+ const [promptFeedback, setPromptFeedback] = (0, import_react26.useState)(null);
5271
+ const [lastPromptPayload, setLastPromptPayload] = (0, import_react26.useState)(null);
5272
+ const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react26.useState)(false);
5273
+ const [activeTab, setActiveTab] = (0, import_react26.useState)("history");
5274
+ const [mobileTab, setMobileTab] = (0, import_react26.useState)("stage");
5275
+ const [middlePanel, setMiddlePanel] = (0, import_react26.useState)("stage");
5276
+ const [recentLabItems, setRecentLabItems] = (0, import_react26.useState)([]);
5277
+ const [aspectRatio, setAspectRatio] = (0, import_react26.useState)("1:1");
5278
+ const [selectedModel, setSelectedModel] = (0, import_react26.useState)("\u{1F34C} Nano Banana Pro");
5279
+ const [seed, setSeed] = (0, import_react26.useState)(Math.floor(Math.random() * 1e6));
5280
+ const [seedMode, setSeedMode] = (0, import_react26.useState)("random");
5281
+ const [imageCount, setImageCount] = (0, import_react26.useState)(() => {
5142
5282
  try {
5143
5283
  const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
5144
5284
  return v >= 1 && v <= 8 ? v : 4;
@@ -5160,45 +5300,45 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5160
5300
  { label: "4 Bilder", value: "4" },
5161
5301
  { label: "8 Bilder", value: "8" }
5162
5302
  ];
5163
- const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react25.useState)(false);
5164
- const [isRightCollapsed, setIsRightCollapsed] = (0, import_react25.useState)(false);
5165
- const [leftPanelWidth, setLeftPanelWidth] = (0, import_react25.useState)(() => {
5303
+ const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react26.useState)(false);
5304
+ const [isRightCollapsed, setIsRightCollapsed] = (0, import_react26.useState)(false);
5305
+ const [leftPanelWidth, setLeftPanelWidth] = (0, import_react26.useState)(() => {
5166
5306
  try {
5167
5307
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
5168
5308
  } catch {
5169
5309
  return 260;
5170
5310
  }
5171
5311
  });
5172
- const [rightPanelWidth, setRightPanelWidth] = (0, import_react25.useState)(() => {
5312
+ const [rightPanelWidth, setRightPanelWidth] = (0, import_react26.useState)(() => {
5173
5313
  try {
5174
5314
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
5175
5315
  } catch {
5176
5316
  return 320;
5177
5317
  }
5178
5318
  });
5179
- const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react25.useState)(false);
5180
- const [projectActionState, setProjectActionState] = (0, import_react25.useState)("idle");
5181
- const syncServerDataRef = (0, import_react25.useRef)(null);
5182
- const [workspaceTags, setWorkspaceTags] = (0, import_react25.useState)(null);
5183
- const [serverProjects, setServerProjects] = (0, import_react25.useState)([]);
5184
- const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react25.useState)(false);
5185
- const [highContrast, setHighContrast] = (0, import_react25.useState)(() => {
5319
+ const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react26.useState)(false);
5320
+ const [projectActionState, setProjectActionState] = (0, import_react26.useState)("idle");
5321
+ const syncServerDataRef = (0, import_react26.useRef)(null);
5322
+ const [workspaceTags, setWorkspaceTags] = (0, import_react26.useState)(null);
5323
+ const [serverProjects, setServerProjects] = (0, import_react26.useState)([]);
5324
+ const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react26.useState)(false);
5325
+ const [highContrast, setHighContrast] = (0, import_react26.useState)(() => {
5186
5326
  try {
5187
5327
  return localStorage.getItem("aa-contrast") === "high";
5188
5328
  } catch {
5189
5329
  return false;
5190
5330
  }
5191
5331
  });
5192
- const [activeReferenceId, setActiveReferenceId] = (0, import_react25.useState)(null);
5193
- const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react25.useState)(null);
5194
- const [isScanningImage, setIsScanningImage] = (0, import_react25.useState)(false);
5195
- const [touchStartX, setTouchStartX] = (0, import_react25.useState)(null);
5196
- const [isFullscreen, setIsFullscreen] = (0, import_react25.useState)(false);
5197
- const [zoomScale, setZoomScale] = (0, import_react25.useState)(1);
5198
- const [zoomOffset, setZoomOffset] = (0, import_react25.useState)({ x: 0, y: 0 });
5199
- const lastPinchDist = (0, import_react25.useRef)(null);
5200
- const lastTapTime = (0, import_react25.useRef)(0);
5201
- const dragStart = (0, import_react25.useRef)(null);
5332
+ const [activeReferenceId, setActiveReferenceId] = (0, import_react26.useState)(null);
5333
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react26.useState)(null);
5334
+ const [isScanningImage, setIsScanningImage] = (0, import_react26.useState)(false);
5335
+ const [touchStartX, setTouchStartX] = (0, import_react26.useState)(null);
5336
+ const [isFullscreen, setIsFullscreen] = (0, import_react26.useState)(false);
5337
+ const [zoomScale, setZoomScale] = (0, import_react26.useState)(1);
5338
+ const [zoomOffset, setZoomOffset] = (0, import_react26.useState)({ x: 0, y: 0 });
5339
+ const lastPinchDist = (0, import_react26.useRef)(null);
5340
+ const lastTapTime = (0, import_react26.useRef)(0);
5341
+ const dragStart = (0, import_react26.useRef)(null);
5202
5342
  const openFullscreen = () => {
5203
5343
  setIsFullscreen(true);
5204
5344
  setZoomScale(1);
@@ -5261,7 +5401,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5261
5401
  setActiveReferenceId(null);
5262
5402
  setActiveReferenceThumbnail(null);
5263
5403
  };
5264
- const labServices = (0, import_react25.useMemo)(() => {
5404
+ const labServices = (0, import_react26.useMemo)(() => {
5265
5405
  const available = groupGenerationsToLabItems([...galleryItems, ...history]);
5266
5406
  return {
5267
5407
  availableItems: available,
@@ -5341,14 +5481,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5341
5481
  setIsScanningImage(false);
5342
5482
  }
5343
5483
  };
5344
- const currentIndex = (0, import_react25.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
5345
- const goToPrev = (0, import_react25.useCallback)(() => {
5484
+ const currentIndex = (0, import_react26.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
5485
+ const goToPrev = (0, import_react26.useCallback)(() => {
5346
5486
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
5347
5487
  }, [currentIndex, history]);
5348
- const goToNext = (0, import_react25.useCallback)(() => {
5488
+ const goToNext = (0, import_react26.useCallback)(() => {
5349
5489
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
5350
5490
  }, [currentIndex, history]);
5351
- const handleGallerySelect = (0, import_react25.useCallback)((g) => {
5491
+ const handleGallerySelect = (0, import_react26.useCallback)((g) => {
5352
5492
  setCurrentResult(g);
5353
5493
  setMobileTab("stage");
5354
5494
  if (g.hasThumb && g.filename && hfToken && !g.fullBase64) {
@@ -5361,7 +5501,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5361
5501
  });
5362
5502
  }
5363
5503
  }, [hfToken, effectiveNamespace]);
5364
- const handleTitleSet = (0, import_react25.useCallback)((id) => {
5504
+ const handleTitleSet = (0, import_react26.useCallback)((id) => {
5365
5505
  const ts = Date.now();
5366
5506
  setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
5367
5507
  setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
@@ -5370,13 +5510,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5370
5510
  });
5371
5511
  }
5372
5512
  }, [hfToken, effectiveNamespace, hfWriteEvent]);
5373
- const currentGroup = (0, import_react25.useMemo)(() => {
5513
+ const currentGroup = (0, import_react26.useMemo)(() => {
5374
5514
  if (!currentResult?.prompt) return [];
5375
5515
  const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
5376
5516
  const group = groups.find((gr) => gr.prompt === currentResult.prompt);
5377
5517
  return group ? group.items : [];
5378
5518
  }, [galleryItems, currentResult?.prompt]);
5379
- (0, import_react25.useEffect)(() => {
5519
+ (0, import_react26.useEffect)(() => {
5380
5520
  if (!currentResult?.prompt || !hfToken || !effectiveNamespace || !hfState) return;
5381
5521
  const siblings = galleryItemsRef.current.filter(
5382
5522
  (g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
@@ -5402,20 +5542,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5402
5542
  })();
5403
5543
  }, [currentResult?.id, currentResult?.prompt]);
5404
5544
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
5405
- const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5545
+ const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5406
5546
  "div",
5407
5547
  {
5408
5548
  className: "flex items-center gap-1 rounded-full bg-sky-500/15 border border-sky-400/30 px-2 shrink-0",
5409
5549
  style: { height: 24 },
5410
5550
  title: `${activeGenerationsCount} Generierung${activeGenerationsCount === 1 ? "" : "en"} l\xE4uft gerade`,
5411
5551
  children: [
5412
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
5413
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
5552
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
5553
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
5414
5554
  ]
5415
5555
  }
5416
5556
  ) : null;
5417
5557
  useKeyboardNavigation(history, currentResult, setCurrentResult);
5418
- const getSubtreeFormat = (0, import_react25.useCallback)((nodeId, depth = 0) => {
5558
+ const getSubtreeFormat = (0, import_react26.useCallback)((nodeId, depth = 0) => {
5419
5559
  const node = nodes.find((n) => n.id === nodeId);
5420
5560
  if (!node) return "";
5421
5561
  const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
@@ -5423,7 +5563,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5423
5563
  return `${indent}- ${node.data.label || "(unbenannt)"}
5424
5564
  ` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
5425
5565
  }, [nodes, edges]);
5426
- const activePath = (0, import_react25.useMemo)(() => {
5566
+ const activePath = (0, import_react26.useMemo)(() => {
5427
5567
  if (!focusedNodeId) return /* @__PURE__ */ new Set();
5428
5568
  const path = /* @__PURE__ */ new Set([focusedNodeId]);
5429
5569
  let currId = focusedNodeId;
@@ -5781,7 +5921,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5781
5921
  setTimeout(() => setProjectActionState("idle"), 4e3);
5782
5922
  }
5783
5923
  };
5784
- (0, import_react25.useEffect)(() => {
5924
+ (0, import_react26.useEffect)(() => {
5785
5925
  if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
5786
5926
  }, [activeTab]);
5787
5927
  const mergeWorkspaceTags = (local, remote) => {
@@ -5806,7 +5946,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5806
5946
  if (isFullscreen && currentResult?.base64) {
5807
5947
  const fsRaw = currentResult.fullBase64 || currentResult.base64;
5808
5948
  const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
5809
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5949
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5810
5950
  "div",
5811
5951
  {
5812
5952
  className: "fixed inset-0 bg-black z-50 flex items-center justify-center overflow-hidden touch-none",
@@ -5814,7 +5954,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5814
5954
  onTouchMove: handleFsTouchMove,
5815
5955
  onTouchEnd: handleFsTouchEnd,
5816
5956
  children: [
5817
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5957
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5818
5958
  "img",
5819
5959
  {
5820
5960
  src: fsBase64,
@@ -5831,77 +5971,77 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5831
5971
  }
5832
5972
  }
5833
5973
  ),
5834
- /* @__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" }) }),
5835
- zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5974
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
5975
+ zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => {
5836
5976
  setZoomScale(1);
5837
5977
  setZoomOffset({ x: 0, y: 0 });
5838
- }, 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" }) }),
5839
- history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5840
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5978
+ }, 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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
5979
+ history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
5980
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => {
5841
5981
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
5842
- }, 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" }) }),
5843
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
5982
+ }, 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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5983
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => {
5844
5984
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
5845
- }, 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" }) }),
5846
- /* @__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: [
5985
+ }, 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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5986
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
5847
5987
  currentIndex + 1,
5848
5988
  " / ",
5849
5989
  history.length
5850
5990
  ] })
5851
5991
  ] }),
5852
- 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" })
5992
+ zoomScale === 1 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
5853
5993
  ]
5854
5994
  }
5855
5995
  );
5856
5996
  }
5857
5997
  if (showStart) {
5858
- 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: [
5859
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
5998
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
5999
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
5860
6000
  const f = e.target.files?.[0];
5861
6001
  if (f) handleProjectImport(f);
5862
6002
  e.target.value = "";
5863
6003
  } }),
5864
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
5865
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
5866
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
5867
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
6004
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
6005
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
6006
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
6007
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
5868
6008
  "v",
5869
6009
  LIB_VERSION
5870
6010
  ] })
5871
6011
  ] }),
5872
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6012
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5873
6013
  "button",
5874
6014
  {
5875
6015
  onClick: toggleContrast,
5876
6016
  className: "flex items-center gap-3 px-5 py-3 rounded-2xl border transition-colors",
5877
6017
  style: { borderColor: highContrast ? "rgba(255,255,255,0.3)" : "rgba(255,255,255,0.08)", background: highContrast ? "rgba(255,255,255,0.08)" : "transparent" },
5878
6018
  children: [
5879
- /* @__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" }),
5880
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-start", children: [
5881
- /* @__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" }),
5882
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
6019
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
6020
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-start", children: [
6021
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
6022
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
5883
6023
  ] })
5884
6024
  ]
5885
6025
  }
5886
6026
  ),
5887
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5888
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6027
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6028
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5889
6029
  "button",
5890
6030
  {
5891
6031
  onClick: () => wsInputRef.current?.click(),
5892
6032
  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",
5893
6033
  style: { height: 56, background: projectLoaded ? "#16a34a" : "#0284c7" },
5894
6034
  children: [
5895
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
6035
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
5896
6036
  projectLoaded ? "Projekt geladen \u2713" : "Projekt laden (.zip)"
5897
6037
  ]
5898
6038
  }
5899
6039
  ),
5900
- !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
6040
+ !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
5901
6041
  ] }),
5902
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5903
- !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 w-full", children: [
5904
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6042
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6043
+ !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2 w-full", children: [
6044
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5905
6045
  "input",
5906
6046
  {
5907
6047
  type: "password",
@@ -5917,7 +6057,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5917
6057
  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)" }
5918
6058
  }
5919
6059
  ),
5920
- hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6060
+ hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5921
6061
  "button",
5922
6062
  {
5923
6063
  type: "button",
@@ -5928,9 +6068,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5928
6068
  }
5929
6069
  )
5930
6070
  ] }),
5931
- !hfNamespace && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
5932
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
5933
- ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6071
+ !hfNamespace && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
6072
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
6073
+ ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5934
6074
  "button",
5935
6075
  {
5936
6076
  onClick: () => {
@@ -5950,7 +6090,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5950
6090
  ns
5951
6091
  ))
5952
6092
  ] }),
5953
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6093
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5954
6094
  "button",
5955
6095
  {
5956
6096
  disabled: isLoadingFromHF,
@@ -5972,15 +6112,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5972
6112
  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",
5973
6113
  style: { height: 56, background: "#f59e0b" },
5974
6114
  children: [
5975
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
6115
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
5976
6116
  isLoadingFromHF ? "Laden\u2026" : "Von HF laden"
5977
6117
  ]
5978
6118
  }
5979
6119
  ),
5980
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
6120
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
5981
6121
  ] }),
5982
- onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5983
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6122
+ onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6123
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5984
6124
  "button",
5985
6125
  {
5986
6126
  disabled: isLoadingFromServer,
@@ -6001,35 +6141,35 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6001
6141
  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",
6002
6142
  style: { height: 56, background: "#7c3aed" },
6003
6143
  children: [
6004
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
6144
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
6005
6145
  isLoadingFromServer ? "Laden\u2026" : "Vom Server laden"
6006
6146
  ]
6007
6147
  }
6008
6148
  ),
6009
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
6149
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
6010
6150
  ] }),
6011
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6012
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
6013
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
6151
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6152
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
6153
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
6014
6154
  { id: "mobile", icon: "smartphone", label: "Mobile" },
6015
6155
  { id: "mobile-desktop", icon: "phonelink", label: "Mobile+" },
6016
6156
  { id: "desktop", icon: "desktop_windows", label: "Desktop" },
6017
6157
  { id: "tablet-landscape", icon: "tablet", label: "Landscape" }
6018
- ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6158
+ ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
6019
6159
  "button",
6020
6160
  {
6021
6161
  onClick: () => startApp(opt.id),
6022
6162
  className: "flex flex-col items-center gap-2 py-4 rounded-2xl border transition-colors",
6023
6163
  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" },
6024
6164
  children: [
6025
- /* @__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 }),
6026
- /* @__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 })
6165
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
6166
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
6027
6167
  ]
6028
6168
  },
6029
6169
  opt.id
6030
6170
  )) }),
6031
- 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" }),
6032
- 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" })
6171
+ layoutChoice === "mobile-desktop" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
6172
+ layoutChoice === "tablet-landscape" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
6033
6173
  ] })
6034
6174
  ] });
6035
6175
  }
@@ -6038,22 +6178,22 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6038
6178
  const mdScale = mdMode ? window.innerWidth / 430 : 1;
6039
6179
  const mdW = mdMode ? 430 : void 0;
6040
6180
  const mdH = mdMode ? Math.ceil(window.innerHeight / mdScale) : void 0;
6041
- const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
6181
+ const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
6042
6182
  width: mdMode ? mdW : "100vw",
6043
6183
  height: mdMode ? mdH : "100dvh",
6044
6184
  transform: mdMode ? `scale(${mdScale})` : void 0,
6045
6185
  transformOrigin: mdMode ? "top left" : void 0,
6046
6186
  ...hcStyle || {}
6047
6187
  }, children: [
6048
- 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) => {
6188
+ mobileTab === "labs" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LabsTab, { services: labServices, onResult: (item) => {
6049
6189
  const frame = item.frames[0];
6050
6190
  if (frame?.base64) {
6051
6191
  setCurrentResult(frameToGeneration(frame, item));
6052
6192
  setMobileTab("stage");
6053
6193
  }
6054
6194
  } }) }),
6055
- mobileTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl }) }),
6056
- 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)(
6195
+ mobileTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ServerTab, { serverBaseUrl }) }),
6196
+ mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6057
6197
  TagManagerPanel,
6058
6198
  {
6059
6199
  workspaceTags,
@@ -6064,23 +6204,23 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6064
6204
  onTagMove: handleTagMove
6065
6205
  }
6066
6206
  ) }),
6067
- mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
6068
- /* @__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: [
6069
- /* @__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" }] }),
6070
- /* @__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" }] }),
6071
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6072
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1" }),
6207
+ mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
6208
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
6209
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6210
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6211
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6212
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1" }),
6073
6213
  runningBadge,
6074
- 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: [
6075
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6076
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6077
- /* @__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" }) })
6078
- ] }) : /* @__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" }) }),
6079
- /* @__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" }) }),
6080
- /* @__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" }) })
6214
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6215
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6216
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6217
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6218
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
6219
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
6220
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
6081
6221
  ] }),
6082
- /* @__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: [
6083
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6222
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
6223
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6084
6224
  "textarea",
6085
6225
  {
6086
6226
  value: activePrompt,
@@ -6090,9 +6230,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6090
6230
  placeholder: "Prompt eingeben..."
6091
6231
  }
6092
6232
  ),
6093
- 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" }) })
6233
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
6094
6234
  ] }) }),
6095
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6235
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
6096
6236
  "button",
6097
6237
  {
6098
6238
  onClick: () => handleGenerateBatch(),
@@ -6100,13 +6240,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6100
6240
  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",
6101
6241
  style: { height: 48, background: activePrompt.trim() ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
6102
6242
  children: [
6103
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
6104
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
6243
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
6244
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Generieren" })
6105
6245
  ]
6106
6246
  }
6107
6247
  ) }),
6108
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
6109
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6248
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
6249
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
6110
6250
  "div",
6111
6251
  {
6112
6252
  className: "w-full rounded-2xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center",
@@ -6120,25 +6260,25 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6120
6260
  setTouchStartX(null);
6121
6261
  },
6122
6262
  children: [
6123
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6124
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6125
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6263
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6264
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6265
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6126
6266
  ] }),
6127
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6128
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
6129
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
6130
- /* @__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" })
6267
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6268
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
6269
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
6270
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" })
6131
6271
  ] }),
6132
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6133
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6134
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
6135
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6272
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6273
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6274
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
6275
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6136
6276
  ] }),
6137
- 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" }) }),
6138
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6139
- /* @__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" }) }),
6140
- /* @__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" }) }),
6141
- /* @__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: [
6277
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
6278
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
6279
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6280
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
6281
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6142
6282
  currentIndex + 1,
6143
6283
  " / ",
6144
6284
  history.length
@@ -6147,8 +6287,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6147
6287
  ]
6148
6288
  }
6149
6289
  ),
6150
- currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
6151
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6290
+ currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
6291
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6152
6292
  "div",
6153
6293
  {
6154
6294
  onClick: () => handleGallerySelect(item),
@@ -6161,10 +6301,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6161
6301
  border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
6162
6302
  opacity: item.id === currentResult.id ? 1 : 0.55
6163
6303
  },
6164
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
6304
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
6165
6305
  }
6166
6306
  ),
6167
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6307
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6168
6308
  "button",
6169
6309
  {
6170
6310
  onClick: (e) => {
@@ -6186,34 +6326,34 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6186
6326
  alignItems: "center",
6187
6327
  justifyContent: "center"
6188
6328
  },
6189
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
6329
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
6190
6330
  }
6191
6331
  )
6192
6332
  ] }, item.id)) }),
6193
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 mt-3", children: [
6194
- /* @__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: [
6195
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
6196
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
6333
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2 mt-3", children: [
6334
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6335
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
6336
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
6197
6337
  ] }),
6198
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(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: [
6199
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
6200
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
6338
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("button", { onClick: () => handleGenerateBatch(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: [
6339
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
6340
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
6201
6341
  ] }),
6202
- /* @__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: [
6203
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
6204
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
6342
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6343
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
6344
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
6205
6345
  ] })
6206
6346
  ] })
6207
6347
  ] })
6208
6348
  ] }),
6209
- mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
6210
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6211
- ["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)),
6212
- 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" }) })
6349
+ mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
6350
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6351
+ ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
6352
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
6213
6353
  ] }),
6214
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6215
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6216
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6354
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6355
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6356
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6217
6357
  MediaLibrary,
6218
6358
  {
6219
6359
  items: galleryItems,
@@ -6232,44 +6372,44 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6232
6372
  onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
6233
6373
  }
6234
6374
  ),
6235
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
6375
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
6236
6376
  setCurrentResult(g);
6237
6377
  } })
6238
6378
  ] })
6239
6379
  ] }),
6240
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
6241
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6242
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => {
6380
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
6381
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6382
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("button", { onClick: () => {
6243
6383
  setLeftTab("prompt");
6244
6384
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
6245
6385
  }, 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: [
6246
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
6386
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
6247
6387
  "Prompt"
6248
6388
  ] }),
6249
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => {
6389
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("button", { onClick: () => {
6250
6390
  setLeftTab("hierarchy");
6251
6391
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
6252
6392
  }, 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: [
6253
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
6393
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
6254
6394
  "Hierarchie"
6255
6395
  ] }),
6256
- /* @__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: [
6257
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
6396
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6397
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
6258
6398
  "Setup"
6259
6399
  ] }),
6260
- /* @__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: [
6261
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
6400
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6401
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
6262
6402
  "Sync"
6263
6403
  ] }),
6264
- /* @__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: [
6265
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
6404
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6405
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
6266
6406
  "HF"
6267
6407
  ] }),
6268
- serverBaseUrl && /* @__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" }) }),
6269
- 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" }) })
6408
+ serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
6409
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
6270
6410
  ] }),
6271
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6272
- 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)(
6411
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6412
+ leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6273
6413
  ListView,
6274
6414
  {
6275
6415
  nodes,
@@ -6300,12 +6440,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6300
6440
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
6301
6441
  }
6302
6442
  ) }),
6303
- 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) => {
6443
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
6304
6444
  handleGenerateBatch(prompt);
6305
6445
  setMobileTab("stage");
6306
6446
  }, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
6307
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6308
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6447
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6448
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6309
6449
  ProjectSyncTab,
6310
6450
  {
6311
6451
  topSlot: syncTopSlot,
@@ -6329,7 +6469,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6329
6469
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
6330
6470
  }
6331
6471
  ),
6332
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6472
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6333
6473
  TagManagerPanel,
6334
6474
  {
6335
6475
  workspaceTags,
@@ -6340,7 +6480,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6340
6480
  onTagMove: handleTagMove
6341
6481
  }
6342
6482
  ),
6343
- activeTab === "hftest" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6483
+ activeTab === "hftest" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6344
6484
  HFTestTab,
6345
6485
  {
6346
6486
  token: hfToken,
@@ -6352,23 +6492,23 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6352
6492
  missingImages: hfMissingImages
6353
6493
  }
6354
6494
  ) }),
6355
- activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl }) })
6495
+ activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ServerTab, { serverBaseUrl }) })
6356
6496
  ] })
6357
6497
  ] }),
6358
- /* @__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: [
6498
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
6359
6499
  { id: "tools", icon: "auto_fix_high", label: "Prompt" },
6360
6500
  { id: "stage", icon: "palette", label: "Stage" },
6361
6501
  { id: "labs", icon: "science", label: "Labs" },
6362
6502
  ...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
6363
6503
  { id: "browse", icon: "photo_library", label: "Galerie" },
6364
6504
  ...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
6365
- ].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: [
6366
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
6367
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
6505
+ ].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6506
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
6507
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
6368
6508
  ] }, tab.id)) })
6369
6509
  ] });
6370
6510
  if (mdMode) {
6371
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
6511
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
6372
6512
  }
6373
6513
  return mobileRoot;
6374
6514
  }
@@ -6376,19 +6516,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6376
6516
  const tlScale = Math.min(window.innerWidth / 920, window.innerHeight / 520);
6377
6517
  const tlW = 920;
6378
6518
  const tlH = 520;
6379
- 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: [
6380
- /* @__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: [
6381
- /* @__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: [
6382
- /* @__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" }] }),
6383
- /* @__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" }] }),
6384
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6385
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1 } }),
6519
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
6520
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6521
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6522
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6523
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6524
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6525
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { flex: 1 } }),
6386
6526
  runningBadge,
6387
- /* @__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" }) }),
6388
- /* @__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" }) })
6527
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
6528
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
6389
6529
  ] }),
6390
- /* @__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: [
6391
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6530
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6531
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6392
6532
  "textarea",
6393
6533
  {
6394
6534
  value: activePrompt,
@@ -6397,24 +6537,24 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6397
6537
  placeholder: "Prompt eingeben..."
6398
6538
  }
6399
6539
  ),
6400
- 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" }) })
6540
+ activePrompt && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
6401
6541
  ] }) }),
6402
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6542
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
6403
6543
  "button",
6404
6544
  {
6405
6545
  onClick: () => handleGenerateBatch(),
6406
6546
  disabled: !activePrompt.trim(),
6407
6547
  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() ? "#0284c7" : "transparent", color: "#fff", cursor: activePrompt.trim() ? "pointer" : "default", opacity: !activePrompt.trim() ? 0.3 : 1, fontFamily: "inherit", transition: "background 0.2s" },
6408
6548
  children: [
6409
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
6410
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
6549
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
6550
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Generieren" })
6411
6551
  ]
6412
6552
  }
6413
6553
  ) }),
6414
- /* @__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: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
6554
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
6415
6555
  ] }),
6416
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
6417
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6556
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
6557
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6418
6558
  "div",
6419
6559
  {
6420
6560
  style: { flex: 1, padding: 16, display: "flex", alignItems: "center", justifyContent: "center", position: "relative" },
@@ -6426,26 +6566,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6426
6566
  else if (dx > 50) goToPrev();
6427
6567
  setTouchStartX(null);
6428
6568
  },
6429
- 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: [
6430
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
6431
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
6432
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6569
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6570
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
6571
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
6572
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6433
6573
  ] }),
6434
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6435
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
6436
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
6437
- /* @__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" })
6574
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6575
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
6576
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
6577
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" })
6438
6578
  ] }),
6439
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
6440
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
6441
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
6442
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
6579
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
6580
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
6581
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
6582
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
6443
6583
  ] }),
6444
- 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" }) }),
6445
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6446
- /* @__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" }) }),
6447
- /* @__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" }) }),
6448
- /* @__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: [
6584
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
6585
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
6586
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
6587
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
6588
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6449
6589
  currentIndex + 1,
6450
6590
  " / ",
6451
6591
  history.length
@@ -6454,42 +6594,42 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6454
6594
  ] })
6455
6595
  }
6456
6596
  ),
6457
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
6458
- /* @__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: [
6459
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
6460
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Prompt" })
6597
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
6598
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6599
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
6600
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Prompt" })
6461
6601
  ] }),
6462
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(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: [
6463
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
6464
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Referenz" })
6602
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("button", { onClick: () => handleGenerateBatch(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: [
6603
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
6604
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Referenz" })
6465
6605
  ] }),
6466
- /* @__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: [
6467
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
6468
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Laden" })
6606
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6607
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
6608
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Laden" })
6469
6609
  ] })
6470
6610
  ] })
6471
6611
  ] })
6472
6612
  ] }) });
6473
6613
  }
6474
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
6475
- /* @__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" }) }),
6476
- /* @__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: [
6477
- /* @__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: [
6478
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-1 gap-1", children: [
6479
- 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: [
6480
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
6614
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
6615
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
6616
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6617
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
6618
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-1 gap-1", children: [
6619
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6620
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
6481
6621
  "Prompt"
6482
6622
  ] }),
6483
- /* @__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: [
6484
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
6623
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6624
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
6485
6625
  "Hierarchie"
6486
6626
  ] }),
6487
- 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" }) })
6627
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
6488
6628
  ] }),
6489
- /* @__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" })
6629
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" })
6490
6630
  ] }),
6491
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6492
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6631
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6632
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6493
6633
  TagManagerPanel,
6494
6634
  {
6495
6635
  workspaceTags,
@@ -6500,11 +6640,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6500
6640
  onTagMove: handleTagMove
6501
6641
  }
6502
6642
  ),
6503
- 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: [
6504
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6505
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6643
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
6644
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6645
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6506
6646
  ] }) }),
6507
- leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6647
+ leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6508
6648
  ListView,
6509
6649
  {
6510
6650
  nodes,
@@ -6529,19 +6669,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6529
6669
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
6530
6670
  }
6531
6671
  ) }),
6532
- 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) => handleGenerateBatch(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
6672
+ leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateBatch(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
6533
6673
  ] })
6534
6674
  ] }),
6535
- !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" } }),
6536
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
6537
- /* @__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: [
6538
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1.5", children: [
6539
- /* @__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" }] }),
6540
- /* @__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" }] }),
6541
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
6675
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.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" } }),
6676
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
6677
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6678
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-1.5", children: [
6679
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6680
+ /* @__PURE__ */ (0, import_jsx_runtime24.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" }] }),
6681
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
6542
6682
  ] }),
6543
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
6544
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6683
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
6684
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6545
6685
  "button",
6546
6686
  {
6547
6687
  onClick: () => setMiddlePanel("stage"),
@@ -6549,7 +6689,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6549
6689
  children: "Stage"
6550
6690
  }
6551
6691
  ),
6552
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6692
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6553
6693
  "button",
6554
6694
  {
6555
6695
  onClick: () => setMiddlePanel("labs"),
@@ -6558,52 +6698,52 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6558
6698
  }
6559
6699
  )
6560
6700
  ] }),
6561
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
6562
- 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: [
6563
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6564
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6565
- /* @__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" }) })
6566
- ] }) : /* @__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: [
6567
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
6568
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Ref" })
6701
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
6702
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
6703
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6704
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6705
+ /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6706
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6707
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
6708
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Ref" })
6569
6709
  ] }),
6570
- /* @__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" }) }),
6710
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
6571
6711
  runningBadge,
6572
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
6712
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
6573
6713
  ] })
6574
6714
  ] }),
6575
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
6576
- !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: [
6577
- /* @__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..." }),
6578
- 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" }) })
6715
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
6716
+ !isPromptCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
6717
+ /* @__PURE__ */ (0, import_jsx_runtime24.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..." }),
6718
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6579
6719
  ] }) }),
6580
- 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) => {
6720
+ middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LabsTab, { services: labServices, onResult: (item) => {
6581
6721
  const frame = item.frames[0];
6582
6722
  if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
6583
- } }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
6584
- /* @__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.jsx)("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: currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
6585
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6586
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6587
- ] }) : 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: [
6588
- /* @__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" }) }),
6589
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
6590
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
6591
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
6723
+ } }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
6724
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("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: currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
6725
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6726
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6727
+ ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
6728
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
6729
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-2", children: [
6730
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
6731
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
6592
6732
  ] }),
6593
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
6594
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
6595
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
6596
- /* @__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: [
6597
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
6598
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
6599
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
6733
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
6734
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
6735
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
6736
+ /* @__PURE__ */ (0, import_jsx_runtime24.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: [
6737
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
6738
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
6739
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
6600
6740
  ] })
6601
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6602
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
6603
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6741
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6742
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
6743
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6604
6744
  ] }) }) }),
6605
- currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
6606
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6745
+ currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
6746
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6607
6747
  "div",
6608
6748
  {
6609
6749
  onClick: () => handleGallerySelect(item),
@@ -6618,10 +6758,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6618
6758
  transition: "opacity 0.15s, border-color 0.15s"
6619
6759
  },
6620
6760
  className: "hover:opacity-80",
6621
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
6761
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
6622
6762
  }
6623
6763
  ),
6624
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6764
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6625
6765
  "button",
6626
6766
  {
6627
6767
  onClick: (e) => {
@@ -6644,31 +6784,31 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6644
6784
  alignItems: "center",
6645
6785
  justifyContent: "center"
6646
6786
  },
6647
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
6787
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
6648
6788
  }
6649
6789
  )
6650
6790
  ] }, item.id)) })
6651
6791
  ] })
6652
6792
  ] })
6653
6793
  ] }),
6654
- !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" } }),
6655
- /* @__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: [
6656
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
6657
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-1", children: [
6658
- ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
6794
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.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" } }),
6795
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
6796
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
6797
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-1", children: [
6798
+ ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => {
6659
6799
  setActiveTab(tab);
6660
6800
  setIsRightCollapsed(false);
6661
- }, 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" : "label" }) }, tab)),
6662
- serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
6801
+ }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime24.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)),
6802
+ serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => {
6663
6803
  setActiveTab("server");
6664
6804
  setIsRightCollapsed(false);
6665
- }, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
6805
+ }, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
6666
6806
  ] }),
6667
- 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" }) }),
6668
- /* @__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" }) })
6807
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime24.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_runtime24.jsx)("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
6808
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
6669
6809
  ] }),
6670
- !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6671
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6810
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6811
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6672
6812
  TagManagerPanel,
6673
6813
  {
6674
6814
  workspaceTags,
@@ -6679,12 +6819,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6679
6819
  onTagMove: handleTagMove
6680
6820
  }
6681
6821
  ),
6682
- 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: [
6683
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6684
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6822
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
6823
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6824
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6685
6825
  ] }) }),
6686
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6687
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6826
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6827
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6688
6828
  MediaLibrary,
6689
6829
  {
6690
6830
  items: galleryItems,
@@ -6700,9 +6840,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6700
6840
  onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
6701
6841
  }
6702
6842
  ),
6703
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
6704
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6705
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6843
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
6844
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
6845
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6706
6846
  ProjectSyncTab,
6707
6847
  {
6708
6848
  topSlot: syncTopSlot,
@@ -6726,15 +6866,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6726
6866
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
6727
6867
  }
6728
6868
  ),
6729
- activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl })
6869
+ activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ServerTab, { serverBaseUrl })
6730
6870
  ] })
6731
6871
  ] })
6732
6872
  ] });
6733
6873
  }
6734
6874
 
6735
6875
  // src/components/FaApp.tsx
6736
- var import_react26 = require("react");
6737
- var import_jsx_runtime24 = require("react/jsx-runtime");
6876
+ var import_react27 = require("react");
6877
+ var import_jsx_runtime25 = require("react/jsx-runtime");
6738
6878
  function FaApp({
6739
6879
  onGenerateImage,
6740
6880
  onGeneratePrompt,
@@ -6753,8 +6893,8 @@ function FaApp({
6753
6893
  onServerDelete,
6754
6894
  buildInfo
6755
6895
  }) {
6756
- const [hfNamespace, setHfNamespace] = (0, import_react26.useState)(void 0);
6757
- (0, import_react26.useEffect)(() => {
6896
+ const [hfNamespace, setHfNamespace] = (0, import_react27.useState)(void 0);
6897
+ (0, import_react27.useEffect)(() => {
6758
6898
  if (!serverBaseUrl) return;
6759
6899
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
6760
6900
  if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
@@ -6765,7 +6905,7 @@ function FaApp({
6765
6905
  const result = await onGeneratePrompt(text, options);
6766
6906
  return result.text;
6767
6907
  };
6768
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6908
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6769
6909
  AvatarArchitectApp,
6770
6910
  {
6771
6911
  onGenerateImage,
@@ -6788,7 +6928,7 @@ function FaApp({
6788
6928
  // src/index.ts
6789
6929
  init_hfStateService();
6790
6930
  init_hfStateService();
6791
- var LIB_VERSION = "2.0.61";
6931
+ var LIB_VERSION = "2.0.62";
6792
6932
  // Annotate the CommonJS export names for ESM import in node:
6793
6933
  0 && (module.exports = {
6794
6934
  AvatarArchitectApp,