@rslsp1/fa-app-tools 10.3.3 → 10.3.5

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.mjs CHANGED
@@ -22,7 +22,7 @@ import "./chunk-FUY2OCVC.mjs";
22
22
  import "./chunk-GKLCL2VQ.mjs";
23
23
 
24
24
  // package.json
25
- var version = "10.3.3";
25
+ var version = "10.3.5";
26
26
 
27
27
  // src/hooks/useOnClickOutside.ts
28
28
  import { useEffect } from "react";
@@ -1549,7 +1549,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
1549
1549
  }
1550
1550
 
1551
1551
  // src/components/AvatarArchitectApp.tsx
1552
- import { useState as useState26, useCallback as useCallback4, useMemo as useMemo7, useEffect as useEffect11, useRef as useRef10 } from "react";
1552
+ import { useState as useState27, useCallback as useCallback4, useMemo as useMemo8, useEffect as useEffect12, useRef as useRef11 } from "react";
1553
1553
 
1554
1554
  // src/components/PromptTab.tsx
1555
1555
  import { useRef as useRef5, useState as useState8 } from "react";
@@ -5465,7 +5465,7 @@ import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs26 } from "react/jsx-r
5465
5465
  function FlowWorkspacePicker({
5466
5466
  tagBase,
5467
5467
  selectedUserId,
5468
- message,
5468
+ message: message3,
5469
5469
  onSelectUser,
5470
5470
  onSelectContext
5471
5471
  }) {
@@ -5489,7 +5489,7 @@ function FlowWorkspacePicker({
5489
5489
  /* @__PURE__ */ jsx28("strong", { children: "FineArt Flow" }),
5490
5490
  /* @__PURE__ */ jsx28("small", { children: step === "user" ? "Benutzer w\xE4hlen" : `Kontext f\xFCr ${selectedUser?.username ?? `User ${selectedUserId}`}` })
5491
5491
  ] }),
5492
- message && /* @__PURE__ */ jsx28("p", { className: "flow-workspace-picker__warning", children: message }),
5492
+ message3 && /* @__PURE__ */ jsx28("p", { className: "flow-workspace-picker__warning", children: message3 }),
5493
5493
  step === "user" ? /* @__PURE__ */ jsxs26("div", { className: "flow-workspace-picker__choices", "aria-label": "Benutzer w\xE4hlen", children: [
5494
5494
  tagBase.users.map((user) => /* @__PURE__ */ jsxs26("button", { type: "button", onClick: () => chooseUser(user.id), children: [
5495
5495
  /* @__PURE__ */ jsx28("span", { children: user.username }),
@@ -5538,6 +5538,7 @@ var FLOW_BRIDGE_REQUEST_EVENT = "fine-art-flow-bridge:request:v1";
5538
5538
  var FLOW_BRIDGE_RESPONSE_EVENT = "fine-art-flow-bridge:response:v1";
5539
5539
  var FLOW_BRIDGE_HELLO_TIMEOUT_MS = 1500;
5540
5540
  var FLOW_BRIDGE_REQUEST_TIMEOUT_MS = 15e3;
5541
+ var FLOW_BRIDGE_CONNECT_TIMEOUT_MS = 3e5;
5541
5542
  function isRecord(value) {
5542
5543
  return value !== null && typeof value === "object" && !Array.isArray(value);
5543
5544
  }
@@ -5604,12 +5605,23 @@ function createFlowBridgeClient({
5604
5605
  }
5605
5606
  return { available: true, name: bridge.name, version: bridge.version, protocol: bridge.protocol, roundTripMs };
5606
5607
  },
5607
- async request(request) {
5608
+ async connect(env, { timeoutMs = FLOW_BRIDGE_CONNECT_TIMEOUT_MS } = {}) {
5608
5609
  const started = clock();
5609
- const reply = await exchange({ op: "request", target: request.target, method: request.method, path: request.path }, requestTimeoutMs);
5610
+ const reply = await exchange({ op: "connect", env }, timeoutMs);
5611
+ const waitedMs = Math.round(clock() - started);
5612
+ if (!reply) {
5613
+ return { ok: false, error: { code: "no-bridge", message: `Keine Freigabe innerhalb von ${Math.round(timeoutMs / 1e3)} s \u2014 Extension fehlt, Frame nicht freigegeben oder Popup nicht bestaetigt.` }, waitedMs };
5614
+ }
5615
+ if (reply.ok !== true || reply.env !== env || typeof reply.server !== "string") return { ok: false, error: readError(reply.error), waitedMs };
5616
+ return { ok: true, env, server: reply.server, waitedMs };
5617
+ },
5618
+ async request(request, { timeoutMs = requestTimeoutMs } = {}) {
5619
+ const started = clock();
5620
+ const tokenSuffix = "tokenSuffix" in request && request.tokenSuffix !== void 0 ? { tokenSuffix: request.tokenSuffix } : {};
5621
+ const reply = await exchange({ op: "request", target: request.target, method: request.method, path: request.path, ...tokenSuffix }, timeoutMs);
5610
5622
  const roundTripMs = Math.round(clock() - started);
5611
5623
  if (!reply) {
5612
- return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(requestTimeoutMs) };
5624
+ return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(timeoutMs) };
5613
5625
  }
5614
5626
  const ok = reply.ok === true;
5615
5627
  return {
@@ -5625,13 +5637,130 @@ function createFlowBridgeClient({
5625
5637
  };
5626
5638
  }
5627
5639
 
5640
+ // src/lib/flowProbeLoader.ts
5641
+ var FLOW_PROBE_REQUEST = { target: "devMcp", method: "GET", path: "/flow-app/probe-bundle" };
5642
+ var HF_TOKEN_SUFFIX_CHARS = 8;
5643
+ var FLOW_PROBE_MARKER = "__faFlowProbe";
5644
+ var FLOW_PROBE_METHOD = "script-blob";
5645
+ var FLOW_PROBE_LOAD_TIMEOUT_MS = 5e3;
5646
+ var CSP_SETTLE_MS = 100;
5647
+ function isRecord2(value) {
5648
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5649
+ }
5650
+ function hfTokenSuffix(token) {
5651
+ const trimmed = (token ?? "").trim();
5652
+ return trimmed.length >= HF_TOKEN_SUFFIX_CHARS ? trimmed.slice(-HF_TOKEN_SUFFIX_CHARS) : null;
5653
+ }
5654
+ function readFlowProbeBundle(data) {
5655
+ if (!isRecord2(data)) return null;
5656
+ const { version: version2, sha256, source } = data;
5657
+ if (typeof version2 !== "string" || !/^probe-\d{3}$/.test(version2)) return null;
5658
+ if (typeof sha256 !== "string" || !/^[0-9a-f]{64}$/.test(sha256)) return null;
5659
+ if (typeof source !== "string" || source.length === 0) return null;
5660
+ return { version: version2, sha256, source };
5661
+ }
5662
+ function readMarker(value) {
5663
+ if (!isRecord2(value) || value.executed !== true || typeof value.version !== "string") return null;
5664
+ return { executed: true, version: value.version, executedAt: typeof value.executedAt === "string" ? value.executedAt : null };
5665
+ }
5666
+ async function sha256Hex(text) {
5667
+ if (!globalThis.crypto?.subtle) throw new Error("crypto.subtle ist in diesem Kontext nicht verfuegbar.");
5668
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
5669
+ return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
5670
+ }
5671
+ var message = (error) => error instanceof Error ? error.message : String(error);
5672
+ var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5673
+ async function executeFlowProbeBundle(bundle, {
5674
+ win = window,
5675
+ doc = document,
5676
+ timeoutMs = FLOW_PROBE_LOAD_TIMEOUT_MS,
5677
+ digest = sha256Hex
5678
+ } = {}) {
5679
+ const markerHost = win;
5680
+ const result = {
5681
+ method: FLOW_PROBE_METHOD,
5682
+ pageOrigin: win.location.origin,
5683
+ hash: { expected: bundle.sha256, actual: null, matches: null, error: null },
5684
+ scriptEvent: "not-started",
5685
+ marker: null,
5686
+ executed: false,
5687
+ cspViolations: [],
5688
+ error: null
5689
+ };
5690
+ try {
5691
+ result.hash.actual = await digest(bundle.source);
5692
+ result.hash.matches = result.hash.actual === bundle.sha256;
5693
+ } catch (error) {
5694
+ result.hash.error = message(error);
5695
+ }
5696
+ if (result.hash.matches === false) {
5697
+ result.error = "SHA-256 des empfangenen Quelltexts weicht ab \u2014 Bundle nicht ausgefuehrt.";
5698
+ return result;
5699
+ }
5700
+ delete markerHost[FLOW_PROBE_MARKER];
5701
+ const onViolation = (event) => {
5702
+ const violation = event;
5703
+ result.cspViolations.push(`${violation.effectiveDirective || violation.violatedDirective}: ${violation.blockedURI || "unbekannt"}`);
5704
+ };
5705
+ doc.addEventListener("securitypolicyviolation", onViolation);
5706
+ let url = null;
5707
+ let script = null;
5708
+ try {
5709
+ url = URL.createObjectURL(new Blob([bundle.source], { type: "text/javascript" }));
5710
+ const element = doc.createElement("script");
5711
+ script = element;
5712
+ result.scriptEvent = await new Promise((resolve) => {
5713
+ const timer = setTimeout(() => resolve("timeout"), timeoutMs);
5714
+ element.addEventListener("load", () => {
5715
+ clearTimeout(timer);
5716
+ resolve("load");
5717
+ });
5718
+ element.addEventListener("error", () => {
5719
+ clearTimeout(timer);
5720
+ resolve("error");
5721
+ });
5722
+ element.src = url;
5723
+ (doc.head ?? doc.documentElement).appendChild(element);
5724
+ });
5725
+ } catch (error) {
5726
+ result.error = `Skript nicht einfuegbar: ${message(error)}`;
5727
+ }
5728
+ result.marker = readMarker(markerHost[FLOW_PROBE_MARKER]);
5729
+ result.executed = result.marker !== null && result.marker.version === bundle.version;
5730
+ if (!result.executed) await wait(CSP_SETTLE_MS);
5731
+ doc.removeEventListener("securitypolicyviolation", onViolation);
5732
+ script?.remove();
5733
+ if (url) URL.revokeObjectURL(url);
5734
+ if (!result.executed && !result.error) {
5735
+ if (result.marker) result.error = `Marker meldet Version ${result.marker.version}, erwartet ${bundle.version}.`;
5736
+ else if (result.scriptEvent === "load") result.error = "script.onload ohne Marker \u2014 Ausfuehrung nicht belegt.";
5737
+ else if (result.scriptEvent === "error") result.error = "script.onerror \u2014 Skript nicht geladen oder blockiert.";
5738
+ else result.error = `Kein Skript-Ereignis innerhalb von ${timeoutMs} ms.`;
5739
+ }
5740
+ return result;
5741
+ }
5742
+
5628
5743
  // src/components/FlowBridgePanel.tsx
5629
- import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5744
+ import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5630
5745
  var STATUS_REQUEST = { target: "dev", method: "GET", path: "/api/status" };
5631
- var FlowBridgePanel = ({ appVersion, client }) => {
5746
+ function hashText(execution) {
5747
+ if (execution.hash.matches === true) return "Hash gepr\xFCft";
5748
+ if (execution.hash.matches === false) return `Hash ABWEICHEND (berechnet ${execution.hash.actual?.slice(0, 12)}\u2026)`;
5749
+ return `Hash nicht pr\xFCfbar (${execution.hash.error})`;
5750
+ }
5751
+ function probeVerdict(run) {
5752
+ if (run.execution?.executed) return { ok: true, text: `ERGEBNIS: ausgef\xFChrt (executed: true, ${run.execution.marker?.version})` };
5753
+ if (!run.response.ok) {
5754
+ return { ok: false, text: `ERGEBNIS: nicht ausgef\xFChrt \u2014 ${run.response.error?.code === "no-hf-token" ? "kein HF-Token in FlowFA." : "Bundle nicht \xFCber die Bridge erhalten."}` };
5755
+ }
5756
+ if (!run.bundle) return { ok: false, text: "ERGEBNIS: nicht ausgef\xFChrt \u2014 Antwort ohne g\xFCltiges Bundle." };
5757
+ return { ok: false, text: `ERGEBNIS: nicht ausgef\xFChrt \u2014 ${run.execution?.error}` };
5758
+ }
5759
+ var FlowBridgePanel = ({ appVersion, client, hfToken }) => {
5632
5760
  const bridge = useMemo6(() => client ?? createFlowBridgeClient({ appVersion }), [client, appVersion]);
5633
5761
  const [status, setStatus] = useState25(null);
5634
5762
  const [response, setResponse] = useState25(null);
5763
+ const [probe, setProbe] = useState25(null);
5635
5764
  const [busy, setBusy] = useState25(null);
5636
5765
  const checkStatus = async () => {
5637
5766
  setBusy("status");
@@ -5659,6 +5788,35 @@ var FlowBridgePanel = ({ appVersion, client }) => {
5659
5788
  setBusy(null);
5660
5789
  }
5661
5790
  };
5791
+ const runProbe = async () => {
5792
+ setBusy("probe");
5793
+ setProbe(null);
5794
+ try {
5795
+ const tokenSuffix = hfTokenSuffix(hfToken);
5796
+ if (!tokenSuffix) {
5797
+ setProbe({
5798
+ response: {
5799
+ ok: false,
5800
+ transport: null,
5801
+ status: null,
5802
+ data: null,
5803
+ latencyMs: null,
5804
+ roundTripMs: 0,
5805
+ error: { code: "no-hf-token", message: "Kein HF-Token in FlowFA gesetzt \u2014 ohne ihn kein Zugang zum Dev-MCP-Host." }
5806
+ },
5807
+ bundle: null,
5808
+ execution: null
5809
+ });
5810
+ return;
5811
+ }
5812
+ const response2 = await bridge.request({ ...FLOW_PROBE_REQUEST, tokenSuffix });
5813
+ const bundle = response2.ok ? readFlowProbeBundle(response2.data) : null;
5814
+ const execution = bundle ? await executeFlowProbeBundle(bundle) : null;
5815
+ setProbe({ response: response2, bundle, execution });
5816
+ } finally {
5817
+ setBusy(null);
5818
+ }
5819
+ };
5662
5820
  const buttonStyle = {
5663
5821
  height: 36,
5664
5822
  border: "1px solid rgba(255,255,255,0.12)",
@@ -5672,6 +5830,7 @@ var FlowBridgePanel = ({ appVersion, client }) => {
5672
5830
  /* @__PURE__ */ jsx29("button", { type: "button", onClick: checkStatus, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "status" ? "Pr\xFCfe\u2026" : "Bridge pr\xFCfen" }),
5673
5831
  /* @__PURE__ */ jsx29("button", { type: "button", onClick: runRequest, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "request" ? "L\xE4uft\u2026" : "Dev /api/status" })
5674
5832
  ] }),
5833
+ /* @__PURE__ */ jsx29("button", { type: "button", onClick: runProbe, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "probe" ? "L\xE4uft\u2026" : "Mini-Bundle laden & ausf\xFChren" }),
5675
5834
  status && /* @__PURE__ */ jsx29("div", { role: "status", "data-testid": "flow-bridge-status", style: { color: status.available ? "#4ade80" : "#f87171" }, children: status.available ? `Bridge: verbunden \xB7 ${status.name} v${status.version} \xB7 Protokoll ${status.protocol} \xB7 ${status.roundTripMs} ms` : `Bridge: nicht verbunden \xB7 ${status.error.code}: ${status.error.message}` }),
5676
5835
  response && /* @__PURE__ */ jsxs27("div", { "data-testid": "flow-bridge-response", className: "flex flex-col gap-1", children: [
5677
5836
  /* @__PURE__ */ jsxs27("span", { style: { color: response.ok ? "#4ade80" : "#f87171" }, children: [
@@ -5681,11 +5840,258 @@ var FlowBridgePanel = ({ appVersion, client }) => {
5681
5840
  ] }),
5682
5841
  /* @__PURE__ */ jsx29("span", { className: "text-white/40", children: `Transport: ${response.transport ?? "keiner"} \xB7 Server ${response.latencyMs ?? "\u2014"} ms \xB7 gesamt ${response.roundTripMs} ms` }),
5683
5842
  response.ok && /* @__PURE__ */ jsx29("pre", { className: "text-white/60 whitespace-pre-wrap break-all bg-black/30 rounded-lg p-2", children: JSON.stringify(response.data, null, 2) })
5843
+ ] }),
5844
+ probe && /* @__PURE__ */ jsxs27("div", { "data-testid": "flow-bridge-probe", className: "flex flex-col gap-1", children: [
5845
+ /* @__PURE__ */ jsxs27("span", { style: { color: probe.response.ok ? "#4ade80" : "#f87171" }, children: [
5846
+ `${FLOW_PROBE_REQUEST.method} ${FLOW_PROBE_REQUEST.path} (${FLOW_PROBE_REQUEST.target}) \u2192 `,
5847
+ probe.response.status !== null ? `HTTP ${probe.response.status}` : "kein HTTP-Status",
5848
+ probe.response.ok ? "" : ` \xB7 ${probe.response.error?.code}: ${probe.response.error?.message}`
5849
+ ] }),
5850
+ /* @__PURE__ */ jsx29("span", { className: "text-white/40", children: `Transport: ${probe.response.transport ?? "keiner"} \xB7 Server ${probe.response.latencyMs ?? "\u2014"} ms \xB7 gesamt ${probe.response.roundTripMs} ms` }),
5851
+ probe.bundle && /* @__PURE__ */ jsxs27("span", { className: "text-white/60 break-all", children: [
5852
+ `Bundle ${probe.bundle.version} \xB7 ${probe.bundle.source.length} Zeichen \xB7 SHA-256 ${probe.bundle.sha256.slice(0, 12)}\u2026`,
5853
+ probe.execution ? ` \xB7 ${hashText(probe.execution)}` : ""
5854
+ ] }),
5855
+ probe.execution && /* @__PURE__ */ jsxs27(Fragment10, { children: [
5856
+ /* @__PURE__ */ jsx29("span", { className: "text-white/60 break-all", children: `Ausf\xFChrung: <script src=blob:> \xB7 Ereignis ${probe.execution.scriptEvent} \xB7 Seite ${probe.execution.pageOrigin}` }),
5857
+ /* @__PURE__ */ jsx29("span", { className: "text-white/60 break-all", children: `Marker window.${FLOW_PROBE_MARKER}: ${probe.execution.marker ? JSON.stringify(probe.execution.marker) : "fehlt"}` }),
5858
+ /* @__PURE__ */ jsx29("span", { className: "break-all", style: { color: probe.execution.cspViolations.length > 0 ? "#f87171" : "rgba(255,255,255,0.4)" }, children: probe.execution.cspViolations.length > 0 ? `CSP: ${probe.execution.cspViolations.join("; ")}` : "CSP: keine Verletzung gemeldet" })
5859
+ ] }),
5860
+ /* @__PURE__ */ jsx29("span", { "data-testid": "flow-bridge-probe-verdict", className: "font-bold", style: { color: probeVerdict(probe).ok ? "#4ade80" : "#f87171" }, children: probeVerdict(probe).text })
5684
5861
  ] })
5685
5862
  ] })
5686
5863
  ] });
5687
5864
  };
5688
5865
 
5866
+ // src/components/FlowFineArtApp.tsx
5867
+ import { useEffect as useEffect11, useMemo as useMemo7, useRef as useRef10, useState as useState26 } from "react";
5868
+
5869
+ // src/lib/flowAppLoader.ts
5870
+ var FLOW_APP_TARGETS = {
5871
+ dev: { bridgeTarget: "devMcp", backendUrl: "https://dev-app.art-by-rolands.de" },
5872
+ prod: { bridgeTarget: "prodMcp", backendUrl: "https://app.art-by-rolands.de" }
5873
+ };
5874
+ var FLOW_APP_FILES = ["react-runtime.js", "master.css", "app.js"];
5875
+ var FLOW_APP_REQUEST_TIMEOUT_MS = 75e3;
5876
+ var FLOW_APP_SCRIPT_TIMEOUT_MS = 15e3;
5877
+ var CSP_SETTLE_MS2 = 100;
5878
+ function isRecord3(value) {
5879
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5880
+ }
5881
+ function readFlowAppFile(data, file) {
5882
+ if (!isRecord3(data)) return null;
5883
+ const { sha256, source } = data;
5884
+ if (data.file !== file) return null;
5885
+ if (typeof sha256 !== "string" || !/^[0-9a-f]{64}$/.test(sha256)) return null;
5886
+ if (typeof source !== "string" || source.length === 0) return null;
5887
+ return { file, sha256, source };
5888
+ }
5889
+ async function sha256Hex2(text) {
5890
+ if (!globalThis.crypto?.subtle) throw new Error("crypto.subtle ist in diesem Kontext nicht verfuegbar.");
5891
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
5892
+ return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
5893
+ }
5894
+ var message2 = (error) => error instanceof Error ? error.message : String(error);
5895
+ var wait2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5896
+ async function runScriptBlob(source, doc, timeoutMs, step) {
5897
+ const onViolation = (event) => {
5898
+ const violation = event;
5899
+ step.cspViolations.push(`${violation.effectiveDirective || violation.violatedDirective}: ${violation.blockedURI || "unbekannt"}`);
5900
+ };
5901
+ doc.addEventListener("securitypolicyviolation", onViolation);
5902
+ let url = null;
5903
+ let script = null;
5904
+ try {
5905
+ url = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
5906
+ const element = doc.createElement("script");
5907
+ script = element;
5908
+ step.scriptEvent = await new Promise((resolve) => {
5909
+ const timer = setTimeout(() => resolve("timeout"), timeoutMs);
5910
+ element.addEventListener("load", () => {
5911
+ clearTimeout(timer);
5912
+ resolve("load");
5913
+ });
5914
+ element.addEventListener("error", () => {
5915
+ clearTimeout(timer);
5916
+ resolve("error");
5917
+ });
5918
+ element.src = url;
5919
+ (doc.head ?? doc.documentElement).appendChild(element);
5920
+ });
5921
+ } catch (error) {
5922
+ step.error = `Skript nicht einfuegbar: ${message2(error)}`;
5923
+ }
5924
+ if (step.scriptEvent !== "load") await wait2(CSP_SETTLE_MS2);
5925
+ doc.removeEventListener("securitypolicyviolation", onViolation);
5926
+ script?.remove();
5927
+ if (url) URL.revokeObjectURL(url);
5928
+ }
5929
+ function scriptFailure(step, expectation) {
5930
+ if (step.error) return step.error;
5931
+ if (step.scriptEvent === "load") return `script.onload, aber ${expectation} \u2014 Ausfuehrung nicht belegt.`;
5932
+ if (step.scriptEvent === "error") return "script.onerror \u2014 Skript nicht geladen oder blockiert.";
5933
+ return "Kein Skript-Ereignis innerhalb der Wartezeit.";
5934
+ }
5935
+ async function loadFlowApp({
5936
+ bridge,
5937
+ environment,
5938
+ tokenSuffix,
5939
+ win = window,
5940
+ doc = document,
5941
+ digest = sha256Hex2,
5942
+ scriptTimeoutMs = FLOW_APP_SCRIPT_TIMEOUT_MS,
5943
+ onStep
5944
+ }) {
5945
+ const target = FLOW_APP_TARGETS[environment];
5946
+ const globals = win;
5947
+ const steps = [];
5948
+ const report = () => onStep?.(steps.map((step) => ({ ...step, cspViolations: [...step.cspViolations] })));
5949
+ const fail3 = (step, error) => {
5950
+ step.error = error;
5951
+ report();
5952
+ return { ok: false, steps, error: `${step.file}: ${error}` };
5953
+ };
5954
+ let css = "";
5955
+ for (const file of FLOW_APP_FILES) {
5956
+ const step = { file, response: null, chars: null, hash: null, scriptEvent: null, cspViolations: [], error: null };
5957
+ steps.push(step);
5958
+ report();
5959
+ step.response = await bridge.request(
5960
+ { target: target.bridgeTarget, method: "GET", path: `/flow-app/bundle/${file}`, tokenSuffix },
5961
+ { timeoutMs: FLOW_APP_REQUEST_TIMEOUT_MS }
5962
+ );
5963
+ if (!step.response.ok) {
5964
+ const status = step.response.status !== null ? `HTTP ${step.response.status} \xB7 ` : "";
5965
+ return fail3(step, `${status}${step.response.error?.code}: ${step.response.error?.message}`);
5966
+ }
5967
+ const loaded = readFlowAppFile(step.response.data, file);
5968
+ if (!loaded) return fail3(step, "Antwort ohne gueltige Datei.");
5969
+ step.chars = loaded.source.length;
5970
+ try {
5971
+ step.hash = await digest(loaded.source) === loaded.sha256 ? "ok" : "mismatch";
5972
+ } catch {
5973
+ step.hash = "unavailable";
5974
+ }
5975
+ if (step.hash === "mismatch") return fail3(step, "SHA-256 des empfangenen Quelltexts weicht ab \u2014 nicht ausgefuehrt.");
5976
+ if (file === "master.css") {
5977
+ css = loaded.source;
5978
+ report();
5979
+ continue;
5980
+ }
5981
+ if (file === "app.js") delete globals.FineArtApp;
5982
+ await runScriptBlob(loaded.source, doc, scriptTimeoutMs, step);
5983
+ if (file === "react-runtime.js") {
5984
+ const ReactDOM = globals.ReactDOM;
5985
+ if (!isRecord3(globals.React) || typeof ReactDOM?.createRoot !== "function") {
5986
+ return fail3(step, scriptFailure(step, "window.React/window.ReactDOM.createRoot fehlen"));
5987
+ }
5988
+ } else if (typeof globals.FineArtApp !== "function") {
5989
+ return fail3(step, scriptFailure(step, "window.FineArtApp fehlt"));
5990
+ }
5991
+ report();
5992
+ }
5993
+ return {
5994
+ ok: true,
5995
+ steps,
5996
+ css,
5997
+ runtime: {
5998
+ React: globals.React,
5999
+ ReactDOM: globals.ReactDOM,
6000
+ FineArtApp: globals.FineArtApp
6001
+ },
6002
+ backendUrl: target.backendUrl
6003
+ };
6004
+ }
6005
+
6006
+ // src/components/FlowFineArtApp.tsx
6007
+ import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6008
+ var FLOW_APP_STYLE_ID = "fa-flow-app-master-css";
6009
+ var BAR_HEIGHT = 32;
6010
+ function stepText(step) {
6011
+ const parts = [step.file];
6012
+ if (step.response) {
6013
+ parts.push(step.response.status !== null ? `HTTP ${step.response.status}` : "kein HTTP-Status");
6014
+ parts.push(`${step.response.transport ?? "kein Transport"} \xB7 ${step.response.roundTripMs} ms`);
6015
+ } else {
6016
+ parts.push("l\xE4dt\u2026");
6017
+ }
6018
+ if (step.chars !== null) parts.push(`${step.chars} Zeichen`);
6019
+ if (step.hash === "ok") parts.push("Hash gepr\xFCft");
6020
+ if (step.hash === "unavailable") parts.push("Hash nicht pr\xFCfbar");
6021
+ if (step.scriptEvent) parts.push(`Skript ${step.scriptEvent}`);
6022
+ if (step.cspViolations.length > 0) parts.push(`CSP: ${step.cspViolations.join("; ")}`);
6023
+ if (step.error) parts.push(`FEHLER: ${step.error}`);
6024
+ return parts.join(" \xB7 ");
6025
+ }
6026
+ var FlowFineArtApp = ({ environment, hfToken, appVersion, client, onClose }) => {
6027
+ const bridge = useMemo7(() => client ?? createFlowBridgeClient({ appVersion }), [client, appVersion]);
6028
+ const [connection, setConnection] = useState26(null);
6029
+ const [steps, setSteps] = useState26([]);
6030
+ const [load, setLoad] = useState26(null);
6031
+ const [renderError, setRenderError] = useState26(null);
6032
+ const appRootRef = useRef10(null);
6033
+ const tokenSuffix = hfTokenSuffix(hfToken);
6034
+ const target = FLOW_APP_TARGETS[environment];
6035
+ useEffect11(() => {
6036
+ if (!tokenSuffix) return void 0;
6037
+ let active = true;
6038
+ void (async () => {
6039
+ const connected = bridge.connect ? await bridge.connect(environment) : { ok: false, error: { code: "no-bridge", message: "Bridge-Client ohne connect." }, waitedMs: 0 };
6040
+ if (!active) return;
6041
+ setConnection(connected);
6042
+ if (!connected.ok) return;
6043
+ const result = await loadFlowApp({ bridge, environment, tokenSuffix, onStep: (next) => {
6044
+ if (active) setSteps(next);
6045
+ } });
6046
+ if (active) setLoad(result);
6047
+ })();
6048
+ return () => {
6049
+ active = false;
6050
+ };
6051
+ }, [bridge, environment, tokenSuffix]);
6052
+ useEffect11(() => {
6053
+ const container = appRootRef.current;
6054
+ if (!load?.ok || !container) return void 0;
6055
+ const style = document.createElement("style");
6056
+ style.id = FLOW_APP_STYLE_ID;
6057
+ style.textContent = load.css;
6058
+ document.head.appendChild(style);
6059
+ let root = null;
6060
+ try {
6061
+ root = load.runtime.ReactDOM.createRoot(container);
6062
+ root.render(load.runtime.React.createElement(load.runtime.FineArtApp, {
6063
+ customTabs: [],
6064
+ apiKey: null,
6065
+ backendUrl: load.backendUrl,
6066
+ transport: "flow-bridge"
6067
+ }));
6068
+ } catch (error) {
6069
+ setRenderError(error instanceof Error ? error.message : String(error));
6070
+ }
6071
+ return () => {
6072
+ root?.unmount();
6073
+ style.remove();
6074
+ };
6075
+ }, [load]);
6076
+ const failed = !tokenSuffix || connection !== null && !connection.ok || load !== null && !load.ok || renderError !== null;
6077
+ return /* @__PURE__ */ jsxs28("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col", "data-testid": "flow-fine-art-app", children: [
6078
+ /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-3 px-3 text-[11px] font-mono text-white/60", style: { height: BAR_HEIGHT, borderBottom: "1px solid rgba(255,255,255,0.08)" }, children: [
6079
+ /* @__PURE__ */ jsx30("button", { type: "button", onClick: onClose, className: "font-bold text-white/80", children: "\u2190 FlowFA" }),
6080
+ /* @__PURE__ */ jsx30("span", { children: `Fine-Art App \xB7 ${environment.toUpperCase()} \xB7 ${target.backendUrl}` })
6081
+ ] }),
6082
+ !load?.ok && /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1 p-4 text-[11px] font-mono break-all", "data-testid": "flow-fine-art-app-steps", children: [
6083
+ !tokenSuffix && /* @__PURE__ */ jsx30("span", { role: "alert", style: { color: "#f87171" }, children: "Kein HF-Token in FlowFA gesetzt \u2014 ohne ihn kein Zugang zum MCP-Host." }),
6084
+ tokenSuffix && !connection && /* @__PURE__ */ jsx30("span", { "data-testid": "flow-fine-art-app-connect", style: { color: "#fbbf24" }, children: `Freigabe n\xF6tig: Extension-Popup \u201EFine-Art Flow Bridge\u201C \xF6ffnen (Zahl am Symbol) \u2192 \u201EFreigeben\u201C f\xFCr ${environment.toUpperCase()} (${target.backendUrl}).` }),
6085
+ connection && /* @__PURE__ */ jsx30("span", { "data-testid": "flow-fine-art-app-connect", style: { color: connection.ok ? "rgba(255,255,255,0.6)" : "#f87171" }, children: connection.ok ? `Freigegeben f\xFCr dieses Dokument \xB7 ${connection.server} \xB7 nach ${connection.waitedMs} ms` : `Keine Freigabe \u2014 ${connection.error.code}: ${connection.error.message}` }),
6086
+ connection && !connection.ok && /* @__PURE__ */ jsx30("span", { role: "alert", className: "font-bold", style: { color: "#f87171" }, children: "App nicht gestartet \u2014 ohne Freigabe erreicht sie ihren Server nicht." }),
6087
+ steps.map((step) => /* @__PURE__ */ jsx30("span", { style: { color: step.error ? "#f87171" : "rgba(255,255,255,0.6)" }, children: stepText(step) }, step.file)),
6088
+ load && !load.ok && /* @__PURE__ */ jsx30("span", { role: "alert", className: "font-bold", style: { color: "#f87171" }, children: `App nicht gestartet \u2014 ${load.error}` })
6089
+ ] }),
6090
+ renderError && /* @__PURE__ */ jsx30("span", { role: "alert", className: "p-4 text-[11px] font-mono", style: { color: "#f87171" }, children: `App nicht gerendert \u2014 ${renderError}` }),
6091
+ /* @__PURE__ */ jsx30("div", { ref: appRootRef, className: "flex-1 overflow-auto", style: { display: load?.ok && !failed ? "block" : "none" } })
6092
+ ] });
6093
+ };
6094
+
5689
6095
  // src/lib/flowBootstrapTarget.ts
5690
6096
  var PROD_NAMESPACE = "app.art-by-rolands.de/";
5691
6097
  var DEV_NAMESPACE = "dev-app.art-by-rolands.de/";
@@ -5736,11 +6142,15 @@ function resolveBootstrapTarget(input) {
5736
6142
  environment: environmentForNamespace(namespace)
5737
6143
  };
5738
6144
  }
6145
+ function flowAppEnvironment(target, isDialogTarget, selectedNamespace) {
6146
+ if (isDialogTarget) return environmentForNamespace(normalizeSelectableNamespace(selectedNamespace));
6147
+ return target.ready ? target.environment : null;
6148
+ }
5739
6149
 
5740
6150
  // src/components/AvatarArchitectApp.tsx
5741
- import { Fragment as Fragment10, jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6151
+ import { Fragment as Fragment11, jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
5742
6152
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, requireWorkspaceSelection = false, serverBaseUrl }) {
5743
- useEffect11(() => {
6153
+ useEffect12(() => {
5744
6154
  const id = "flow-styles";
5745
6155
  if (!document.getElementById(id)) {
5746
6156
  const style = document.createElement("style");
@@ -5749,33 +6159,34 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5749
6159
  document.head.appendChild(style);
5750
6160
  }
5751
6161
  }, []);
5752
- const [showStart, setShowStart] = useState26(true);
5753
- const [layoutChoice, setLayoutChoice] = useState26(() => {
6162
+ const [showStart, setShowStart] = useState27(true);
6163
+ const [layoutChoice, setLayoutChoice] = useState27(() => {
5754
6164
  try {
5755
6165
  return localStorage.getItem("aa-layout") || null;
5756
6166
  } catch {
5757
6167
  return null;
5758
6168
  }
5759
6169
  });
5760
- const [hfToken, setHfToken] = useState26(initialHfToken || "");
5761
- const [hfTokenInput, setHfTokenInput] = useState26(initialHfToken || "");
5762
- const [hfNamespaceLocal, setHfNamespaceLocal] = useState26(() => {
6170
+ const [hfToken, setHfToken] = useState27(initialHfToken || "");
6171
+ const [serverAppEnvironment, setServerAppEnvironment] = useState27(null);
6172
+ const [hfTokenInput, setHfTokenInput] = useState27(initialHfToken || "");
6173
+ const [hfNamespaceLocal, setHfNamespaceLocal] = useState27(() => {
5763
6174
  try {
5764
6175
  return normalizeSelectableNamespace(localStorage.getItem("aa-hf-namespace"));
5765
6176
  } catch {
5766
6177
  return DEFAULT_NAMESPACE;
5767
6178
  }
5768
6179
  });
5769
- const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState26(null);
5770
- const [serverProbeFailed, setServerProbeFailed] = useState26(false);
5771
- useEffect11(() => {
6180
+ const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState27(null);
6181
+ const [serverProbeFailed, setServerProbeFailed] = useState27(false);
6182
+ useEffect12(() => {
5772
6183
  if (hfNamespace !== void 0 || !serverBaseUrl) return;
5773
6184
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
5774
6185
  if (typeof d.hfNamespace === "string" && d.hfNamespace) setHfNamespaceFromServer(d.hfNamespace);
5775
6186
  else setServerProbeFailed(true);
5776
6187
  }).catch(() => setServerProbeFailed(true));
5777
6188
  }, [hfNamespace, serverBaseUrl]);
5778
- const [targetConfirmed, setTargetConfirmed] = useState26(false);
6189
+ const [targetConfirmed, setTargetConfirmed] = useState27(false);
5779
6190
  const isDialogTarget = hfNamespace === void 0 && hfNamespaceFromServer === null && (!serverBaseUrl || serverProbeFailed);
5780
6191
  const isProbingServer = hfNamespace === void 0 && !!serverBaseUrl && hfNamespaceFromServer === null && !serverProbeFailed;
5781
6192
  const bootstrapTarget = resolveBootstrapTarget({
@@ -5786,8 +6197,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5786
6197
  isStartDialogOpen: isDialogTarget && !targetConfirmed
5787
6198
  });
5788
6199
  const effectiveNamespace = bootstrapTarget.namespace ?? "";
5789
- const kontextRef = useRef10(null);
5790
- const szenenPort = useMemo7(() => hfToken && effectiveNamespace ? createFlowSzenenViewPort({
6200
+ const kontextRef = useRef11(null);
6201
+ const szenenPort = useMemo8(() => hfToken && effectiveNamespace ? createFlowSzenenViewPort({
5791
6202
  generateText: onGeneratePrompt,
5792
6203
  token: hfToken,
5793
6204
  namespace: effectiveNamespace,
@@ -5809,36 +6220,36 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5809
6220
  const tagBaseResult = useTagBase(hfToken, effectiveNamespace);
5810
6221
  const szenenKontextId = tagBaseResult.selectedContextId === null ? null : String(tagBaseResult.selectedContextId);
5811
6222
  kontextRef.current = szenenKontextId;
5812
- const [imageUploadStatus, setImageUploadStatus] = useState26(/* @__PURE__ */ new Map());
5813
- const [bootstrapLog, setBootstrapLog] = useState26([]);
5814
- const [isBootstrapping, setIsBootstrapping] = useState26(false);
5815
- const [hfMissingImages, setHfMissingImages] = useState26([]);
5816
- const syncTopSlot = /* @__PURE__ */ jsxs28(Fragment10, { children: [
5817
- localOnlyCount > 0 && /* @__PURE__ */ jsxs28("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: [
6223
+ const [imageUploadStatus, setImageUploadStatus] = useState27(/* @__PURE__ */ new Map());
6224
+ const [bootstrapLog, setBootstrapLog] = useState27([]);
6225
+ const [isBootstrapping, setIsBootstrapping] = useState27(false);
6226
+ const [hfMissingImages, setHfMissingImages] = useState27([]);
6227
+ const syncTopSlot = /* @__PURE__ */ jsxs29(Fragment11, { children: [
6228
+ localOnlyCount > 0 && /* @__PURE__ */ jsxs29("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: [
5818
6229
  "\u26A0 ",
5819
6230
  localOnlyCount,
5820
6231
  " lokale Event",
5821
6232
  localOnlyCount > 1 ? "s" : "",
5822
6233
  " noch nicht auf HF best\xE4tigt"
5823
6234
  ] }),
5824
- pendingBufferCount > 0 && /* @__PURE__ */ jsxs28("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
6235
+ pendingBufferCount > 0 && /* @__PURE__ */ jsxs29("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
5825
6236
  pendingBufferCount,
5826
6237
  " \xC4nderung",
5827
6238
  pendingBufferCount > 1 ? "en" : "",
5828
6239
  " lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
5829
6240
  ] }),
5830
- eventCount > 100 && /* @__PURE__ */ jsxs28("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
6241
+ eventCount > 100 && /* @__PURE__ */ jsxs29("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
5831
6242
  "\u26A0 ",
5832
6243
  eventCount,
5833
6244
  " Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
5834
6245
  ] }),
5835
- eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ jsxs28("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
6246
+ eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ jsxs29("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
5836
6247
  eventCount,
5837
6248
  " Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
5838
6249
  ] }),
5839
- hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ jsxs28("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
5840
- /* @__PURE__ */ jsx30("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" }),
5841
- /* @__PURE__ */ jsx30(
6250
+ hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ jsxs29("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
6251
+ /* @__PURE__ */ jsx31("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" }),
6252
+ /* @__PURE__ */ jsx31(
5842
6253
  "button",
5843
6254
  {
5844
6255
  disabled: isBootstrapping || !effectiveNamespace,
@@ -5859,7 +6270,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5859
6270
  children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
5860
6271
  }
5861
6272
  ),
5862
- bootstrapLog.length > 0 && /* @__PURE__ */ jsx30("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ jsx30("div", { children: l }, i)) })
6273
+ bootstrapLog.length > 0 && /* @__PURE__ */ jsx31("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ jsx31("div", { children: l }, i)) })
5863
6274
  ] })
5864
6275
  ] });
5865
6276
  const startApp = (choice) => {
@@ -5871,18 +6282,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5871
6282
  setTargetConfirmed(true);
5872
6283
  setShowStart(false);
5873
6284
  };
5874
- const [nodes, setNodes] = useState26([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
5875
- const [edges, setEdges] = useState26([]);
5876
- const [history, setHistory] = useState26([]);
5877
- const [galleryItems, setGalleryItems] = useState26([]);
5878
- const galleryItemsRef = useRef10([]);
5879
- useEffect11(() => {
6285
+ const [nodes, setNodes] = useState27([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
6286
+ const [edges, setEdges] = useState27([]);
6287
+ const [history, setHistory] = useState27([]);
6288
+ const [galleryItems, setGalleryItems] = useState27([]);
6289
+ const galleryItemsRef = useRef11([]);
6290
+ useEffect12(() => {
5880
6291
  galleryItemsRef.current = galleryItems;
5881
6292
  }, [galleryItems]);
5882
- const hfImageNotFoundRef = useRef10(/* @__PURE__ */ new Map());
5883
- const [galleryVisibleCount, setGalleryVisibleCount] = useState26(20);
5884
- const [historyVisibleCount, setHistoryVisibleCount] = useState26(20);
5885
- const hfInFlightRef = useRef10(/* @__PURE__ */ new Set());
6293
+ const hfImageNotFoundRef = useRef11(/* @__PURE__ */ new Map());
6294
+ const [galleryVisibleCount, setGalleryVisibleCount] = useState27(20);
6295
+ const [historyVisibleCount, setHistoryVisibleCount] = useState27(20);
6296
+ const hfInFlightRef = useRef11(/* @__PURE__ */ new Set());
5886
6297
  const loadThumbnailsForEntries = useCallback4(async (entries) => {
5887
6298
  await loadThumbnailsSequentially(entries, {
5888
6299
  inFlight: hfInFlightRef.current,
@@ -5903,7 +6314,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5903
6314
  }
5904
6315
  });
5905
6316
  }, [hfToken, effectiveNamespace]);
5906
- useEffect11(() => {
6317
+ useEffect12(() => {
5907
6318
  if (!hfState) return;
5908
6319
  if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
5909
6320
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
@@ -5930,24 +6341,24 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5930
6341
  return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5931
6342
  });
5932
6343
  }, [hfState]);
5933
- const [activePrompt, setActivePrompt] = useState26("");
5934
- const [isSynthesizing, setIsSynthesizing] = useState26(false);
5935
- const [activeGenerationsCount, setActiveGenerationsCount] = useState26(0);
5936
- const [currentResult, setCurrentResult] = useState26(null);
5937
- const [focusedNodeId, setFocusedNodeId] = useState26(null);
5938
- const [leftTab, setLeftTab] = useState26("prompt");
5939
- const [promptFeedback, setPromptFeedback] = useState26(null);
5940
- const [lastPromptPayload, setLastPromptPayload] = useState26(null);
5941
- const [isPromptTabGenerating, setIsPromptTabGenerating] = useState26(false);
5942
- const [activeTab, setActiveTab] = useState26("history");
5943
- const [mobileTab, setMobileTab] = useState26("stage");
5944
- const [middlePanel, setMiddlePanel] = useState26("stage");
5945
- const [recentLabItems, setRecentLabItems] = useState26([]);
5946
- const [aspectRatio, setAspectRatio] = useState26("1:1");
5947
- const [selectedModel, setSelectedModel] = useState26("\u{1F34C} Nano Banana Pro");
5948
- const [seed, setSeed] = useState26(Math.floor(Math.random() * 1e6));
5949
- const [seedMode, setSeedMode] = useState26("random");
5950
- const [imageCount, setImageCount] = useState26(() => {
6344
+ const [activePrompt, setActivePrompt] = useState27("");
6345
+ const [isSynthesizing, setIsSynthesizing] = useState27(false);
6346
+ const [activeGenerationsCount, setActiveGenerationsCount] = useState27(0);
6347
+ const [currentResult, setCurrentResult] = useState27(null);
6348
+ const [focusedNodeId, setFocusedNodeId] = useState27(null);
6349
+ const [leftTab, setLeftTab] = useState27("prompt");
6350
+ const [promptFeedback, setPromptFeedback] = useState27(null);
6351
+ const [lastPromptPayload, setLastPromptPayload] = useState27(null);
6352
+ const [isPromptTabGenerating, setIsPromptTabGenerating] = useState27(false);
6353
+ const [activeTab, setActiveTab] = useState27("history");
6354
+ const [mobileTab, setMobileTab] = useState27("stage");
6355
+ const [middlePanel, setMiddlePanel] = useState27("stage");
6356
+ const [recentLabItems, setRecentLabItems] = useState27([]);
6357
+ const [aspectRatio, setAspectRatio] = useState27("1:1");
6358
+ const [selectedModel, setSelectedModel] = useState27("\u{1F34C} Nano Banana Pro");
6359
+ const [seed, setSeed] = useState27(Math.floor(Math.random() * 1e6));
6360
+ const [seedMode, setSeedMode] = useState27("random");
6361
+ const [imageCount, setImageCount] = useState27(() => {
5951
6362
  try {
5952
6363
  const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
5953
6364
  return v >= 1 && v <= 8 ? v : 4;
@@ -5969,38 +6380,38 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5969
6380
  { label: "4 Bilder", value: "4" },
5970
6381
  { label: "8 Bilder", value: "8" }
5971
6382
  ];
5972
- const [isLeftCollapsed, setIsLeftCollapsed] = useState26(false);
5973
- const [isRightCollapsed, setIsRightCollapsed] = useState26(false);
5974
- const [leftPanelWidth, setLeftPanelWidth] = useState26(() => {
6383
+ const [isLeftCollapsed, setIsLeftCollapsed] = useState27(false);
6384
+ const [isRightCollapsed, setIsRightCollapsed] = useState27(false);
6385
+ const [leftPanelWidth, setLeftPanelWidth] = useState27(() => {
5975
6386
  try {
5976
6387
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
5977
6388
  } catch {
5978
6389
  return 260;
5979
6390
  }
5980
6391
  });
5981
- const [rightPanelWidth, setRightPanelWidth] = useState26(() => {
6392
+ const [rightPanelWidth, setRightPanelWidth] = useState27(() => {
5982
6393
  try {
5983
6394
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
5984
6395
  } catch {
5985
6396
  return 320;
5986
6397
  }
5987
6398
  });
5988
- const [isPromptCollapsed, setIsPromptCollapsed] = useState26(false);
5989
- const [workspaceTags, setWorkspaceTags] = useState26(null);
5990
- const [highContrast, setHighContrast] = useState26(() => {
6399
+ const [isPromptCollapsed, setIsPromptCollapsed] = useState27(false);
6400
+ const [workspaceTags, setWorkspaceTags] = useState27(null);
6401
+ const [highContrast, setHighContrast] = useState27(() => {
5991
6402
  try {
5992
6403
  return localStorage.getItem("aa-contrast") === "high";
5993
6404
  } catch {
5994
6405
  return false;
5995
6406
  }
5996
6407
  });
5997
- const [activeReferenceId, setActiveReferenceId] = useState26(null);
5998
- const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState26(null);
5999
- const [isScanningImage, setIsScanningImage] = useState26(false);
6000
- const [touchStartX, setTouchStartX] = useState26(null);
6001
- const [isFullscreen, setIsFullscreen] = useState26(false);
6002
- const [zoomScale, setZoomScale] = useState26(1);
6003
- const [zoomOffset, setZoomOffset] = useState26({ x: 0, y: 0 });
6408
+ const [activeReferenceId, setActiveReferenceId] = useState27(null);
6409
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState27(null);
6410
+ const [isScanningImage, setIsScanningImage] = useState27(false);
6411
+ const [touchStartX, setTouchStartX] = useState27(null);
6412
+ const [isFullscreen, setIsFullscreen] = useState27(false);
6413
+ const [zoomScale, setZoomScale] = useState27(1);
6414
+ const [zoomOffset, setZoomOffset] = useState27({ x: 0, y: 0 });
6004
6415
  const { historyVisible, galleryVisible } = computePrefetchVisibility({
6005
6416
  layoutChoice,
6006
6417
  appShellVisible: !showStart && !requireWorkspaceSelection && !(isFullscreen && !!currentResult?.base64),
@@ -6017,9 +6428,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6017
6428
  galleryVisibleCount,
6018
6429
  loadThumbnailsForEntries
6019
6430
  });
6020
- const lastPinchDist = useRef10(null);
6021
- const lastTapTime = useRef10(0);
6022
- const dragStart = useRef10(null);
6431
+ const lastPinchDist = useRef11(null);
6432
+ const lastTapTime = useRef11(0);
6433
+ const dragStart = useRef11(null);
6023
6434
  const openFullscreen = () => {
6024
6435
  setIsFullscreen(true);
6025
6436
  setZoomScale(1);
@@ -6082,7 +6493,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6082
6493
  setActiveReferenceId(null);
6083
6494
  setActiveReferenceThumbnail(null);
6084
6495
  };
6085
- const labServices = useMemo7(() => {
6496
+ const labServices = useMemo8(() => {
6086
6497
  const available = groupGenerationsToLabItems([...galleryItems, ...history]);
6087
6498
  return {
6088
6499
  availableItems: available,
@@ -6162,7 +6573,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6162
6573
  setIsScanningImage(false);
6163
6574
  }
6164
6575
  };
6165
- const currentIndex = useMemo7(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
6576
+ const currentIndex = useMemo8(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
6166
6577
  const goToPrev = useCallback4(() => {
6167
6578
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
6168
6579
  }, [currentIndex, history]);
@@ -6191,13 +6602,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6191
6602
  });
6192
6603
  }
6193
6604
  }, [hfToken, effectiveNamespace, hfWriteEvent]);
6194
- const currentGroup = useMemo7(() => {
6605
+ const currentGroup = useMemo8(() => {
6195
6606
  if (!currentResult?.prompt) return [];
6196
6607
  const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
6197
6608
  const group = groups.find((gr) => gr.prompt === currentResult.prompt);
6198
6609
  return group ? group.items : [];
6199
6610
  }, [galleryItems, currentResult?.prompt]);
6200
- useEffect11(() => {
6611
+ useEffect12(() => {
6201
6612
  if (!currentResult?.prompt || !hfToken || !effectiveNamespace || !hfState) return;
6202
6613
  const siblings = galleryItemsRef.current.filter(
6203
6614
  (g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
@@ -6223,15 +6634,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6223
6634
  })();
6224
6635
  }, [currentResult?.id, currentResult?.prompt]);
6225
6636
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
6226
- const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ jsxs28(
6637
+ const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ jsxs29(
6227
6638
  "div",
6228
6639
  {
6229
6640
  className: "flex items-center gap-1 rounded-full bg-sky-500/15 border border-sky-400/30 px-2 shrink-0",
6230
6641
  style: { height: 24 },
6231
6642
  title: `${activeGenerationsCount} Generierung${activeGenerationsCount === 1 ? "" : "en"} l\xE4uft gerade`,
6232
6643
  children: [
6233
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
6234
- /* @__PURE__ */ jsx30("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
6644
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
6645
+ /* @__PURE__ */ jsx31("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
6235
6646
  ]
6236
6647
  }
6237
6648
  ) : null;
@@ -6244,7 +6655,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6244
6655
  return `${indent}- ${node.data.label || "(unbenannt)"}
6245
6656
  ` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
6246
6657
  }, [nodes, edges]);
6247
- const activePath = useMemo7(() => {
6658
+ const activePath = useMemo8(() => {
6248
6659
  if (!focusedNodeId) return /* @__PURE__ */ new Set();
6249
6660
  const path = /* @__PURE__ */ new Set([focusedNodeId]);
6250
6661
  let currId = focusedNodeId;
@@ -6520,7 +6931,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6520
6931
  if (isFullscreen && currentResult?.base64) {
6521
6932
  const fsRaw = currentResult.fullBase64 || currentResult.base64;
6522
6933
  const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
6523
- return /* @__PURE__ */ jsxs28(
6934
+ return /* @__PURE__ */ jsxs29(
6524
6935
  "div",
6525
6936
  {
6526
6937
  className: "fixed inset-0 bg-black z-50 flex items-center justify-center overflow-hidden touch-none",
@@ -6528,7 +6939,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6528
6939
  onTouchMove: handleFsTouchMove,
6529
6940
  onTouchEnd: handleFsTouchEnd,
6530
6941
  children: [
6531
- /* @__PURE__ */ jsx30(
6942
+ /* @__PURE__ */ jsx31(
6532
6943
  "img",
6533
6944
  {
6534
6945
  src: fsBase64,
@@ -6545,57 +6956,61 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6545
6956
  }
6546
6957
  }
6547
6958
  ),
6548
- /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
6549
- zoomScale > 1 && /* @__PURE__ */ jsx30("button", { onClick: () => {
6959
+ /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
6960
+ zoomScale > 1 && /* @__PURE__ */ jsx31("button", { onClick: () => {
6550
6961
  setZoomScale(1);
6551
6962
  setZoomOffset({ x: 0, y: 0 });
6552
- }, 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__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
6553
- history.length > 1 && /* @__PURE__ */ jsxs28(Fragment10, { children: [
6554
- /* @__PURE__ */ jsx30("button", { onClick: () => {
6963
+ }, 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__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
6964
+ history.length > 1 && /* @__PURE__ */ jsxs29(Fragment11, { children: [
6965
+ /* @__PURE__ */ jsx31("button", { onClick: () => {
6555
6966
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
6556
- }, 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__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6557
- /* @__PURE__ */ jsx30("button", { onClick: () => {
6967
+ }, 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__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6968
+ /* @__PURE__ */ jsx31("button", { onClick: () => {
6558
6969
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
6559
- }, 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__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
6560
- /* @__PURE__ */ jsxs28("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: [
6970
+ }, 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__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
6971
+ /* @__PURE__ */ jsxs29("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: [
6561
6972
  currentIndex + 1,
6562
6973
  " / ",
6563
6974
  history.length
6564
6975
  ] })
6565
6976
  ] }),
6566
- zoomScale === 1 && /* @__PURE__ */ jsx30("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
6977
+ zoomScale === 1 && /* @__PURE__ */ jsx31("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
6567
6978
  ]
6568
6979
  }
6569
6980
  );
6570
6981
  }
6982
+ if (serverAppEnvironment) {
6983
+ return /* @__PURE__ */ jsx31(FlowFineArtApp, { environment: serverAppEnvironment, hfToken, appVersion: version, onClose: () => setServerAppEnvironment(null) });
6984
+ }
6571
6985
  if (showStart) {
6572
- return /* @__PURE__ */ jsxs28("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
6573
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-1", children: [
6574
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
6575
- /* @__PURE__ */ jsx30("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
6576
- /* @__PURE__ */ jsxs28("span", { className: "text-white text-[13px] font-mono", children: [
6986
+ const serverAppTarget = flowAppEnvironment(bootstrapTarget, isDialogTarget, hfNamespaceLocal);
6987
+ return /* @__PURE__ */ jsxs29("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
6988
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-1", children: [
6989
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
6990
+ /* @__PURE__ */ jsx31("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
6991
+ /* @__PURE__ */ jsxs29("span", { className: "text-white text-[13px] font-mono", children: [
6577
6992
  "v",
6578
6993
  version
6579
6994
  ] })
6580
6995
  ] }),
6581
- /* @__PURE__ */ jsxs28(
6996
+ /* @__PURE__ */ jsxs29(
6582
6997
  "button",
6583
6998
  {
6584
6999
  onClick: toggleContrast,
6585
7000
  className: "flex items-center gap-3 px-5 py-3 rounded-2xl border transition-colors",
6586
7001
  style: { borderColor: highContrast ? "rgba(255,255,255,0.3)" : "rgba(255,255,255,0.08)", background: highContrast ? "rgba(255,255,255,0.08)" : "transparent" },
6587
7002
  children: [
6588
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
6589
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-start", children: [
6590
- /* @__PURE__ */ jsx30("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
6591
- /* @__PURE__ */ jsx30("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
7003
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
7004
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-start", children: [
7005
+ /* @__PURE__ */ jsx31("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
7006
+ /* @__PURE__ */ jsx31("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
6592
7007
  ] })
6593
7008
  ]
6594
7009
  }
6595
7010
  ),
6596
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6597
- !initialHfToken && /* @__PURE__ */ jsxs28("div", { className: "flex gap-2 w-full", children: [
6598
- /* @__PURE__ */ jsx30(
7011
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
7012
+ !initialHfToken && /* @__PURE__ */ jsxs29("div", { className: "flex gap-2 w-full", children: [
7013
+ /* @__PURE__ */ jsx31(
6599
7014
  "input",
6600
7015
  {
6601
7016
  type: "password",
@@ -6611,7 +7026,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6611
7026
  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)" }
6612
7027
  }
6613
7028
  ),
6614
- hfTokenInput.trim() && /* @__PURE__ */ jsx30(
7029
+ hfTokenInput.trim() && /* @__PURE__ */ jsx31(
6615
7030
  "button",
6616
7031
  {
6617
7032
  type: "button",
@@ -6622,9 +7037,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6622
7037
  }
6623
7038
  )
6624
7039
  ] }),
6625
- isDialogTarget && /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-3 w-full", children: [
6626
- /* @__PURE__ */ jsx30("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
6627
- ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ jsx30(
7040
+ isDialogTarget && /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3 w-full", children: [
7041
+ /* @__PURE__ */ jsx31("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
7042
+ ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ jsx31(
6628
7043
  "button",
6629
7044
  {
6630
7045
  onClick: () => {
@@ -6645,48 +7060,61 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6645
7060
  ))
6646
7061
  ] })
6647
7062
  ] }),
6648
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
6649
- /* @__PURE__ */ jsx30("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
6650
- /* @__PURE__ */ jsx30("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
7063
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
7064
+ /* @__PURE__ */ jsx31("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
7065
+ /* @__PURE__ */ jsx31("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
6651
7066
  { id: "mobile", icon: "smartphone", label: "Mobile" },
6652
7067
  { id: "mobile-desktop", icon: "phonelink", label: "Mobile+" },
6653
7068
  { id: "desktop", icon: "desktop_windows", label: "Desktop" },
6654
7069
  { id: "tablet-landscape", icon: "tablet", label: "Landscape" }
6655
- ].map((opt) => /* @__PURE__ */ jsxs28(
7070
+ ].map((opt) => /* @__PURE__ */ jsxs29(
6656
7071
  "button",
6657
7072
  {
6658
7073
  onClick: () => startApp(opt.id),
6659
7074
  className: "flex flex-col items-center gap-2 py-4 rounded-2xl border transition-colors",
6660
7075
  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" },
6661
7076
  children: [
6662
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
6663
- /* @__PURE__ */ jsx30("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
7077
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
7078
+ /* @__PURE__ */ jsx31("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
6664
7079
  ]
6665
7080
  },
6666
7081
  opt.id
6667
7082
  )) }),
6668
- layoutChoice === "mobile-desktop" && /* @__PURE__ */ jsx30("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
6669
- layoutChoice === "tablet-landscape" && /* @__PURE__ */ jsx30("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
7083
+ layoutChoice === "mobile-desktop" && /* @__PURE__ */ jsx31("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
7084
+ layoutChoice === "tablet-landscape" && /* @__PURE__ */ jsx31("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
6670
7085
  ] }),
6671
- /* @__PURE__ */ jsx30(FlowBridgePanel, { appVersion: version })
7086
+ serverAppTarget && /* @__PURE__ */ jsxs29(
7087
+ "button",
7088
+ {
7089
+ type: "button",
7090
+ onClick: () => setServerAppEnvironment(serverAppTarget),
7091
+ className: "flex items-center justify-center gap-2 w-full max-w-[280px] py-3 rounded-2xl border text-[11px] font-bold",
7092
+ style: { borderColor: "rgba(255,255,255,0.08)", color: "rgba(255,255,255,0.6)" },
7093
+ children: [
7094
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "web" }),
7095
+ `Fine-Art App (Server) \xB7 ${serverAppTarget.toUpperCase()}`
7096
+ ]
7097
+ }
7098
+ ),
7099
+ /* @__PURE__ */ jsx31(FlowBridgePanel, { appVersion: version, hfToken })
6672
7100
  ] });
6673
7101
  }
6674
7102
  if (requireWorkspaceSelection) {
6675
7103
  if (!bootstrapTarget.ready) {
6676
- return /* @__PURE__ */ jsx30("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx30("section", { className: "flow-workspace-picker__card", children: "Zielraum wird bestimmt\u2026" }) });
7104
+ return /* @__PURE__ */ jsx31("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx31("section", { className: "flow-workspace-picker__card", children: "Zielraum wird bestimmt\u2026" }) });
6677
7105
  }
6678
7106
  if (!hfToken) {
6679
- return /* @__PURE__ */ jsx30("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx30("section", { className: "flow-workspace-picker__card", role: "alert", children: "HF-Token fehlt \u2014 User und Context koennen nicht aus der Tag-Base geladen werden." }) });
7107
+ return /* @__PURE__ */ jsx31("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx31("section", { className: "flow-workspace-picker__card", role: "alert", children: "HF-Token fehlt \u2014 User und Context koennen nicht aus der Tag-Base geladen werden." }) });
6680
7108
  }
6681
7109
  if (tagBaseResult.isLoading) {
6682
- return /* @__PURE__ */ jsx30("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs28("section", { className: "flow-workspace-picker__card", children: [
7110
+ return /* @__PURE__ */ jsx31("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs29("section", { className: "flow-workspace-picker__card", children: [
6683
7111
  "Lade User und Contexts aus ",
6684
7112
  effectiveNamespace,
6685
7113
  "\u2026"
6686
7114
  ] }) });
6687
7115
  }
6688
7116
  if (tagBaseResult.error) {
6689
- return /* @__PURE__ */ jsx30("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs28("section", { className: "flow-workspace-picker__card", role: "alert", children: [
7117
+ return /* @__PURE__ */ jsx31("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs29("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6690
7118
  "Tag-Base ",
6691
7119
  effectiveNamespace,
6692
7120
  " konnte nicht geladen werden: ",
@@ -6694,14 +7122,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6694
7122
  ] }) });
6695
7123
  }
6696
7124
  if (!tagBaseResult.tagBase) {
6697
- return /* @__PURE__ */ jsx30("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs28("section", { className: "flow-workspace-picker__card", role: "alert", children: [
7125
+ return /* @__PURE__ */ jsx31("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs29("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6698
7126
  "Im Namespace ",
6699
7127
  effectiveNamespace,
6700
7128
  " fehlt tags-state-*.zip. Der Server muss zuerst die Tag-Base erzeugen."
6701
7129
  ] }) });
6702
7130
  }
6703
7131
  if (tagBaseResult.needsPicker) {
6704
- return /* @__PURE__ */ jsx30(
7132
+ return /* @__PURE__ */ jsx31(
6705
7133
  FlowWorkspacePicker,
6706
7134
  {
6707
7135
  tagBase: tagBaseResult.tagBase,
@@ -6713,7 +7141,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6713
7141
  );
6714
7142
  }
6715
7143
  }
6716
- const szenenPane = szenenPort ? /* @__PURE__ */ jsx30("div", { className: "flow-szenen-pane", children: /* @__PURE__ */ jsx30(SzenenView, { port: szenenPort, contextId: szenenKontextId }) }) : /* @__PURE__ */ jsx30("div", { className: "flow-szenen-pane flow-szenen-pane--empty", children: /* @__PURE__ */ jsxs28("p", { children: [
7144
+ const szenenPane = szenenPort ? /* @__PURE__ */ jsx31("div", { className: "flow-szenen-pane", children: /* @__PURE__ */ jsx31(SzenenView, { port: szenenPort, contextId: szenenKontextId }) }) : /* @__PURE__ */ jsx31("div", { className: "flow-szenen-pane flow-szenen-pane--empty", children: /* @__PURE__ */ jsxs29("p", { children: [
6717
7145
  "Szenen brauchen einen HF-Token f\xFCr Namespace ",
6718
7146
  effectiveNamespace || "(noch nicht bestimmt)",
6719
7147
  " \u2014 auf der Flow-Startseite setzen."
@@ -6723,22 +7151,22 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6723
7151
  const mdScale = mdMode ? window.innerWidth / 430 : 1;
6724
7152
  const mdW = mdMode ? 430 : void 0;
6725
7153
  const mdH = mdMode ? Math.ceil(window.innerHeight / mdScale) : void 0;
6726
- const mobileRoot = /* @__PURE__ */ jsxs28("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
7154
+ const mobileRoot = /* @__PURE__ */ jsxs29("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
6727
7155
  width: mdMode ? mdW : "100vw",
6728
7156
  height: mdMode ? mdH : "100dvh",
6729
7157
  transform: mdMode ? `scale(${mdScale})` : void 0,
6730
7158
  transformOrigin: mdMode ? "top left" : void 0,
6731
7159
  ...hcStyle || {}
6732
7160
  }, children: [
6733
- mobileTab === "labs" && /* @__PURE__ */ jsx30("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx30(LabsTab, { services: labServices, onResult: (item) => {
7161
+ mobileTab === "labs" && /* @__PURE__ */ jsx31("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx31(LabsTab, { services: labServices, onResult: (item) => {
6734
7162
  const frame = item.frames[0];
6735
7163
  if (frame?.base64) {
6736
7164
  setCurrentResult(frameToGeneration(frame, item));
6737
7165
  setMobileTab("stage");
6738
7166
  }
6739
7167
  } }) }),
6740
- mobileTab === "server" && /* @__PURE__ */ jsx30("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx30(ServerTab, { serverBaseUrl }) }),
6741
- mobileTab === "tags" && workspaceTags && /* @__PURE__ */ jsx30("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx30(
7168
+ mobileTab === "server" && /* @__PURE__ */ jsx31("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx31(ServerTab, { serverBaseUrl }) }),
7169
+ mobileTab === "tags" && workspaceTags && /* @__PURE__ */ jsx31("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx31(
6742
7170
  TagManagerPanel,
6743
7171
  {
6744
7172
  workspaceTags,
@@ -6750,24 +7178,24 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6750
7178
  }
6751
7179
  ) }),
6752
7180
  mobileTab === "szenen" && szenenPane,
6753
- mobileTab === "stage" && /* @__PURE__ */ jsxs28("div", { className: "flex flex-col flex-1 min-h-0", children: [
6754
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
6755
- /* @__PURE__ */ jsx30(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6756
- /* @__PURE__ */ jsx30(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" }] }),
6757
- /* @__PURE__ */ jsx30(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6758
- /* @__PURE__ */ jsx30("div", { className: "flex-1" }),
6759
- /* @__PURE__ */ jsx30(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7181
+ mobileTab === "stage" && /* @__PURE__ */ jsxs29("div", { className: "flex flex-col flex-1 min-h-0", children: [
7182
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
7183
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
7184
+ /* @__PURE__ */ jsx31(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" }] }),
7185
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
7186
+ /* @__PURE__ */ jsx31("div", { className: "flex-1" }),
7187
+ /* @__PURE__ */ jsx31(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
6760
7188
  runningBadge,
6761
- activeReferenceThumbnail ? /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
6762
- /* @__PURE__ */ jsx30("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6763
- /* @__PURE__ */ jsx30("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
6764
- /* @__PURE__ */ jsx30("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
6765
- ] }) : /* @__PURE__ */ jsx30("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
6766
- /* @__PURE__ */ jsx30("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
6767
- /* @__PURE__ */ jsx30("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
7189
+ activeReferenceThumbnail ? /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
7190
+ /* @__PURE__ */ jsx31("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
7191
+ /* @__PURE__ */ jsx31("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
7192
+ /* @__PURE__ */ jsx31("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
7193
+ ] }) : /* @__PURE__ */ jsx31("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
7194
+ /* @__PURE__ */ jsx31("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
7195
+ /* @__PURE__ */ jsx31("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
6768
7196
  ] }),
6769
- /* @__PURE__ */ jsx30("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ jsxs28("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
6770
- /* @__PURE__ */ jsx30(
7197
+ /* @__PURE__ */ jsx31("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ jsxs29("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
7198
+ /* @__PURE__ */ jsx31(
6771
7199
  "textarea",
6772
7200
  {
6773
7201
  value: activePrompt,
@@ -6777,9 +7205,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6777
7205
  placeholder: "Prompt eingeben..."
6778
7206
  }
6779
7207
  ),
6780
- activePrompt && !isSynthesizing && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
7208
+ activePrompt && !isSynthesizing && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
6781
7209
  ] }) }),
6782
- /* @__PURE__ */ jsx30("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ jsxs28(
7210
+ /* @__PURE__ */ jsx31("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ jsxs29(
6783
7211
  "button",
6784
7212
  {
6785
7213
  onClick: () => handleGenerateBatch(),
@@ -6787,13 +7215,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6787
7215
  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",
6788
7216
  style: { height: 48, background: activePrompt.trim() ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
6789
7217
  children: [
6790
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
6791
- /* @__PURE__ */ jsx30("span", { children: "Generieren" })
7218
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
7219
+ /* @__PURE__ */ jsx31("span", { children: "Generieren" })
6792
7220
  ]
6793
7221
  }
6794
7222
  ) }),
6795
- /* @__PURE__ */ jsxs28("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
6796
- /* @__PURE__ */ jsxs28(
7223
+ /* @__PURE__ */ jsxs29("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
7224
+ /* @__PURE__ */ jsxs29(
6797
7225
  "div",
6798
7226
  {
6799
7227
  className: "w-full rounded-2xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center",
@@ -6807,25 +7235,25 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6807
7235
  setTouchStartX(null);
6808
7236
  },
6809
7237
  children: [
6810
- currentResult?.status === "processing" && /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6811
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6812
- /* @__PURE__ */ jsx30("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
7238
+ currentResult?.status === "processing" && /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
7239
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
7240
+ /* @__PURE__ */ jsx31("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6813
7241
  ] }),
6814
- currentResult?.status === "error" && /* @__PURE__ */ jsxs28("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6815
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
6816
- /* @__PURE__ */ jsx30("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
6817
- /* @__PURE__ */ jsx30("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" })
7242
+ currentResult?.status === "error" && /* @__PURE__ */ jsxs29("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
7243
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
7244
+ /* @__PURE__ */ jsx31("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
7245
+ /* @__PURE__ */ jsx31("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" })
6818
7246
  ] }),
6819
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx30("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6820
- !currentResult && /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6821
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
6822
- /* @__PURE__ */ jsx30("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
7247
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx31("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
7248
+ !currentResult && /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
7249
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
7250
+ /* @__PURE__ */ jsx31("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6823
7251
  ] }),
6824
- currentResult?.status === "done" && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
6825
- history.length > 1 && currentResult && /* @__PURE__ */ jsxs28(Fragment10, { children: [
6826
- /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6827
- /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
6828
- /* @__PURE__ */ jsxs28("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: [
7252
+ currentResult?.status === "done" && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
7253
+ history.length > 1 && currentResult && /* @__PURE__ */ jsxs29(Fragment11, { children: [
7254
+ /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
7255
+ /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
7256
+ /* @__PURE__ */ jsxs29("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: [
6829
7257
  currentIndex + 1,
6830
7258
  " / ",
6831
7259
  history.length
@@ -6834,8 +7262,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6834
7262
  ]
6835
7263
  }
6836
7264
  ),
6837
- currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx30("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs28("div", { style: { position: "relative", flexShrink: 0 }, children: [
6838
- /* @__PURE__ */ jsx30(
7265
+ currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx31("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs29("div", { style: { position: "relative", flexShrink: 0 }, children: [
7266
+ /* @__PURE__ */ jsx31(
6839
7267
  "div",
6840
7268
  {
6841
7269
  onClick: () => handleGallerySelect(item),
@@ -6848,10 +7276,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6848
7276
  border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
6849
7277
  opacity: item.id === currentResult.id ? 1 : 0.55
6850
7278
  },
6851
- children: /* @__PURE__ */ jsx30("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
7279
+ children: /* @__PURE__ */ jsx31("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
6852
7280
  }
6853
7281
  ),
6854
- /* @__PURE__ */ jsx30(
7282
+ /* @__PURE__ */ jsx31(
6855
7283
  "button",
6856
7284
  {
6857
7285
  onClick: (e) => {
@@ -6873,34 +7301,34 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6873
7301
  alignItems: "center",
6874
7302
  justifyContent: "center"
6875
7303
  },
6876
- children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
7304
+ children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
6877
7305
  }
6878
7306
  )
6879
7307
  ] }, item.id)) }),
6880
- currentResult?.status === "done" && /* @__PURE__ */ jsxs28("div", { className: "flex gap-2 mt-3", children: [
6881
- /* @__PURE__ */ jsxs28("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: [
6882
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
6883
- /* @__PURE__ */ jsx30("span", { className: "text-[12px] text-white/60", children: "Prompt" })
7308
+ currentResult?.status === "done" && /* @__PURE__ */ jsxs29("div", { className: "flex gap-2 mt-3", children: [
7309
+ /* @__PURE__ */ jsxs29("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: [
7310
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
7311
+ /* @__PURE__ */ jsx31("span", { className: "text-[12px] text-white/60", children: "Prompt" })
6884
7312
  ] }),
6885
- /* @__PURE__ */ jsxs28("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: [
6886
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
6887
- /* @__PURE__ */ jsx30("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
7313
+ /* @__PURE__ */ jsxs29("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: [
7314
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
7315
+ /* @__PURE__ */ jsx31("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
6888
7316
  ] }),
6889
- /* @__PURE__ */ jsxs28("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: [
6890
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
6891
- /* @__PURE__ */ jsx30("span", { className: "text-[12px] text-white/60", children: "Laden" })
7317
+ /* @__PURE__ */ jsxs29("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: [
7318
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
7319
+ /* @__PURE__ */ jsx31("span", { className: "text-[12px] text-white/60", children: "Laden" })
6892
7320
  ] })
6893
7321
  ] })
6894
7322
  ] })
6895
7323
  ] }),
6896
- mobileTab === "browse" && /* @__PURE__ */ jsxs28("div", { className: "flex flex-col flex-1 min-h-0", children: [
6897
- /* @__PURE__ */ jsxs28("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6898
- ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
6899
- hfToken && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
7324
+ mobileTab === "browse" && /* @__PURE__ */ jsxs29("div", { className: "flex flex-col flex-1 min-h-0", children: [
7325
+ /* @__PURE__ */ jsxs29("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
7326
+ ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
7327
+ hfToken && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
6900
7328
  ] }),
6901
- /* @__PURE__ */ jsxs28("div", { className: "flex-1 overflow-hidden relative", children: [
6902
- activeTab === "history" && /* @__PURE__ */ jsx30(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) }),
6903
- activeTab === "gallery" && /* @__PURE__ */ jsx30(
7329
+ /* @__PURE__ */ jsxs29("div", { className: "flex-1 overflow-hidden relative", children: [
7330
+ activeTab === "history" && /* @__PURE__ */ jsx31(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) }),
7331
+ activeTab === "gallery" && /* @__PURE__ */ jsx31(
6904
7332
  MediaLibrary,
6905
7333
  {
6906
7334
  items: galleryItems,
@@ -6919,44 +7347,44 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6919
7347
  onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
6920
7348
  }
6921
7349
  ),
6922
- activeTab === "inspect" && /* @__PURE__ */ jsx30(InspectPanel, { currentResult, history, onSelect: (g) => {
7350
+ activeTab === "inspect" && /* @__PURE__ */ jsx31(InspectPanel, { currentResult, history, onSelect: (g) => {
6923
7351
  setCurrentResult(g);
6924
7352
  } })
6925
7353
  ] })
6926
7354
  ] }),
6927
- /* @__PURE__ */ jsxs28("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
6928
- /* @__PURE__ */ jsxs28("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
6929
- workspaceTags && /* @__PURE__ */ jsxs28("button", { onClick: () => {
7355
+ /* @__PURE__ */ jsxs29("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
7356
+ /* @__PURE__ */ jsxs29("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
7357
+ workspaceTags && /* @__PURE__ */ jsxs29("button", { onClick: () => {
6930
7358
  setLeftTab("prompt");
6931
7359
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
6932
7360
  }, 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: [
6933
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
7361
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
6934
7362
  "Prompt"
6935
7363
  ] }),
6936
- /* @__PURE__ */ jsxs28("button", { onClick: () => {
7364
+ /* @__PURE__ */ jsxs29("button", { onClick: () => {
6937
7365
  setLeftTab("hierarchy");
6938
7366
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
6939
7367
  }, 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: [
6940
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
7368
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
6941
7369
  "Hierarchie"
6942
7370
  ] }),
6943
- /* @__PURE__ */ jsxs28("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: [
6944
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
7371
+ /* @__PURE__ */ jsxs29("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: [
7372
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
6945
7373
  "Setup"
6946
7374
  ] }),
6947
- /* @__PURE__ */ jsxs28("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: [
6948
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
7375
+ /* @__PURE__ */ jsxs29("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: [
7376
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
6949
7377
  "Sync"
6950
7378
  ] }),
6951
- /* @__PURE__ */ jsxs28("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: [
6952
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
7379
+ /* @__PURE__ */ jsxs29("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: [
7380
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
6953
7381
  "HF"
6954
7382
  ] }),
6955
- serverBaseUrl && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
6956
- workspaceTags && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
7383
+ serverBaseUrl && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
7384
+ workspaceTags && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
6957
7385
  ] }),
6958
- /* @__PURE__ */ jsxs28("div", { className: "flex-1 overflow-hidden relative", children: [
6959
- leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ jsx30("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx30(
7386
+ /* @__PURE__ */ jsxs29("div", { className: "flex-1 overflow-hidden relative", children: [
7387
+ leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ jsx31("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx31(
6960
7388
  ListView,
6961
7389
  {
6962
7390
  nodes,
@@ -6987,19 +7415,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6987
7415
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
6988
7416
  }
6989
7417
  ) }),
6990
- workspaceTags && /* @__PURE__ */ jsx30("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ jsx30(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
7418
+ workspaceTags && /* @__PURE__ */ jsx31("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ jsx31(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
6991
7419
  handleGenerateBatch(prompt);
6992
7420
  setMobileTab("stage");
6993
7421
  }, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
6994
- activeTab === "setup" && /* @__PURE__ */ jsx30(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
6995
- activeTab === "sync" && /* @__PURE__ */ jsx30(
7422
+ activeTab === "setup" && /* @__PURE__ */ jsx31(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
7423
+ activeTab === "sync" && /* @__PURE__ */ jsx31(
6996
7424
  HfMediaSyncTab,
6997
7425
  {
6998
7426
  topSlot: syncTopSlot,
6999
7427
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
7000
7428
  }
7001
7429
  ),
7002
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx30(
7430
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx31(
7003
7431
  TagManagerPanel,
7004
7432
  {
7005
7433
  workspaceTags,
@@ -7010,7 +7438,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7010
7438
  onTagMove: handleTagMove
7011
7439
  }
7012
7440
  ),
7013
- activeTab === "hftest" && /* @__PURE__ */ jsx30("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx30(
7441
+ activeTab === "hftest" && /* @__PURE__ */ jsx31("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx31(
7014
7442
  HFTestTab,
7015
7443
  {
7016
7444
  token: hfToken,
@@ -7022,10 +7450,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7022
7450
  missingImages: hfMissingImages
7023
7451
  }
7024
7452
  ) }),
7025
- activeTab === "server" && /* @__PURE__ */ jsx30("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx30(ServerTab, { serverBaseUrl }) })
7453
+ activeTab === "server" && /* @__PURE__ */ jsx31("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx31(ServerTab, { serverBaseUrl }) })
7026
7454
  ] })
7027
7455
  ] }),
7028
- /* @__PURE__ */ jsx30("div", { className: "flex overflow-x-auto border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
7456
+ /* @__PURE__ */ jsx31("div", { className: "flex overflow-x-auto border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
7029
7457
  { id: "tools", icon: "auto_fix_high", label: "Prompt" },
7030
7458
  { id: "szenen", icon: "movie", label: "Szenen" },
7031
7459
  { id: "stage", icon: "palette", label: "Stage" },
@@ -7033,13 +7461,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7033
7461
  ...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
7034
7462
  { id: "browse", icon: "photo_library", label: "Galerie" },
7035
7463
  ...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
7036
- ].map((tab) => /* @__PURE__ */ jsxs28("button", { onClick: () => setMobileTab(tab.id), className: `flex-none min-w-[64px] flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
7037
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
7038
- /* @__PURE__ */ jsx30("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
7464
+ ].map((tab) => /* @__PURE__ */ jsxs29("button", { onClick: () => setMobileTab(tab.id), className: `flex-none min-w-[64px] flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
7465
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
7466
+ /* @__PURE__ */ jsx31("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
7039
7467
  ] }, tab.id)) })
7040
7468
  ] });
7041
7469
  if (mdMode) {
7042
- return /* @__PURE__ */ jsx30("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
7470
+ return /* @__PURE__ */ jsx31("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
7043
7471
  }
7044
7472
  return mobileRoot;
7045
7473
  }
@@ -7047,20 +7475,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7047
7475
  const tlScale = Math.min(window.innerWidth / 920, window.innerHeight / 520);
7048
7476
  const tlW = 920;
7049
7477
  const tlH = 520;
7050
- return /* @__PURE__ */ jsx30("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ jsxs28("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
7051
- /* @__PURE__ */ jsxs28("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
7052
- /* @__PURE__ */ jsxs28("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: [
7053
- /* @__PURE__ */ jsx30(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
7054
- /* @__PURE__ */ jsx30(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" }] }),
7055
- /* @__PURE__ */ jsx30(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
7056
- /* @__PURE__ */ jsx30("div", { style: { flex: 1 } }),
7057
- /* @__PURE__ */ jsx30(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7478
+ return /* @__PURE__ */ jsx31("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ jsxs29("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
7479
+ /* @__PURE__ */ jsxs29("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
7480
+ /* @__PURE__ */ jsxs29("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: [
7481
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
7482
+ /* @__PURE__ */ jsx31(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" }] }),
7483
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
7484
+ /* @__PURE__ */ jsx31("div", { style: { flex: 1 } }),
7485
+ /* @__PURE__ */ jsx31(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7058
7486
  runningBadge,
7059
- /* @__PURE__ */ jsx30("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
7060
- /* @__PURE__ */ jsx30("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
7487
+ /* @__PURE__ */ jsx31("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
7488
+ /* @__PURE__ */ jsx31("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
7061
7489
  ] }),
7062
- /* @__PURE__ */ jsx30("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs28("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: [
7063
- /* @__PURE__ */ jsx30(
7490
+ /* @__PURE__ */ jsx31("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs29("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: [
7491
+ /* @__PURE__ */ jsx31(
7064
7492
  "textarea",
7065
7493
  {
7066
7494
  value: activePrompt,
@@ -7069,24 +7497,24 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7069
7497
  placeholder: "Prompt eingeben..."
7070
7498
  }
7071
7499
  ),
7072
- activePrompt && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
7500
+ activePrompt && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
7073
7501
  ] }) }),
7074
- /* @__PURE__ */ jsx30("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs28(
7502
+ /* @__PURE__ */ jsx31("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs29(
7075
7503
  "button",
7076
7504
  {
7077
7505
  onClick: () => handleGenerateBatch(),
7078
7506
  disabled: !activePrompt.trim(),
7079
7507
  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" },
7080
7508
  children: [
7081
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
7082
- /* @__PURE__ */ jsx30("span", { children: "Generieren" })
7509
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
7510
+ /* @__PURE__ */ jsx31("span", { children: "Generieren" })
7083
7511
  ]
7084
7512
  }
7085
7513
  ) }),
7086
- /* @__PURE__ */ jsx30("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx30(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) }) })
7514
+ /* @__PURE__ */ jsx31("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx31(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) }) })
7087
7515
  ] }),
7088
- /* @__PURE__ */ jsxs28("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
7089
- /* @__PURE__ */ jsx30(
7516
+ /* @__PURE__ */ jsxs29("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
7517
+ /* @__PURE__ */ jsx31(
7090
7518
  "div",
7091
7519
  {
7092
7520
  style: { flex: 1, padding: 16, display: "flex", alignItems: "center", justifyContent: "center", position: "relative" },
@@ -7098,26 +7526,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7098
7526
  else if (dx > 50) goToPrev();
7099
7527
  setTouchStartX(null);
7100
7528
  },
7101
- children: /* @__PURE__ */ jsxs28("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: [
7102
- currentResult?.status === "processing" && /* @__PURE__ */ jsxs28("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
7103
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
7104
- /* @__PURE__ */ jsx30("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
7529
+ children: /* @__PURE__ */ jsxs29("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: [
7530
+ currentResult?.status === "processing" && /* @__PURE__ */ jsxs29("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
7531
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
7532
+ /* @__PURE__ */ jsx31("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
7105
7533
  ] }),
7106
- currentResult?.status === "error" && /* @__PURE__ */ jsxs28("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
7107
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
7108
- /* @__PURE__ */ jsx30("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
7109
- /* @__PURE__ */ jsx30("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" })
7534
+ currentResult?.status === "error" && /* @__PURE__ */ jsxs29("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
7535
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
7536
+ /* @__PURE__ */ jsx31("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
7537
+ /* @__PURE__ */ jsx31("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" })
7110
7538
  ] }),
7111
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx30("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
7112
- !currentResult && /* @__PURE__ */ jsxs28("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
7113
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
7114
- /* @__PURE__ */ jsx30("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
7539
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx31("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
7540
+ !currentResult && /* @__PURE__ */ jsxs29("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
7541
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
7542
+ /* @__PURE__ */ jsx31("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
7115
7543
  ] }),
7116
- currentResult?.status === "done" && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
7117
- history.length > 1 && currentResult && /* @__PURE__ */ jsxs28(Fragment10, { children: [
7118
- /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
7119
- /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
7120
- /* @__PURE__ */ jsxs28("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: [
7544
+ currentResult?.status === "done" && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
7545
+ history.length > 1 && currentResult && /* @__PURE__ */ jsxs29(Fragment11, { children: [
7546
+ /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
7547
+ /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
7548
+ /* @__PURE__ */ jsxs29("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: [
7121
7549
  currentIndex + 1,
7122
7550
  " / ",
7123
7551
  history.length
@@ -7126,42 +7554,42 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7126
7554
  ] })
7127
7555
  }
7128
7556
  ),
7129
- currentResult?.status === "done" && /* @__PURE__ */ jsxs28("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
7130
- /* @__PURE__ */ jsxs28("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: [
7131
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
7132
- /* @__PURE__ */ jsx30("span", { children: "Prompt" })
7557
+ currentResult?.status === "done" && /* @__PURE__ */ jsxs29("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
7558
+ /* @__PURE__ */ jsxs29("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: [
7559
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
7560
+ /* @__PURE__ */ jsx31("span", { children: "Prompt" })
7133
7561
  ] }),
7134
- /* @__PURE__ */ jsxs28("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: [
7135
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
7136
- /* @__PURE__ */ jsx30("span", { children: "Referenz" })
7562
+ /* @__PURE__ */ jsxs29("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: [
7563
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
7564
+ /* @__PURE__ */ jsx31("span", { children: "Referenz" })
7137
7565
  ] }),
7138
- /* @__PURE__ */ jsxs28("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: [
7139
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
7140
- /* @__PURE__ */ jsx30("span", { children: "Laden" })
7566
+ /* @__PURE__ */ jsxs29("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: [
7567
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
7568
+ /* @__PURE__ */ jsx31("span", { children: "Laden" })
7141
7569
  ] })
7142
7570
  ] })
7143
7571
  ] })
7144
7572
  ] }) });
7145
7573
  }
7146
- return /* @__PURE__ */ jsxs28("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
7147
- /* @__PURE__ */ jsx30("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ jsx30("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
7148
- /* @__PURE__ */ jsxs28("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: [
7149
- /* @__PURE__ */ jsxs28("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
7150
- !isLeftCollapsed && /* @__PURE__ */ jsxs28("div", { className: "flex flex-1 gap-1", children: [
7151
- workspaceTags && /* @__PURE__ */ jsxs28("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: [
7152
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
7574
+ return /* @__PURE__ */ jsxs29("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
7575
+ /* @__PURE__ */ jsx31("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ jsx31("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
7576
+ /* @__PURE__ */ jsxs29("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: [
7577
+ /* @__PURE__ */ jsxs29("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
7578
+ !isLeftCollapsed && /* @__PURE__ */ jsxs29("div", { className: "flex flex-1 gap-1", children: [
7579
+ workspaceTags && /* @__PURE__ */ jsxs29("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: [
7580
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
7153
7581
  "Prompt"
7154
7582
  ] }),
7155
- /* @__PURE__ */ jsxs28("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: [
7156
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
7583
+ /* @__PURE__ */ jsxs29("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: [
7584
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
7157
7585
  "Hierarchie"
7158
7586
  ] }),
7159
- workspaceTags && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
7587
+ workspaceTags && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
7160
7588
  ] }),
7161
- /* @__PURE__ */ jsx30("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" })
7589
+ /* @__PURE__ */ jsx31("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" })
7162
7590
  ] }),
7163
- !isLeftCollapsed && /* @__PURE__ */ jsxs28("div", { className: "flex-1 overflow-hidden relative", children: [
7164
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx30(
7591
+ !isLeftCollapsed && /* @__PURE__ */ jsxs29("div", { className: "flex-1 overflow-hidden relative", children: [
7592
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx31(
7165
7593
  TagManagerPanel,
7166
7594
  {
7167
7595
  workspaceTags,
@@ -7172,11 +7600,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7172
7600
  onTagMove: handleTagMove
7173
7601
  }
7174
7602
  ),
7175
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx30("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs28("div", { children: [
7176
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7177
- /* @__PURE__ */ jsx30("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7603
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs29("div", { children: [
7604
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7605
+ /* @__PURE__ */ jsx31("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7178
7606
  ] }) }),
7179
- leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ jsx30("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx30(
7607
+ leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ jsx31("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx31(
7180
7608
  ListView,
7181
7609
  {
7182
7610
  nodes,
@@ -7201,19 +7629,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7201
7629
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
7202
7630
  }
7203
7631
  ) }),
7204
- leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ jsx30(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 })
7632
+ leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ jsx31(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 })
7205
7633
  ] })
7206
7634
  ] }),
7207
- !isLeftCollapsed && /* @__PURE__ */ jsx30("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
7208
- /* @__PURE__ */ jsxs28("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
7209
- /* @__PURE__ */ jsxs28("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
7210
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1.5", children: [
7211
- /* @__PURE__ */ jsx30(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
7212
- /* @__PURE__ */ jsx30(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" }] }),
7213
- /* @__PURE__ */ jsx30(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
7635
+ !isLeftCollapsed && /* @__PURE__ */ jsx31("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
7636
+ /* @__PURE__ */ jsxs29("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
7637
+ /* @__PURE__ */ jsxs29("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
7638
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1.5", children: [
7639
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
7640
+ /* @__PURE__ */ jsx31(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" }] }),
7641
+ /* @__PURE__ */ jsx31(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
7214
7642
  ] }),
7215
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1 mx-auto", children: [
7216
- /* @__PURE__ */ jsx30(
7643
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1 mx-auto", children: [
7644
+ /* @__PURE__ */ jsx31(
7217
7645
  "button",
7218
7646
  {
7219
7647
  onClick: () => setMiddlePanel("stage"),
@@ -7221,7 +7649,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7221
7649
  children: "Stage"
7222
7650
  }
7223
7651
  ),
7224
- /* @__PURE__ */ jsx30(
7652
+ /* @__PURE__ */ jsx31(
7225
7653
  "button",
7226
7654
  {
7227
7655
  onClick: () => setMiddlePanel("labs"),
@@ -7229,7 +7657,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7229
7657
  children: "Labs"
7230
7658
  }
7231
7659
  ),
7232
- /* @__PURE__ */ jsx30(
7660
+ /* @__PURE__ */ jsx31(
7233
7661
  "button",
7234
7662
  {
7235
7663
  onClick: () => setMiddlePanel("szenen"),
@@ -7238,53 +7666,53 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7238
7666
  }
7239
7667
  )
7240
7668
  ] }),
7241
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2", children: [
7242
- activeReferenceThumbnail ? /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
7243
- /* @__PURE__ */ jsx30("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
7244
- /* @__PURE__ */ jsx30("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
7245
- /* @__PURE__ */ jsx30("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
7246
- ] }) : /* @__PURE__ */ jsxs28("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: [
7247
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
7248
- /* @__PURE__ */ jsx30("span", { children: "Ref" })
7669
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
7670
+ activeReferenceThumbnail ? /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
7671
+ /* @__PURE__ */ jsx31("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
7672
+ /* @__PURE__ */ jsx31("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
7673
+ /* @__PURE__ */ jsx31("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
7674
+ ] }) : /* @__PURE__ */ jsxs29("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: [
7675
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
7676
+ /* @__PURE__ */ jsx31("span", { children: "Ref" })
7249
7677
  ] }),
7250
- /* @__PURE__ */ jsx30("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
7251
- /* @__PURE__ */ jsx30(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7678
+ /* @__PURE__ */ jsx31("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
7679
+ /* @__PURE__ */ jsx31(TaskExecutor, { openTasks: hfState?.openTasks || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7252
7680
  runningBadge,
7253
- /* @__PURE__ */ jsx30(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
7681
+ /* @__PURE__ */ jsx31(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
7254
7682
  ] })
7255
7683
  ] }),
7256
- /* @__PURE__ */ jsxs28("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
7257
- !isPromptCollapsed && /* @__PURE__ */ jsx30("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ jsxs28("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
7258
- /* @__PURE__ */ jsx30("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..." }),
7259
- activePrompt && !isSynthesizing && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
7684
+ /* @__PURE__ */ jsxs29("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
7685
+ !isPromptCollapsed && /* @__PURE__ */ jsx31("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ jsxs29("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
7686
+ /* @__PURE__ */ jsx31("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..." }),
7687
+ activePrompt && !isSynthesizing && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
7260
7688
  ] }) }),
7261
- middlePanel === "szenen" ? szenenPane : middlePanel === "labs" ? /* @__PURE__ */ jsx30("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx30(LabsTab, { services: labServices, onResult: (item) => {
7689
+ middlePanel === "szenen" ? szenenPane : middlePanel === "labs" ? /* @__PURE__ */ jsx31("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx31(LabsTab, { services: labServices, onResult: (item) => {
7262
7690
  const frame = item.frames[0];
7263
7691
  if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
7264
- } }) }) : /* @__PURE__ */ jsxs28("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
7265
- /* @__PURE__ */ jsx30("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ jsx30("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__ */ jsxs28("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
7266
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
7267
- /* @__PURE__ */ jsx30("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
7268
- ] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs28("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
7269
- /* @__PURE__ */ jsx30("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
7270
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2", children: [
7271
- /* @__PURE__ */ jsx30("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
7272
- /* @__PURE__ */ jsx30("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
7692
+ } }) }) : /* @__PURE__ */ jsxs29("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
7693
+ /* @__PURE__ */ jsx31("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ jsx31("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__ */ jsxs29("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
7694
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
7695
+ /* @__PURE__ */ jsx31("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
7696
+ ] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs29("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
7697
+ /* @__PURE__ */ jsx31("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
7698
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-2", children: [
7699
+ /* @__PURE__ */ jsx31("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
7700
+ /* @__PURE__ */ jsx31("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
7273
7701
  ] }),
7274
- /* @__PURE__ */ jsx30(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
7275
- ] }) : /* @__PURE__ */ jsxs28("div", { className: "h-full w-full relative flex items-center justify-center", children: [
7276
- /* @__PURE__ */ jsx30("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
7277
- /* @__PURE__ */ jsxs28("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: [
7278
- /* @__PURE__ */ jsx30(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
7279
- /* @__PURE__ */ jsx30(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
7280
- /* @__PURE__ */ jsx30(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
7702
+ /* @__PURE__ */ jsx31(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
7703
+ ] }) : /* @__PURE__ */ jsxs29("div", { className: "h-full w-full relative flex items-center justify-center", children: [
7704
+ /* @__PURE__ */ jsx31("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
7705
+ /* @__PURE__ */ jsxs29("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: [
7706
+ /* @__PURE__ */ jsx31(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
7707
+ /* @__PURE__ */ jsx31(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
7708
+ /* @__PURE__ */ jsx31(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
7281
7709
  ] })
7282
- ] }) : /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
7283
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
7284
- /* @__PURE__ */ jsx30("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
7710
+ ] }) : /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
7711
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
7712
+ /* @__PURE__ */ jsx31("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
7285
7713
  ] }) }) }),
7286
- currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx30("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs28("div", { style: { position: "relative", flexShrink: 0 }, children: [
7287
- /* @__PURE__ */ jsx30(
7714
+ currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx31("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs29("div", { style: { position: "relative", flexShrink: 0 }, children: [
7715
+ /* @__PURE__ */ jsx31(
7288
7716
  "div",
7289
7717
  {
7290
7718
  onClick: () => handleGallerySelect(item),
@@ -7299,10 +7727,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7299
7727
  transition: "opacity 0.15s, border-color 0.15s"
7300
7728
  },
7301
7729
  className: "hover:opacity-80",
7302
- children: /* @__PURE__ */ jsx30("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
7730
+ children: /* @__PURE__ */ jsx31("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
7303
7731
  }
7304
7732
  ),
7305
- /* @__PURE__ */ jsx30(
7733
+ /* @__PURE__ */ jsx31(
7306
7734
  "button",
7307
7735
  {
7308
7736
  onClick: (e) => {
@@ -7325,31 +7753,31 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7325
7753
  alignItems: "center",
7326
7754
  justifyContent: "center"
7327
7755
  },
7328
- children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
7756
+ children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
7329
7757
  }
7330
7758
  )
7331
7759
  ] }, item.id)) })
7332
7760
  ] })
7333
7761
  ] })
7334
7762
  ] }),
7335
- !isRightCollapsed && /* @__PURE__ */ jsx30("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
7336
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
7337
- /* @__PURE__ */ jsxs28("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
7338
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-1", children: [
7339
- ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ jsx30("button", { onClick: () => {
7763
+ !isRightCollapsed && /* @__PURE__ */ jsx31("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
7764
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
7765
+ /* @__PURE__ */ jsxs29("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
7766
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-1", children: [
7767
+ ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ jsx31("button", { onClick: () => {
7340
7768
  setActiveTab(tab);
7341
7769
  setIsRightCollapsed(false);
7342
- }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx30("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)),
7343
- serverBaseUrl && /* @__PURE__ */ jsx30("button", { onClick: () => {
7770
+ }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx31("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)),
7771
+ serverBaseUrl && /* @__PURE__ */ jsx31("button", { onClick: () => {
7344
7772
  setActiveTab("server");
7345
7773
  setIsRightCollapsed(false);
7346
- }, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
7774
+ }, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
7347
7775
  ] }),
7348
- hfToken && /* @__PURE__ */ jsx30("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__ */ jsx30("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
7349
- /* @__PURE__ */ jsx30("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
7776
+ hfToken && /* @__PURE__ */ jsx31("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__ */ jsx31("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
7777
+ /* @__PURE__ */ jsx31("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
7350
7778
  ] }),
7351
- !isRightCollapsed && /* @__PURE__ */ jsxs28("div", { className: "flex-1 overflow-hidden relative", children: [
7352
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx30(
7779
+ !isRightCollapsed && /* @__PURE__ */ jsxs29("div", { className: "flex-1 overflow-hidden relative", children: [
7780
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx31(
7353
7781
  TagManagerPanel,
7354
7782
  {
7355
7783
  workspaceTags,
@@ -7360,12 +7788,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7360
7788
  onTagMove: handleTagMove
7361
7789
  }
7362
7790
  ),
7363
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx30("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs28("div", { children: [
7364
- /* @__PURE__ */ jsx30("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7365
- /* @__PURE__ */ jsx30("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7791
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs29("div", { children: [
7792
+ /* @__PURE__ */ jsx31("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7793
+ /* @__PURE__ */ jsx31("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7366
7794
  ] }) }),
7367
- activeTab === "history" && /* @__PURE__ */ jsx30(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) }),
7368
- activeTab === "gallery" && /* @__PURE__ */ jsx30(
7795
+ activeTab === "history" && /* @__PURE__ */ jsx31(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) }),
7796
+ activeTab === "gallery" && /* @__PURE__ */ jsx31(
7369
7797
  MediaLibrary,
7370
7798
  {
7371
7799
  items: galleryItems,
@@ -7381,24 +7809,24 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7381
7809
  onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
7382
7810
  }
7383
7811
  ),
7384
- activeTab === "inspect" && /* @__PURE__ */ jsx30(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
7385
- activeTab === "setup" && /* @__PURE__ */ jsx30(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
7386
- activeTab === "sync" && /* @__PURE__ */ jsx30(
7812
+ activeTab === "inspect" && /* @__PURE__ */ jsx31(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
7813
+ activeTab === "setup" && /* @__PURE__ */ jsx31(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
7814
+ activeTab === "sync" && /* @__PURE__ */ jsx31(
7387
7815
  HfMediaSyncTab,
7388
7816
  {
7389
7817
  topSlot: syncTopSlot,
7390
7818
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
7391
7819
  }
7392
7820
  ),
7393
- activeTab === "server" && /* @__PURE__ */ jsx30(ServerTab, { serverBaseUrl })
7821
+ activeTab === "server" && /* @__PURE__ */ jsx31(ServerTab, { serverBaseUrl })
7394
7822
  ] })
7395
7823
  ] })
7396
7824
  ] });
7397
7825
  }
7398
7826
 
7399
7827
  // src/components/FaApp.tsx
7400
- import { useState as useState27, useEffect as useEffect12, useMemo as useMemo8 } from "react";
7401
- import { jsx as jsx31 } from "react/jsx-runtime";
7828
+ import { useState as useState28, useEffect as useEffect13, useMemo as useMemo9 } from "react";
7829
+ import { jsx as jsx32 } from "react/jsx-runtime";
7402
7830
  function FaApp({
7403
7831
  onGenerateImage,
7404
7832
  onGeneratePrompt,
@@ -7413,19 +7841,19 @@ function FaApp({
7413
7841
  serverBaseUrl,
7414
7842
  buildInfo
7415
7843
  }) {
7416
- const [hfNamespace, setHfNamespace] = useState27(void 0);
7417
- useEffect12(() => {
7844
+ const [hfNamespace, setHfNamespace] = useState28(void 0);
7845
+ useEffect13(() => {
7418
7846
  if (!serverBaseUrl) return;
7419
7847
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
7420
7848
  if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
7421
7849
  }).catch(() => {
7422
7850
  });
7423
7851
  }, [serverBaseUrl]);
7424
- const wrappedPrompt = useMemo8(
7852
+ const wrappedPrompt = useMemo9(
7425
7853
  () => alsFlowTextZugang(onGeneratePrompt),
7426
7854
  [onGeneratePrompt]
7427
7855
  );
7428
- return /* @__PURE__ */ jsx31(
7856
+ return /* @__PURE__ */ jsx32(
7429
7857
  AvatarArchitectApp,
7430
7858
  {
7431
7859
  onGenerateImage,
@@ -7675,15 +8103,15 @@ function createInMemoryWorkspacePersistence(now = () => Date.now()) {
7675
8103
  }
7676
8104
 
7677
8105
  // node_modules/zustand/esm/react.mjs
7678
- import React24 from "react";
8106
+ import React25 from "react";
7679
8107
  var identity = (arg) => arg;
7680
8108
  function useStore(api, selector = identity) {
7681
- const slice = React24.useSyncExternalStore(
8109
+ const slice = React25.useSyncExternalStore(
7682
8110
  api.subscribe,
7683
- React24.useCallback(() => selector(api.getState()), [api, selector]),
7684
- React24.useCallback(() => selector(api.getInitialState()), [api, selector])
8111
+ React25.useCallback(() => selector(api.getState()), [api, selector]),
8112
+ React25.useCallback(() => selector(api.getInitialState()), [api, selector])
7685
8113
  );
7686
- React24.useDebugValue(slice);
8114
+ React25.useDebugValue(slice);
7687
8115
  return slice;
7688
8116
  }
7689
8117
 
@@ -7987,7 +8415,7 @@ function zugehoerigkeitenOf(item) {
7987
8415
  }
7988
8416
 
7989
8417
  // src/features/library/ZugehoerigkeitLinks.tsx
7990
- import { Fragment as Fragment11, jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
8418
+ import { Fragment as Fragment12, jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
7991
8419
  var CHIP_BASIS = "text-[9px] px-1.5 py-0.5 rounded-full font-bold border transition";
7992
8420
  var CHIP_LAUF = "bg-teal-900/60 text-teal-200 border-teal-800 hover:bg-teal-800 hover:text-white";
7993
8421
  var CHIP_SZENE = "bg-indigo-900/60 text-indigo-200 border-indigo-800 hover:bg-indigo-800 hover:text-white";
@@ -8013,8 +8441,8 @@ var ZugehoerigkeitLinks = ({
8013
8441
  };
8014
8442
  if (variante === "liste") {
8015
8443
  if (!hatNavigationsziele(zugehoerigkeit)) return null;
8016
- return /* @__PURE__ */ jsxs29(Fragment11, { children: [
8017
- run && /* @__PURE__ */ jsx32(
8444
+ return /* @__PURE__ */ jsxs30(Fragment12, { children: [
8445
+ run && /* @__PURE__ */ jsx33(
8018
8446
  "button",
8019
8447
  {
8020
8448
  type: "button",
@@ -8025,7 +8453,7 @@ var ZugehoerigkeitLinks = ({
8025
8453
  children: beschriftung(run, "Promptlauf")
8026
8454
  }
8027
8455
  ),
8028
- scene && /* @__PURE__ */ jsx32(
8456
+ scene && /* @__PURE__ */ jsx33(
8029
8457
  "button",
8030
8458
  {
8031
8459
  type: "button",
@@ -8038,15 +8466,15 @@ var ZugehoerigkeitLinks = ({
8038
8466
  )
8039
8467
  ] });
8040
8468
  }
8041
- return /* @__PURE__ */ jsxs29(
8469
+ return /* @__PURE__ */ jsxs30(
8042
8470
  "div",
8043
8471
  {
8044
8472
  className: "bg-black border border-neutral-800 p-2 rounded flex flex-col gap-1",
8045
8473
  "data-testid": "zugehoerigkeit-bereich",
8046
8474
  children: [
8047
- /* @__PURE__ */ jsx32("span", { className: "text-[10px] uppercase font-bold text-neutral-500", children: "Zugeh\xF6rigkeit" }),
8048
- /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap gap-2", children: [
8049
- run && /* @__PURE__ */ jsx32(
8475
+ /* @__PURE__ */ jsx33("span", { className: "text-[10px] uppercase font-bold text-neutral-500", children: "Zugeh\xF6rigkeit" }),
8476
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap gap-2", children: [
8477
+ run && /* @__PURE__ */ jsx33(
8050
8478
  "button",
8051
8479
  {
8052
8480
  type: "button",
@@ -8057,7 +8485,7 @@ var ZugehoerigkeitLinks = ({
8057
8485
  children: beschriftung(run, "Promptlauf \xF6ffnen")
8058
8486
  }
8059
8487
  ),
8060
- scene && /* @__PURE__ */ jsx32(
8488
+ scene && /* @__PURE__ */ jsx33(
8061
8489
  "button",
8062
8490
  {
8063
8491
  type: "button",
@@ -8069,7 +8497,7 @@ var ZugehoerigkeitLinks = ({
8069
8497
  }
8070
8498
  )
8071
8499
  ] }),
8072
- hinweis && /* @__PURE__ */ jsx32("span", { className: "text-[10px] text-neutral-500", "data-testid": "zugehoerigkeit-hinweis", children: hinweis })
8500
+ hinweis && /* @__PURE__ */ jsx33("span", { className: "text-[10px] text-neutral-500", "data-testid": "zugehoerigkeit-hinweis", children: hinweis })
8073
8501
  ]
8074
8502
  }
8075
8503
  );
@@ -8152,6 +8580,8 @@ export {
8152
8580
  CURRENT_TAG_EVENT_VERSION,
8153
8581
  CollapsibleCard,
8154
8582
  CompactDropdown,
8583
+ FLOW_PROBE_MARKER,
8584
+ FLOW_PROBE_REQUEST,
8155
8585
  FaApp,
8156
8586
  FaToolsBadge,
8157
8587
  FlowBridgePanel,
@@ -8209,6 +8639,7 @@ export {
8209
8639
  createTagsDefault,
8210
8640
  deriveTagBaseWorkspaceTags,
8211
8641
  deriveTagViewModel,
8642
+ executeFlowProbeBundle,
8212
8643
  formatTreeToMarkdown,
8213
8644
  frameToGeneration,
8214
8645
  getFormattedTimestamp,
@@ -8234,6 +8665,7 @@ export {
8234
8665
  parseLegacyRecentTags,
8235
8666
  parsePromptFile,
8236
8667
  parsePromptResponse,
8668
+ readFlowProbeBundle,
8237
8669
  runLegacyMigration,
8238
8670
  runLibraryLegacyImport,
8239
8671
  runTagsLegacyImport,