@rslsp1/fa-app-tools 5.1.0 → 6.1.0
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/{chunk-3MUI4ZV7.mjs → chunk-GHKN2VX3.mjs} +597 -65
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +573 -54
- package/dist/index.mjs +3 -3
- package/dist/szenen.d.mts +195 -2
- package/dist/szenen.d.ts +195 -2
- package/dist/szenen.js +697 -115
- package/dist/szenen.mjs +63 -3
- package/package.json +1 -1
|
@@ -5225,6 +5225,133 @@ function findPromptRun(events, runId) {
|
|
|
5225
5225
|
return collectPromptRuns(events).find((run) => run.run_id === runId) ?? null;
|
|
5226
5226
|
}
|
|
5227
5227
|
|
|
5228
|
+
// src/lib/szenen/seedListe.ts
|
|
5229
|
+
var DEFAULT_SEED_VORLAGE = {
|
|
5230
|
+
name: "Default",
|
|
5231
|
+
seeds: "1; 10; 100; 1000",
|
|
5232
|
+
builtin: true
|
|
5233
|
+
};
|
|
5234
|
+
function parseSeedListe(eingabe) {
|
|
5235
|
+
if (!eingabe) return [];
|
|
5236
|
+
return eingabe.split(/[,;]/).map((teil) => teil.trim()).filter((teil) => teil.length > 0);
|
|
5237
|
+
}
|
|
5238
|
+
function formatSeedListe(tokens) {
|
|
5239
|
+
return tokens.join("; ");
|
|
5240
|
+
}
|
|
5241
|
+
var GANZZAHL = /^-?\d+$/;
|
|
5242
|
+
function ordneSeedsZu(eingabe, anzahl) {
|
|
5243
|
+
const tokens = Array.isArray(eingabe) ? [...eingabe] : parseSeedListe(eingabe);
|
|
5244
|
+
const eintraege = [];
|
|
5245
|
+
for (let position = 0; position < anzahl; position++) {
|
|
5246
|
+
const roh = tokens[position] ?? null;
|
|
5247
|
+
if (roh === null) {
|
|
5248
|
+
eintraege.push({ position, roh: null, seed: null, ungueltig: false });
|
|
5249
|
+
continue;
|
|
5250
|
+
}
|
|
5251
|
+
const zahl = GANZZAHL.test(roh) ? Number(roh) : Number.NaN;
|
|
5252
|
+
const gueltig = Number.isSafeInteger(zahl);
|
|
5253
|
+
eintraege.push({
|
|
5254
|
+
position,
|
|
5255
|
+
roh,
|
|
5256
|
+
seed: gueltig ? zahl : null,
|
|
5257
|
+
ungueltig: !gueltig
|
|
5258
|
+
});
|
|
5259
|
+
}
|
|
5260
|
+
return {
|
|
5261
|
+
eintraege,
|
|
5262
|
+
ungueltige: eintraege.filter((e) => e.ungueltig),
|
|
5263
|
+
ueberzaehlig: Math.max(0, tokens.length - anzahl)
|
|
5264
|
+
};
|
|
5265
|
+
}
|
|
5266
|
+
function seedFehlerText(ungueltige) {
|
|
5267
|
+
const teile = ungueltige.map((e) => `Bild ${e.position + 1}: "${e.roh}"`);
|
|
5268
|
+
return `Die Seedliste enth\xE4lt keine ganze Zahl an ${teile.length === 1 ? "Position" : "Positionen"} \u2014 ${teile.join(", ")}. Kein Bild wurde importiert.`;
|
|
5269
|
+
}
|
|
5270
|
+
function mitDefaultVorlage(custom) {
|
|
5271
|
+
return [DEFAULT_SEED_VORLAGE, ...custom.filter((v) => !v.builtin)];
|
|
5272
|
+
}
|
|
5273
|
+
|
|
5274
|
+
// src/lib/szenen/zipBilder.ts
|
|
5275
|
+
var BILD_ENDUNGEN = {
|
|
5276
|
+
png: "image/png",
|
|
5277
|
+
jpg: "image/jpeg",
|
|
5278
|
+
jpeg: "image/jpeg",
|
|
5279
|
+
webp: "image/webp"
|
|
5280
|
+
};
|
|
5281
|
+
var UPLOAD_MAX_BYTES = 45 * 1024 * 1024;
|
|
5282
|
+
function byteLaenge(base64) {
|
|
5283
|
+
const fuellzeichen = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
|
|
5284
|
+
return Math.floor(base64.length * 3 / 4) - fuellzeichen;
|
|
5285
|
+
}
|
|
5286
|
+
function angekuendigteGroesse(eintrag) {
|
|
5287
|
+
const roh = eintrag._data?.uncompressedSize;
|
|
5288
|
+
return typeof roh === "number" && Number.isFinite(roh) && roh >= 0 ? roh : null;
|
|
5289
|
+
}
|
|
5290
|
+
function bildGroesseVerdikt(archiv, pfad, bytes) {
|
|
5291
|
+
if (bytes === null || bytes <= UPLOAD_MAX_BYTES) return null;
|
|
5292
|
+
return `${archiv}: Das Bild ${pfad} ist entpackt ${mb(bytes)} MB gro\xDF \u2014 die Grenze f\xFCr eine einzelne Bilddatei liegt bei ${UPLOAD_MAX_BYTES / 1024 / 1024} MB. Kein Bild wurde importiert.`;
|
|
5293
|
+
}
|
|
5294
|
+
function mb(bytes) {
|
|
5295
|
+
return (bytes / 1024 / 1024).toFixed(1);
|
|
5296
|
+
}
|
|
5297
|
+
function istZipDatei(datei) {
|
|
5298
|
+
return /\.zip$/i.test(datei.name);
|
|
5299
|
+
}
|
|
5300
|
+
function endungVon(pfad) {
|
|
5301
|
+
const punkt = pfad.lastIndexOf(".");
|
|
5302
|
+
return punkt >= 0 ? pfad.slice(punkt + 1).toLowerCase() : "";
|
|
5303
|
+
}
|
|
5304
|
+
function istImportierbar(pfad, istVerzeichnis) {
|
|
5305
|
+
if (istVerzeichnis) return false;
|
|
5306
|
+
if (pfad.startsWith("__MACOSX/")) return false;
|
|
5307
|
+
const datei = pfad.slice(pfad.lastIndexOf("/") + 1);
|
|
5308
|
+
if (datei.startsWith(".")) return false;
|
|
5309
|
+
return endungVon(datei) in BILD_ENDUNGEN;
|
|
5310
|
+
}
|
|
5311
|
+
function nachPfad(a, b) {
|
|
5312
|
+
return a.localeCompare(b, "en", { numeric: true, sensitivity: "base" }) || (a < b ? -1 : a > b ? 1 : 0);
|
|
5313
|
+
}
|
|
5314
|
+
async function leseBilderAusZip(datei) {
|
|
5315
|
+
const name = datei.name ?? "Archiv";
|
|
5316
|
+
if (datei.size > UPLOAD_MAX_BYTES) {
|
|
5317
|
+
throw new Error(
|
|
5318
|
+
`${name} ist ${mb(datei.size)} MB gro\xDF \u2014 die Grenze liegt bei ${UPLOAD_MAX_BYTES / 1024 / 1024} MB.`
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
const { default: JSZip } = await import("jszip");
|
|
5322
|
+
const archiv = await JSZip.loadAsync(datei).catch((fehler4) => {
|
|
5323
|
+
throw new Error(
|
|
5324
|
+
`${name} konnte nicht als ZIP gelesen werden: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
|
|
5325
|
+
);
|
|
5326
|
+
});
|
|
5327
|
+
const pfade = [];
|
|
5328
|
+
archiv.forEach((pfad, eintrag) => {
|
|
5329
|
+
if (istImportierbar(pfad, eintrag.dir)) pfade.push(pfad);
|
|
5330
|
+
});
|
|
5331
|
+
pfade.sort(nachPfad);
|
|
5332
|
+
if (pfade.length === 0) {
|
|
5333
|
+
throw new Error(
|
|
5334
|
+
`${name} enth\xE4lt kein unterst\xFCtztes Bild (erwartet: ${Object.keys(BILD_ENDUNGEN).map((e) => `.${e}`).join(", ")}).`
|
|
5335
|
+
);
|
|
5336
|
+
}
|
|
5337
|
+
const bilder = [];
|
|
5338
|
+
for (const pfad of pfade) {
|
|
5339
|
+
const eintrag = archiv.file(pfad);
|
|
5340
|
+
if (!eintrag) continue;
|
|
5341
|
+
const angekuendigt = bildGroesseVerdikt(name, pfad, angekuendigteGroesse(eintrag));
|
|
5342
|
+
if (angekuendigt) throw new Error(angekuendigt);
|
|
5343
|
+
const base64 = await eintrag.async("base64");
|
|
5344
|
+
const nachgemessen = bildGroesseVerdikt(name, pfad, byteLaenge(base64));
|
|
5345
|
+
if (nachgemessen) throw new Error(nachgemessen);
|
|
5346
|
+
bilder.push({
|
|
5347
|
+
name: pfad,
|
|
5348
|
+
base64,
|
|
5349
|
+
mimeType: BILD_ENDUNGEN[endungVon(pfad)]
|
|
5350
|
+
});
|
|
5351
|
+
}
|
|
5352
|
+
return bilder;
|
|
5353
|
+
}
|
|
5354
|
+
|
|
5228
5355
|
// src/lib/szenen/bildVorschau.ts
|
|
5229
5356
|
async function ladeVorschauen(port, mediaRefs, fertig, optionen = {}) {
|
|
5230
5357
|
const laden = port.loadPreview;
|
|
@@ -6242,7 +6369,7 @@ function usePortQuery(frage, abhaengigkeiten) {
|
|
|
6242
6369
|
}
|
|
6243
6370
|
|
|
6244
6371
|
// src/features/szenen/areas/ElementDetail.tsx
|
|
6245
|
-
import { useEffect as
|
|
6372
|
+
import { useEffect as useEffect6, useMemo as useMemo2, useState as useState10 } from "react";
|
|
6246
6373
|
|
|
6247
6374
|
// src/features/szenen/elementLabels.ts
|
|
6248
6375
|
var LABELS = {
|
|
@@ -8334,10 +8461,10 @@ var VersionNavigator = ({
|
|
|
8334
8461
|
};
|
|
8335
8462
|
|
|
8336
8463
|
// src/features/szenen/areas/RunsPanel.tsx
|
|
8337
|
-
import { useState as useState9 } from "react";
|
|
8464
|
+
import { useEffect as useEffect5, useRef as useRef3, useState as useState9 } from "react";
|
|
8338
8465
|
|
|
8339
8466
|
// src/features/szenen/areas/RunImagesPanel.tsx
|
|
8340
|
-
import { useEffect as useEffect4, useRef as useRef2, useState as useState8 } from "react";
|
|
8467
|
+
import React7, { useEffect as useEffect4, useRef as useRef2, useState as useState8 } from "react";
|
|
8341
8468
|
|
|
8342
8469
|
// src/features/szenen/areas/Bildbausteine.tsx
|
|
8343
8470
|
import { useCallback, useEffect as useEffect3, useState as useState7 } from "react";
|
|
@@ -8777,6 +8904,7 @@ function useBildQuellen(port, bilder) {
|
|
|
8777
8904
|
const [stand, setStand] = useState8(() => ({ quellen: /* @__PURE__ */ new Map(), fehler: /* @__PURE__ */ new Map() }));
|
|
8778
8905
|
const gehalten = useRef2(/* @__PURE__ */ new Map());
|
|
8779
8906
|
const gescheitert = useRef2(/* @__PURE__ */ new Map());
|
|
8907
|
+
const [versuch, setVersuch] = useState8(0);
|
|
8780
8908
|
const schluessel = bilder.map((b) => `${b.media_ref}|${b.mime_type ?? ""}`).join(" ");
|
|
8781
8909
|
useEffect4(() => {
|
|
8782
8910
|
const bestand = port.imageLibrary;
|
|
@@ -8785,7 +8913,9 @@ function useBildQuellen(port, bilder) {
|
|
|
8785
8913
|
void (async () => {
|
|
8786
8914
|
for (const bild of bilder) {
|
|
8787
8915
|
if (abgebrochen) return;
|
|
8788
|
-
|
|
8916
|
+
const vorher = gescheitert.current.get(bild.media_ref);
|
|
8917
|
+
const endgueltig = vorher !== void 0 && !vorher.retryable;
|
|
8918
|
+
if (gehalten.current.has(bild.media_ref) || endgueltig) continue;
|
|
8789
8919
|
const ergebnis = await bestand.resolveImage(bild.media_ref, bild.mime_type ?? null);
|
|
8790
8920
|
if (abgebrochen) return;
|
|
8791
8921
|
if (ergebnis.kind === "ok" && ergebnis.value) {
|
|
@@ -8793,8 +8923,12 @@ function useBildQuellen(port, bilder) {
|
|
|
8793
8923
|
bild.media_ref,
|
|
8794
8924
|
`data:${ergebnis.value.mime_type};base64,${ergebnis.value.data}`
|
|
8795
8925
|
);
|
|
8926
|
+
gescheitert.current.delete(bild.media_ref);
|
|
8796
8927
|
} else if (ergebnis.kind === "error") {
|
|
8797
|
-
gescheitert.current.set(bild.media_ref,
|
|
8928
|
+
gescheitert.current.set(bild.media_ref, {
|
|
8929
|
+
message: ergebnis.message,
|
|
8930
|
+
retryable: ergebnis.retryable
|
|
8931
|
+
});
|
|
8798
8932
|
}
|
|
8799
8933
|
setStand({
|
|
8800
8934
|
quellen: new Map(gehalten.current),
|
|
@@ -8805,8 +8939,19 @@ function useBildQuellen(port, bilder) {
|
|
|
8805
8939
|
return () => {
|
|
8806
8940
|
abgebrochen = true;
|
|
8807
8941
|
};
|
|
8808
|
-
}, [port, schluessel]);
|
|
8809
|
-
|
|
8942
|
+
}, [port, schluessel, versuch]);
|
|
8943
|
+
const fehlerNachricht = /* @__PURE__ */ new Map();
|
|
8944
|
+
let wiederholbar = false;
|
|
8945
|
+
for (const [ref, f] of stand.fehler) {
|
|
8946
|
+
fehlerNachricht.set(ref, f.message);
|
|
8947
|
+
if (f.retryable) wiederholbar = true;
|
|
8948
|
+
}
|
|
8949
|
+
return {
|
|
8950
|
+
quellen: stand.quellen,
|
|
8951
|
+
fehler: fehlerNachricht,
|
|
8952
|
+
wiederholbar,
|
|
8953
|
+
erneutVersuchen: () => setVersuch((n) => n + 1)
|
|
8954
|
+
};
|
|
8810
8955
|
}
|
|
8811
8956
|
var BildDetails = ({ bild, fehler: fehler4, aufloesbar }) => /* @__PURE__ */ jsxs8("span", { className: "szenen-bilder__meta", "data-testid": `batchbild-${bild.media_ref}`, children: [
|
|
8812
8957
|
/* @__PURE__ */ jsx8("code", { children: bild.media_ref }),
|
|
@@ -8827,8 +8972,17 @@ var BildDetails = ({ bild, fehler: fehler4, aufloesbar }) => /* @__PURE__ */ jsx
|
|
|
8827
8972
|
// Serverroute (A6).
|
|
8828
8973
|
/* @__PURE__ */ jsx8("em", { "data-testid": `batchbild-unsupported-${bild.media_ref}`, children: "Dieser Host l\xF6st keine Bilder auf \u2014 nur die Metadaten sind bekannt." })
|
|
8829
8974
|
] });
|
|
8975
|
+
var HERKUNFT_TEXT = {
|
|
8976
|
+
generated_in_app: "in der App erzeugt",
|
|
8977
|
+
external_import: "extern importiert",
|
|
8978
|
+
mixed: "gemischte Herkunft"
|
|
8979
|
+
};
|
|
8980
|
+
var HERKUNFT_KURZ = {
|
|
8981
|
+
generated_in_app: "in der App erzeugt",
|
|
8982
|
+
external_import: "extern importiert"
|
|
8983
|
+
};
|
|
8830
8984
|
var BatchKachel = ({ port, batch }) => {
|
|
8831
|
-
const { quellen, fehler: fehler4 } = useBildQuellen(port, batch.images);
|
|
8985
|
+
const { quellen, fehler: fehler4, wiederholbar, erneutVersuchen } = useBildQuellen(port, batch.images);
|
|
8832
8986
|
const aufloesbar = Boolean(port.imageLibrary);
|
|
8833
8987
|
const bilder = batch.images.map((bild) => ({
|
|
8834
8988
|
id: bild.media_ref,
|
|
@@ -8854,7 +9008,7 @@ var BatchKachel = ({ port, batch }) => {
|
|
|
8854
9008
|
/* @__PURE__ */ jsxs8("header", { className: "szenen-bilder__batchkopf", children: [
|
|
8855
9009
|
/* @__PURE__ */ jsx8("strong", { children: batch.title }),
|
|
8856
9010
|
/* @__PURE__ */ jsxs8("span", { className: "szenen-bilder__herkunft", children: [
|
|
8857
|
-
batch.source_kind
|
|
9011
|
+
HERKUNFT_TEXT[batch.source_kind],
|
|
8858
9012
|
" \xB7 ",
|
|
8859
9013
|
batch.images.length,
|
|
8860
9014
|
" Bild(er)"
|
|
@@ -8868,6 +9022,16 @@ var BatchKachel = ({ port, batch }) => {
|
|
|
8868
9022
|
satzTitel: batch.title
|
|
8869
9023
|
}
|
|
8870
9024
|
),
|
|
9025
|
+
wiederholbar && /* @__PURE__ */ jsx8(
|
|
9026
|
+
"button",
|
|
9027
|
+
{
|
|
9028
|
+
type: "button",
|
|
9029
|
+
className: "szenen-bilder__retry",
|
|
9030
|
+
onClick: erneutVersuchen,
|
|
9031
|
+
"data-testid": `batch-retry-${batch.item_id}`,
|
|
9032
|
+
children: "Bilder erneut laden"
|
|
9033
|
+
}
|
|
9034
|
+
),
|
|
8871
9035
|
/* @__PURE__ */ jsxs8("details", { className: "szenen-bilder__technik", "data-testid": `batch-technik-${batch.item_id}`, children: [
|
|
8872
9036
|
/* @__PURE__ */ jsx8("summary", { children: "Technische Details" }),
|
|
8873
9037
|
/* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__ids", children: [
|
|
@@ -8876,8 +9040,13 @@ var BatchKachel = ({ port, batch }) => {
|
|
|
8876
9040
|
/* @__PURE__ */ jsx8("code", { "data-testid": `batch-item-${batch.item_id}`, children: batch.item_id })
|
|
8877
9041
|
] }),
|
|
8878
9042
|
/* @__PURE__ */ jsxs8("span", { children: [
|
|
8879
|
-
"Batches
|
|
8880
|
-
|
|
9043
|
+
"Batches",
|
|
9044
|
+
" ",
|
|
9045
|
+
batch.origins.length > 0 ? batch.origins.map((h, i) => /* @__PURE__ */ jsxs8(React7.Fragment, { children: [
|
|
9046
|
+
i > 0 ? ", " : "",
|
|
9047
|
+
/* @__PURE__ */ jsx8("code", { children: h.generation_batch_id }),
|
|
9048
|
+
` (${HERKUNFT_KURZ[h.source_kind]})`
|
|
9049
|
+
] }, h.generation_batch_id)) : /* @__PURE__ */ jsx8("code", { children: batch.generation_batch_ids.join(", ") })
|
|
8881
9050
|
] })
|
|
8882
9051
|
] }),
|
|
8883
9052
|
/* @__PURE__ */ jsx8("ul", { className: "szenen-bilder__batchliste", children: batch.images.map((bild) => /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsx8(
|
|
@@ -9081,21 +9250,114 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
|
|
|
9081
9250
|
)
|
|
9082
9251
|
] });
|
|
9083
9252
|
};
|
|
9253
|
+
var DEFAULT_VORLAGE_KEY = "__default__";
|
|
9084
9254
|
var ZuordnenAktion = ({ port, lauf, onFertig }) => {
|
|
9085
9255
|
const [dateien, setDateien] = useState8([]);
|
|
9086
9256
|
const [seeds, setSeeds] = useState8({});
|
|
9257
|
+
const [zip, setZip] = useState8(null);
|
|
9258
|
+
const [zipLaedt, setZipLaedt] = useState8(false);
|
|
9259
|
+
const [seedListe, setSeedListe] = useState8("");
|
|
9260
|
+
const [vorlagen, setVorlagen] = useState8([DEFAULT_SEED_VORLAGE]);
|
|
9261
|
+
const [vorlageKey, setVorlageKey] = useState8(DEFAULT_VORLAGE_KEY);
|
|
9262
|
+
const [vorlagenStand, setVorlagenStand] = useState8(0);
|
|
9263
|
+
const [vorlageBenennen, setVorlageBenennen] = useState8(false);
|
|
9264
|
+
const [vorlageName, setVorlageName] = useState8("");
|
|
9087
9265
|
const [modell, setModell] = useState8("");
|
|
9088
9266
|
const [itemId, setItemId] = useState8("");
|
|
9089
9267
|
const [laeuft, setLaeuft] = useState8(false);
|
|
9090
9268
|
const [notiz, setNotiz] = useState8(null);
|
|
9269
|
+
const auswahlMarke = useRef2(0);
|
|
9270
|
+
const zipAktiv = zip !== null;
|
|
9271
|
+
useEffect4(() => {
|
|
9272
|
+
if (!zipAktiv) return;
|
|
9273
|
+
let abgebrochen = false;
|
|
9274
|
+
void (async () => {
|
|
9275
|
+
const gelesen = port.seedTemplates ? await port.seedTemplates.listSeedTemplates() : null;
|
|
9276
|
+
if (abgebrochen) return;
|
|
9277
|
+
setVorlagen(mitDefaultVorlage(
|
|
9278
|
+
gelesen && gelesen.kind === "ok" ? gelesen.value : []
|
|
9279
|
+
));
|
|
9280
|
+
})();
|
|
9281
|
+
return () => {
|
|
9282
|
+
abgebrochen = true;
|
|
9283
|
+
};
|
|
9284
|
+
}, [zipAktiv, port, vorlagenStand]);
|
|
9091
9285
|
if (!port.imageBatchWrite) {
|
|
9092
9286
|
return /* @__PURE__ */ jsx8("p", { "data-testid": `zuordnen-unsupported-${lauf.run_id}`, children: "Dieser Host ordnet keine externen Bilder zu \u2014 er hat keinen gesicherten Batch-Schreibweg. Die Historie oben bleibt trotzdem sichtbar." });
|
|
9093
9287
|
}
|
|
9094
|
-
const
|
|
9288
|
+
const zuordnung = zip ? ordneSeedsZu(seedListe, zip.bilder.length) : null;
|
|
9289
|
+
const dateiWahl = async (liste) => {
|
|
9290
|
+
const gewaehlt = [...liste ?? []];
|
|
9291
|
+
const warZip = zip !== null;
|
|
9292
|
+
const meine = auswahlMarke.current += 1;
|
|
9293
|
+
const veraltet = () => auswahlMarke.current !== meine;
|
|
9294
|
+
const zips = gewaehlt.filter(istZipDatei);
|
|
9295
|
+
const nurEinZip = zips.length === 1 && gewaehlt.length === 1;
|
|
9296
|
+
setNotiz(null);
|
|
9297
|
+
setSeeds({});
|
|
9298
|
+
setZip(null);
|
|
9299
|
+
setDateien(zips.length === 0 ? gewaehlt : []);
|
|
9300
|
+
setZipLaedt(nurEinZip);
|
|
9301
|
+
if (zips.length > 0 && zips.length !== gewaehlt.length) {
|
|
9302
|
+
setNotiz({
|
|
9303
|
+
tone: "error",
|
|
9304
|
+
text: `Die Auswahl enth\xE4lt ${zips.length} ZIP-Datei(en) und ${gewaehlt.length - zips.length} Bilddatei(en). Bitte entweder ein ZIP oder einzelne Bilder w\xE4hlen \u2014 nicht beides in einem Import.`
|
|
9305
|
+
});
|
|
9306
|
+
return;
|
|
9307
|
+
}
|
|
9308
|
+
if (zips.length > 1) {
|
|
9309
|
+
setNotiz({
|
|
9310
|
+
tone: "error",
|
|
9311
|
+
text: `${zips.length} ZIP-Dateien gew\xE4hlt (${zips.map((z) => z.name).join(", ")}). Ein Import nimmt genau ein ZIP.`
|
|
9312
|
+
});
|
|
9313
|
+
return;
|
|
9314
|
+
}
|
|
9315
|
+
if (!nurEinZip) return;
|
|
9316
|
+
const datei = zips[0];
|
|
9317
|
+
try {
|
|
9318
|
+
const bilder = await leseBilderAusZip(datei);
|
|
9319
|
+
if (veraltet()) return;
|
|
9320
|
+
setZip({ datei, bilder });
|
|
9321
|
+
if (!warZip) {
|
|
9322
|
+
setSeedListe(DEFAULT_SEED_VORLAGE.seeds);
|
|
9323
|
+
setVorlageKey(DEFAULT_VORLAGE_KEY);
|
|
9324
|
+
}
|
|
9325
|
+
} catch (fehler4) {
|
|
9326
|
+
if (veraltet()) return;
|
|
9327
|
+
setNotiz({
|
|
9328
|
+
tone: "error",
|
|
9329
|
+
text: fehler4 instanceof Error ? fehler4.message : String(fehler4)
|
|
9330
|
+
});
|
|
9331
|
+
}
|
|
9332
|
+
if (veraltet()) return;
|
|
9333
|
+
setZipLaedt(false);
|
|
9334
|
+
};
|
|
9335
|
+
const schreiben = async (bilder, generationBatchId, titel) => {
|
|
9095
9336
|
setLaeuft(true);
|
|
9096
9337
|
setNotiz(null);
|
|
9097
9338
|
try {
|
|
9098
|
-
const
|
|
9339
|
+
const ergebnis = await port.imageBatchWrite.importBatch({
|
|
9340
|
+
runId: lauf.run_id,
|
|
9341
|
+
generationBatchId,
|
|
9342
|
+
images: bilder,
|
|
9343
|
+
title: titel
|
|
9344
|
+
});
|
|
9345
|
+
setNotiz(
|
|
9346
|
+
ergebnis.kind === "ok" ? { tone: "ok", text: `Importiert als Item ${ergebnis.value.item_id} mit ${bilder.length} Bild(ern).` } : noticeFor(ergebnis, "Externe Bilder importieren")
|
|
9347
|
+
);
|
|
9348
|
+
} catch (fehler4) {
|
|
9349
|
+
setNotiz({
|
|
9350
|
+
tone: "error",
|
|
9351
|
+
text: `Externe Bilder importieren: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
|
|
9352
|
+
});
|
|
9353
|
+
}
|
|
9354
|
+
setLaeuft(false);
|
|
9355
|
+
onFertig();
|
|
9356
|
+
};
|
|
9357
|
+
const importieren = async () => {
|
|
9358
|
+
let bilder;
|
|
9359
|
+
try {
|
|
9360
|
+
bilder = [];
|
|
9099
9361
|
for (let index = 0; index < dateien.length; index++) {
|
|
9100
9362
|
const roh = (seeds[index] ?? "").trim();
|
|
9101
9363
|
const seed = roh === "" ? void 0 : Number.parseInt(roh, 10);
|
|
@@ -9108,25 +9370,42 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
|
|
|
9108
9370
|
...seed !== void 0 ? { seed } : {}
|
|
9109
9371
|
});
|
|
9110
9372
|
}
|
|
9111
|
-
const ergebnis = await port.imageBatchWrite.importBatch({
|
|
9112
|
-
runId: lauf.run_id,
|
|
9113
|
-
// Vor dem Aufruf gebildet und stabil (D-113): eine Wiederholung
|
|
9114
|
-
// derselben Einreichung erzeugt kein zweites Item.
|
|
9115
|
-
generationBatchId: `imp-${lauf.run_id}-${dateien.length}-${dateien.map((d) => d.size).join("_")}`,
|
|
9116
|
-
images: bilder,
|
|
9117
|
-
title: `Externer Import zu Lauf ${lauf.run_id}`
|
|
9118
|
-
});
|
|
9119
|
-
setNotiz(
|
|
9120
|
-
ergebnis.kind === "ok" ? { tone: "ok", text: `Importiert als Item ${ergebnis.value.item_id} mit ${bilder.length} Bild(ern).` } : noticeFor(ergebnis, "Externe Bilder importieren")
|
|
9121
|
-
);
|
|
9122
9373
|
} catch (fehler4) {
|
|
9123
9374
|
setNotiz({
|
|
9124
9375
|
tone: "error",
|
|
9125
9376
|
text: `Externe Bilder importieren: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
|
|
9126
9377
|
});
|
|
9378
|
+
return;
|
|
9127
9379
|
}
|
|
9128
|
-
|
|
9129
|
-
|
|
9380
|
+
await schreiben(
|
|
9381
|
+
bilder,
|
|
9382
|
+
// Vor dem Aufruf gebildet und stabil (D-113): eine Wiederholung
|
|
9383
|
+
// derselben Einreichung erzeugt kein zweites Item.
|
|
9384
|
+
`imp-${lauf.run_id}-${dateien.length}-${dateien.map((d) => d.size).join("_")}`,
|
|
9385
|
+
`Externer Import zu Lauf ${lauf.run_id}`
|
|
9386
|
+
);
|
|
9387
|
+
};
|
|
9388
|
+
const zipImportieren = async () => {
|
|
9389
|
+
if (!zip || !zuordnung) return;
|
|
9390
|
+
if (zuordnung.ungueltige.length > 0) {
|
|
9391
|
+
setNotiz({ tone: "error", text: seedFehlerText(zuordnung.ungueltige) });
|
|
9392
|
+
return;
|
|
9393
|
+
}
|
|
9394
|
+
const bilder = zip.bilder.map((bild, index) => {
|
|
9395
|
+
const seed = zuordnung.eintraege[index]?.seed ?? null;
|
|
9396
|
+
return {
|
|
9397
|
+
imageBase64: bild.base64,
|
|
9398
|
+
...modell.trim() ? { model: modell.trim() } : {},
|
|
9399
|
+
// Unbekannt bleibt unbekannt: kein Feld statt eines erfundenen
|
|
9400
|
+
// Werts (§6.1).
|
|
9401
|
+
...seed !== null ? { seed } : {}
|
|
9402
|
+
};
|
|
9403
|
+
});
|
|
9404
|
+
await schreiben(
|
|
9405
|
+
bilder,
|
|
9406
|
+
`imp-${lauf.run_id}-zip-${zip.datei.size}-${bilder.length}`,
|
|
9407
|
+
`Externer Import zu Lauf ${lauf.run_id} (${zip.datei.name})`
|
|
9408
|
+
);
|
|
9130
9409
|
};
|
|
9131
9410
|
const zuordnen = async () => {
|
|
9132
9411
|
setLaeuft(true);
|
|
@@ -9144,35 +9423,63 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
|
|
|
9144
9423
|
setLaeuft(false);
|
|
9145
9424
|
onFertig();
|
|
9146
9425
|
};
|
|
9426
|
+
const vorlageWaehlen = (key) => {
|
|
9427
|
+
setVorlageKey(key);
|
|
9428
|
+
const vorlage = key === DEFAULT_VORLAGE_KEY ? DEFAULT_SEED_VORLAGE : vorlagen.find((v) => String(v.id) === key);
|
|
9429
|
+
if (vorlage) setSeedListe(vorlage.seeds);
|
|
9430
|
+
};
|
|
9431
|
+
const vorlageSpeichern = async () => {
|
|
9432
|
+
const name = vorlageName.trim();
|
|
9433
|
+
if (!name || !seedListe.trim() || !port.seedTemplates?.saveSeedTemplate) return;
|
|
9434
|
+
const ergebnis = await port.seedTemplates.saveSeedTemplate({ name, seeds: seedListe.trim() });
|
|
9435
|
+
if (ergebnis.kind !== "ok") {
|
|
9436
|
+
setNotiz(noticeFor(ergebnis, "Seed-Vorlage speichern"));
|
|
9437
|
+
return;
|
|
9438
|
+
}
|
|
9439
|
+
setVorlageBenennen(false);
|
|
9440
|
+
setVorlageName("");
|
|
9441
|
+
if (ergebnis.value.id !== void 0) setVorlageKey(String(ergebnis.value.id));
|
|
9442
|
+
setVorlagenStand((n) => n + 1);
|
|
9443
|
+
};
|
|
9444
|
+
const vorlageLoeschen = async () => {
|
|
9445
|
+
if (vorlageKey === DEFAULT_VORLAGE_KEY || !port.seedTemplates?.deleteSeedTemplate) return;
|
|
9446
|
+
const ergebnis = await port.seedTemplates.deleteSeedTemplate(vorlageKey);
|
|
9447
|
+
if (ergebnis.kind !== "ok") {
|
|
9448
|
+
setNotiz(noticeFor(ergebnis, "Seed-Vorlage l\xF6schen"));
|
|
9449
|
+
return;
|
|
9450
|
+
}
|
|
9451
|
+
setVorlageKey(DEFAULT_VORLAGE_KEY);
|
|
9452
|
+
setVorlagenStand((n) => n + 1);
|
|
9453
|
+
};
|
|
9147
9454
|
return /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder__aktion-inhalt", "data-testid": `zuordnen-${lauf.run_id}`, children: [
|
|
9148
9455
|
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9149
|
-
"Bilddateien",
|
|
9456
|
+
"Bilddateien oder ein ZIP",
|
|
9150
9457
|
/* @__PURE__ */ jsx8(
|
|
9151
9458
|
"input",
|
|
9152
9459
|
{
|
|
9153
9460
|
type: "file",
|
|
9154
|
-
accept: "image
|
|
9461
|
+
accept: "image/*,.zip",
|
|
9155
9462
|
multiple: true,
|
|
9156
9463
|
"data-testid": `zuordnen-dateien-${lauf.run_id}`,
|
|
9157
9464
|
onChange: (e) => {
|
|
9158
|
-
|
|
9159
|
-
setSeeds({});
|
|
9465
|
+
void dateiWahl(e.target.files);
|
|
9160
9466
|
}
|
|
9161
9467
|
}
|
|
9162
9468
|
)
|
|
9163
9469
|
] }),
|
|
9470
|
+
zipLaedt && /* @__PURE__ */ jsx8("p", { "data-testid": `zuordnen-zip-laedt-${lauf.run_id}`, children: "ZIP wird gelesen \u2026" }),
|
|
9471
|
+
(dateien.length > 0 || zip) && /* @__PURE__ */ jsxs8("label", { children: [
|
|
9472
|
+
"Modell (f\xFCr alle Bilder, leer = unbekannt)",
|
|
9473
|
+
/* @__PURE__ */ jsx8(
|
|
9474
|
+
"input",
|
|
9475
|
+
{
|
|
9476
|
+
value: modell,
|
|
9477
|
+
"data-testid": `zuordnen-modell-${lauf.run_id}`,
|
|
9478
|
+
onChange: (e) => setModell(e.target.value)
|
|
9479
|
+
}
|
|
9480
|
+
)
|
|
9481
|
+
] }),
|
|
9164
9482
|
dateien.length > 0 && /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
9165
|
-
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9166
|
-
"Modell (f\xFCr alle Bilder, leer = unbekannt)",
|
|
9167
|
-
/* @__PURE__ */ jsx8(
|
|
9168
|
-
"input",
|
|
9169
|
-
{
|
|
9170
|
-
value: modell,
|
|
9171
|
-
"data-testid": `zuordnen-modell-${lauf.run_id}`,
|
|
9172
|
-
onChange: (e) => setModell(e.target.value)
|
|
9173
|
-
}
|
|
9174
|
-
)
|
|
9175
|
-
] }),
|
|
9176
9483
|
/* @__PURE__ */ jsx8("ol", { "data-testid": `zuordnen-vorschau-${lauf.run_id}`, children: dateien.map((datei, index) => /* @__PURE__ */ jsxs8("li", { children: [
|
|
9177
9484
|
/* @__PURE__ */ jsxs8("span", { children: [
|
|
9178
9485
|
"Position ",
|
|
@@ -9206,6 +9513,157 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
|
|
|
9206
9513
|
}
|
|
9207
9514
|
)
|
|
9208
9515
|
] }),
|
|
9516
|
+
zip && zuordnung && /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder__zip", "data-testid": `zuordnen-zip-${lauf.run_id}`, children: [
|
|
9517
|
+
/* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipkopf", children: [
|
|
9518
|
+
"ZIP ",
|
|
9519
|
+
/* @__PURE__ */ jsx8("code", { children: zip.datei.name }),
|
|
9520
|
+
" \u2014 ",
|
|
9521
|
+
zip.bilder.length,
|
|
9522
|
+
" Bild(er) erkannt"
|
|
9523
|
+
] }),
|
|
9524
|
+
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9525
|
+
"Seeds (pro Bild ein Seed, Trenner , oder ;)",
|
|
9526
|
+
/* @__PURE__ */ jsx8(
|
|
9527
|
+
"input",
|
|
9528
|
+
{
|
|
9529
|
+
"data-testid": `zuordnen-seedliste-${lauf.run_id}`,
|
|
9530
|
+
value: seedListe,
|
|
9531
|
+
placeholder: "z. B. 1; 10; 100; 1000",
|
|
9532
|
+
onChange: (e) => setSeedListe(e.target.value)
|
|
9533
|
+
}
|
|
9534
|
+
)
|
|
9535
|
+
] }),
|
|
9536
|
+
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9537
|
+
"Seed-Vorlage",
|
|
9538
|
+
/* @__PURE__ */ jsxs8(
|
|
9539
|
+
"select",
|
|
9540
|
+
{
|
|
9541
|
+
"data-testid": `zuordnen-seedvorlage-${lauf.run_id}`,
|
|
9542
|
+
value: vorlageKey,
|
|
9543
|
+
onChange: (e) => vorlageWaehlen(e.target.value),
|
|
9544
|
+
children: [
|
|
9545
|
+
/* @__PURE__ */ jsxs8("option", { value: DEFAULT_VORLAGE_KEY, children: [
|
|
9546
|
+
"Default (",
|
|
9547
|
+
DEFAULT_SEED_VORLAGE.seeds,
|
|
9548
|
+
")"
|
|
9549
|
+
] }),
|
|
9550
|
+
vorlagen.filter((v) => !v.builtin).map((v) => /* @__PURE__ */ jsxs8("option", { value: String(v.id), children: [
|
|
9551
|
+
v.name,
|
|
9552
|
+
" (",
|
|
9553
|
+
v.seeds,
|
|
9554
|
+
")"
|
|
9555
|
+
] }, String(v.id)))
|
|
9556
|
+
]
|
|
9557
|
+
}
|
|
9558
|
+
)
|
|
9559
|
+
] }),
|
|
9560
|
+
(port.seedTemplates?.saveSeedTemplate || port.seedTemplates?.deleteSeedTemplate) && /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipvorlagen", children: [
|
|
9561
|
+
port.seedTemplates?.saveSeedTemplate && !vorlageBenennen && /* @__PURE__ */ jsx8(
|
|
9562
|
+
"button",
|
|
9563
|
+
{
|
|
9564
|
+
type: "button",
|
|
9565
|
+
"data-testid": `zuordnen-vorlage-neu-${lauf.run_id}`,
|
|
9566
|
+
disabled: !seedListe.trim(),
|
|
9567
|
+
onClick: () => {
|
|
9568
|
+
setVorlageName("");
|
|
9569
|
+
setVorlageBenennen(true);
|
|
9570
|
+
},
|
|
9571
|
+
children: "Als Vorlage speichern"
|
|
9572
|
+
}
|
|
9573
|
+
),
|
|
9574
|
+
port.seedTemplates?.deleteSeedTemplate && /* @__PURE__ */ jsx8(
|
|
9575
|
+
"button",
|
|
9576
|
+
{
|
|
9577
|
+
type: "button",
|
|
9578
|
+
"data-testid": `zuordnen-vorlage-loeschen-${lauf.run_id}`,
|
|
9579
|
+
disabled: vorlageKey === DEFAULT_VORLAGE_KEY,
|
|
9580
|
+
onClick: () => {
|
|
9581
|
+
void vorlageLoeschen();
|
|
9582
|
+
},
|
|
9583
|
+
children: "Vorlage l\xF6schen"
|
|
9584
|
+
}
|
|
9585
|
+
)
|
|
9586
|
+
] }),
|
|
9587
|
+
vorlageBenennen && /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
9588
|
+
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9589
|
+
"Name der Vorlage",
|
|
9590
|
+
/* @__PURE__ */ jsx8(
|
|
9591
|
+
"input",
|
|
9592
|
+
{
|
|
9593
|
+
"data-testid": `zuordnen-vorlage-name-${lauf.run_id}`,
|
|
9594
|
+
value: vorlageName,
|
|
9595
|
+
onChange: (e) => setVorlageName(e.target.value)
|
|
9596
|
+
}
|
|
9597
|
+
)
|
|
9598
|
+
] }),
|
|
9599
|
+
/* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipvorlagen", children: [
|
|
9600
|
+
/* @__PURE__ */ jsx8(
|
|
9601
|
+
"button",
|
|
9602
|
+
{
|
|
9603
|
+
type: "button",
|
|
9604
|
+
"data-testid": `zuordnen-vorlage-sichern-${lauf.run_id}`,
|
|
9605
|
+
disabled: !vorlageName.trim(),
|
|
9606
|
+
onClick: () => {
|
|
9607
|
+
void vorlageSpeichern();
|
|
9608
|
+
},
|
|
9609
|
+
children: "Speichern"
|
|
9610
|
+
}
|
|
9611
|
+
),
|
|
9612
|
+
/* @__PURE__ */ jsx8(
|
|
9613
|
+
"button",
|
|
9614
|
+
{
|
|
9615
|
+
type: "button",
|
|
9616
|
+
"data-testid": `zuordnen-vorlage-abbrechen-${lauf.run_id}`,
|
|
9617
|
+
onClick: () => setVorlageBenennen(false),
|
|
9618
|
+
children: "Abbrechen"
|
|
9619
|
+
}
|
|
9620
|
+
)
|
|
9621
|
+
] })
|
|
9622
|
+
] }),
|
|
9623
|
+
zuordnung.ueberzaehlig > 0 && /* @__PURE__ */ jsxs8("p", { "data-testid": `zuordnen-ueberzaehlig-${lauf.run_id}`, children: [
|
|
9624
|
+
zuordnung.ueberzaehlig,
|
|
9625
|
+
" Seed(s) mehr als Bilder \u2014 die \xFCberz\xE4hligen werden nicht geschrieben."
|
|
9626
|
+
] }),
|
|
9627
|
+
/* @__PURE__ */ jsx8(
|
|
9628
|
+
"ol",
|
|
9629
|
+
{
|
|
9630
|
+
className: "szenen-bilder__zipliste",
|
|
9631
|
+
"data-testid": `zuordnen-zip-vorschau-${lauf.run_id}`,
|
|
9632
|
+
children: zip.bilder.map((bild, index) => {
|
|
9633
|
+
const eintrag = zuordnung.eintraege[index];
|
|
9634
|
+
return /* @__PURE__ */ jsxs8("li", { children: [
|
|
9635
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
9636
|
+
"Position ",
|
|
9637
|
+
index,
|
|
9638
|
+
": ",
|
|
9639
|
+
bild.name
|
|
9640
|
+
] }),
|
|
9641
|
+
/* @__PURE__ */ jsx8(
|
|
9642
|
+
"span",
|
|
9643
|
+
{
|
|
9644
|
+
"data-testid": `zuordnen-zip-seed-${lauf.run_id}-${index}`,
|
|
9645
|
+
"data-seed": eintrag.seed === null ? "" : String(eintrag.seed),
|
|
9646
|
+
children: eintrag.ungueltig ? `Seed ung\xFCltig: "${eintrag.roh}"` : eintrag.seed === null ? "Seed unbekannt" : `Seed ${eintrag.seed}`
|
|
9647
|
+
}
|
|
9648
|
+
)
|
|
9649
|
+
] }, `${bild.name}-${index}`);
|
|
9650
|
+
})
|
|
9651
|
+
}
|
|
9652
|
+
),
|
|
9653
|
+
/* @__PURE__ */ jsxs8(
|
|
9654
|
+
"button",
|
|
9655
|
+
{
|
|
9656
|
+
type: "button",
|
|
9657
|
+
"data-testid": `zuordnen-zip-import-${lauf.run_id}`,
|
|
9658
|
+
disabled: laeuft || zipLaedt,
|
|
9659
|
+
onClick: zipImportieren,
|
|
9660
|
+
children: [
|
|
9661
|
+
zip.bilder.length,
|
|
9662
|
+
" Bild(er) aus ZIP importieren"
|
|
9663
|
+
]
|
|
9664
|
+
}
|
|
9665
|
+
)
|
|
9666
|
+
] }),
|
|
9209
9667
|
/* @__PURE__ */ jsxs8("label", { children: [
|
|
9210
9668
|
"Oder ein bestehendes Library-Item",
|
|
9211
9669
|
/* @__PURE__ */ jsx8(
|
|
@@ -9261,6 +9719,8 @@ var RunsPanel = ({ port, source, contextId }) => {
|
|
|
9261
9719
|
const [nachladen, setNachladen] = useState9(0);
|
|
9262
9720
|
const faehig = capabilitiesOf(port);
|
|
9263
9721
|
const quellSchluessel = source.kind === "published" ? source.shotVersionId : source.kind === "draft_chain" ? source.chainId : source.sceneElementId;
|
|
9722
|
+
const aktuelleQuelle = useRef3({ kind: source.kind, id: quellSchluessel });
|
|
9723
|
+
aktuelleQuelle.current = { kind: source.kind, id: quellSchluessel };
|
|
9264
9724
|
const [phase, neuLaden] = usePortQuery(
|
|
9265
9725
|
() => {
|
|
9266
9726
|
if (source.kind === "published") return port.runs.listRunsForShot(source.shotVersionId);
|
|
@@ -9271,12 +9731,16 @@ var RunsPanel = ({ port, source, contextId }) => {
|
|
|
9271
9731
|
);
|
|
9272
9732
|
const starten = async () => {
|
|
9273
9733
|
if (source.kind !== "published") return;
|
|
9734
|
+
const gestartetFuer = { kind: source.kind, id: source.shotVersionId };
|
|
9274
9735
|
setLaeuft(true);
|
|
9275
9736
|
const ergebnis = await port.runs.startRun({
|
|
9276
9737
|
shotVersionId: source.shotVersionId,
|
|
9277
9738
|
...anweisung.trim() ? { userInstruction: anweisung.trim() } : {},
|
|
9278
9739
|
contextId
|
|
9279
9740
|
});
|
|
9741
|
+
if (aktuelleQuelle.current.kind !== gestartetFuer.kind || aktuelleQuelle.current.id !== gestartetFuer.id) {
|
|
9742
|
+
return;
|
|
9743
|
+
}
|
|
9280
9744
|
setNotiz(noticeFor(ergebnis, "Prompt-Lauf starten"));
|
|
9281
9745
|
setLaeuft(false);
|
|
9282
9746
|
setNachladen((n) => n + 1);
|
|
@@ -9286,6 +9750,12 @@ var RunsPanel = ({ port, source, contextId }) => {
|
|
|
9286
9750
|
const [gewaehlteRunde, setGewaehlteRunde] = useState9(void 0);
|
|
9287
9751
|
const neueste = laeufe.length > 0 ? laeufe[laeufe.length - 1].run_id : null;
|
|
9288
9752
|
const offeneRunde = gewaehlteRunde === void 0 ? neueste : gewaehlteRunde;
|
|
9753
|
+
useEffect5(() => {
|
|
9754
|
+
setGewaehlteRunde(void 0);
|
|
9755
|
+
setAnweisung("");
|
|
9756
|
+
setNotiz(null);
|
|
9757
|
+
setLaeuft(false);
|
|
9758
|
+
}, [source.kind, quellSchluessel]);
|
|
9289
9759
|
return /* @__PURE__ */ jsxs9("div", { className: "szenen-runs", "data-testid": "laeufe-bereich", "data-shot-version": quellSchluessel, children: [
|
|
9290
9760
|
/* @__PURE__ */ jsx9("h4", { children: "Prompt-L\xE4ufe" }),
|
|
9291
9761
|
source.kind === "published" && /* @__PURE__ */ jsxs9("div", { className: "szenen-runs__start", children: [
|
|
@@ -9356,6 +9826,26 @@ var Sekundaertext = ({ titel, text, testId }) => {
|
|
|
9356
9826
|
)
|
|
9357
9827
|
] });
|
|
9358
9828
|
};
|
|
9829
|
+
var LISTE_ANFANG = 3;
|
|
9830
|
+
var SekundaerListe = ({ titel, eintraege, testId, className }) => {
|
|
9831
|
+
const [alle, setAlle] = useState9(false);
|
|
9832
|
+
const lang = eintraege.length > LISTE_ANFANG;
|
|
9833
|
+
const gezeigt = lang && !alle ? eintraege.slice(0, LISTE_ANFANG) : eintraege;
|
|
9834
|
+
return /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__sekundaer", children: [
|
|
9835
|
+
/* @__PURE__ */ jsx9("h5", { children: titel }),
|
|
9836
|
+
/* @__PURE__ */ jsx9("ul", { className, "data-testid": testId, children: gezeigt.map((eintrag, i) => /* @__PURE__ */ jsx9("li", { children: eintrag }, i)) }),
|
|
9837
|
+
lang && /* @__PURE__ */ jsx9(
|
|
9838
|
+
"button",
|
|
9839
|
+
{
|
|
9840
|
+
type: "button",
|
|
9841
|
+
className: "szenen-runs__mehr",
|
|
9842
|
+
onClick: () => setAlle(!alle),
|
|
9843
|
+
"data-testid": `${testId}-mehr`,
|
|
9844
|
+
children: alle ? "weniger anzeigen" : `${eintraege.length - LISTE_ANFANG} weitere anzeigen`
|
|
9845
|
+
}
|
|
9846
|
+
)
|
|
9847
|
+
] });
|
|
9848
|
+
};
|
|
9359
9849
|
var RundenEintrag = ({ port, lauf, runde, offen, onUmschalten, itemMoeglich, onItemGespeichert }) => {
|
|
9360
9850
|
const [notiz, setNotiz] = useState9(null);
|
|
9361
9851
|
const [laeuft, setLaeuft] = useState9(false);
|
|
@@ -9441,11 +9931,23 @@ var RundenEintrag = ({ port, lauf, runde, offen, onUmschalten, itemMoeglich, onI
|
|
|
9441
9931
|
testId: `feedback-${lauf.run_id}`
|
|
9442
9932
|
}
|
|
9443
9933
|
),
|
|
9444
|
-
lauf.output.visibility.assumptions.length > 0 && /* @__PURE__ */
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9934
|
+
lauf.output.visibility.assumptions.length > 0 && /* @__PURE__ */ jsx9(
|
|
9935
|
+
SekundaerListe,
|
|
9936
|
+
{
|
|
9937
|
+
titel: "Annahmen",
|
|
9938
|
+
eintraege: lauf.output.visibility.assumptions,
|
|
9939
|
+
testId: `annahmen-${lauf.run_id}`
|
|
9940
|
+
}
|
|
9941
|
+
),
|
|
9942
|
+
lauf.output.notes.length > 0 && /* @__PURE__ */ jsx9(
|
|
9943
|
+
SekundaerListe,
|
|
9944
|
+
{
|
|
9945
|
+
titel: "Notizen",
|
|
9946
|
+
eintraege: lauf.output.notes,
|
|
9947
|
+
testId: `notizen-${lauf.run_id}`,
|
|
9948
|
+
className: "szenen-runs__notizen"
|
|
9949
|
+
}
|
|
9950
|
+
)
|
|
9449
9951
|
] }),
|
|
9450
9952
|
lauf.raw_output && /* @__PURE__ */ jsxs9("details", { "data-testid": `diagnose-${lauf.run_id}`, children: [
|
|
9451
9953
|
/* @__PURE__ */ jsx9("summary", { children: "Rohantwort (Diagnose)" }),
|
|
@@ -9533,7 +10035,7 @@ var ElementDetail = ({
|
|
|
9533
10035
|
() => schnappschuss ? fieldsForType(schnappschuss.element.type) : [],
|
|
9534
10036
|
[schnappschuss?.element.type]
|
|
9535
10037
|
);
|
|
9536
|
-
|
|
10038
|
+
useEffect6(() => {
|
|
9537
10039
|
setWahl(null);
|
|
9538
10040
|
setBasiswechsel(null);
|
|
9539
10041
|
setNotiz(null);
|
|
@@ -9564,7 +10066,7 @@ var ElementDetail = ({
|
|
|
9564
10066
|
return {};
|
|
9565
10067
|
}, [schnappschuss, angezeigt]);
|
|
9566
10068
|
const anzeigeSchluessel = angezeigt.kind === "version" ? `v:${angezeigt.versionId}` : angezeigt.kind;
|
|
9567
|
-
|
|
10069
|
+
useEffect6(() => {
|
|
9568
10070
|
if (!schnappschuss) return;
|
|
9569
10071
|
setEntwurf(formFromPayload(felder, angezeigtePayload));
|
|
9570
10072
|
}, [
|
|
@@ -9996,7 +10498,7 @@ var ElementDetail = ({
|
|
|
9996
10498
|
};
|
|
9997
10499
|
|
|
9998
10500
|
// src/features/szenen/areas/useSchmalesDisplay.ts
|
|
9999
|
-
import { useEffect as
|
|
10501
|
+
import { useEffect as useEffect7, useState as useState11 } from "react";
|
|
10000
10502
|
var SCHMALE_ANSICHT = "(max-width: 760px)";
|
|
10001
10503
|
function messen(abfrage) {
|
|
10002
10504
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
@@ -10004,7 +10506,7 @@ function messen(abfrage) {
|
|
|
10004
10506
|
}
|
|
10005
10507
|
function useSchmalesDisplay(abfrage = SCHMALE_ANSICHT) {
|
|
10006
10508
|
const [schmal, setSchmal] = useState11(() => messen(abfrage));
|
|
10007
|
-
|
|
10509
|
+
useEffect7(() => {
|
|
10008
10510
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
10009
10511
|
const liste = window.matchMedia(abfrage);
|
|
10010
10512
|
const aktualisieren = () => setSchmal(liste.matches);
|
|
@@ -10431,7 +10933,7 @@ var MediaArea = ({ port }) => {
|
|
|
10431
10933
|
};
|
|
10432
10934
|
|
|
10433
10935
|
// src/features/szenen/areas/DeriveArea.tsx
|
|
10434
|
-
import { useEffect as
|
|
10936
|
+
import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef4, useState as useState16 } from "react";
|
|
10435
10937
|
|
|
10436
10938
|
// src/features/szenen/areas/RecoveryPanel.tsx
|
|
10437
10939
|
import { useState as useState14 } from "react";
|
|
@@ -10704,7 +11206,7 @@ var MODUS_TEXT = {
|
|
|
10704
11206
|
};
|
|
10705
11207
|
var BelegFeld = ({ titel, text, testId, offen }) => {
|
|
10706
11208
|
const [kopiert, setKopiert] = useState16(false);
|
|
10707
|
-
const feld =
|
|
11209
|
+
const feld = useRef4(null);
|
|
10708
11210
|
async function kopieren() {
|
|
10709
11211
|
try {
|
|
10710
11212
|
await navigator.clipboard.writeText(text);
|
|
@@ -10803,7 +11305,7 @@ var ERSTE_KACHELN = 12;
|
|
|
10803
11305
|
function useSichtbareKacheln(alle, wurzel) {
|
|
10804
11306
|
const [gesehen, setGesehen] = useState16([]);
|
|
10805
11307
|
const schluessel = alle.join(" ");
|
|
10806
|
-
|
|
11308
|
+
useEffect8(() => {
|
|
10807
11309
|
const ziel = wurzel.current;
|
|
10808
11310
|
if (!ziel || typeof IntersectionObserver === "undefined") return void 0;
|
|
10809
11311
|
const beobachter = new IntersectionObserver((eintraege) => {
|
|
@@ -10822,10 +11324,10 @@ function useSichtbareKacheln(alle, wurzel) {
|
|
|
10822
11324
|
}
|
|
10823
11325
|
function useVorschauen(port, mediaRefs) {
|
|
10824
11326
|
const [stand, setStand] = useState16(() => ({ quellen: /* @__PURE__ */ new Map(), gescheitert: /* @__PURE__ */ new Set() }));
|
|
10825
|
-
const gehalten =
|
|
10826
|
-
const ohneBild =
|
|
11327
|
+
const gehalten = useRef4(/* @__PURE__ */ new Map());
|
|
11328
|
+
const ohneBild = useRef4(/* @__PURE__ */ new Set());
|
|
10827
11329
|
const schluessel = mediaRefs.join(" ");
|
|
10828
|
-
|
|
11330
|
+
useEffect8(() => {
|
|
10829
11331
|
const bestand = port.imageLibrary;
|
|
10830
11332
|
if (!bestand?.loadPreview) return void 0;
|
|
10831
11333
|
const refs = schluessel ? schluessel.split(" ") : [];
|
|
@@ -10865,7 +11367,7 @@ function useVorschauen(port, mediaRefs) {
|
|
|
10865
11367
|
var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
|
|
10866
11368
|
const [suche, setSuche] = useState16("");
|
|
10867
11369
|
const [fokus, setFokus] = useState16(null);
|
|
10868
|
-
const browser =
|
|
11370
|
+
const browser = useRef4(null);
|
|
10869
11371
|
const [items] = usePortQuery(
|
|
10870
11372
|
() => port.imageLibrary.listItems({ search: suche.trim() || void 0, limit: 60 }),
|
|
10871
11373
|
[port, suche]
|
|
@@ -11092,8 +11594,6 @@ var DeriveArea = ({ port, contextId }) => {
|
|
|
11092
11594
|
if (ergebnis.kind === "ok") setLauf(ergebnis.value);
|
|
11093
11595
|
else if (ergebnis.kind === "unsupported") {
|
|
11094
11596
|
setMeldung(`Dieser Host bietet \u201E${ergebnis.capability}" nicht an.`);
|
|
11095
|
-
} else if (ergebnis.kind === "rejected") {
|
|
11096
|
-
setMeldung(ergebnis.errors.map((e) => e.message).join("; "));
|
|
11097
11597
|
} else {
|
|
11098
11598
|
setMeldung(ergebnis.message);
|
|
11099
11599
|
}
|
|
@@ -11183,8 +11683,6 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
|
|
|
11183
11683
|
});
|
|
11184
11684
|
if (ergebnis.kind === "ok") {
|
|
11185
11685
|
setUebernommen((v) => ({ ...v, [type]: ergebnis.value.elementId }));
|
|
11186
|
-
} else if (ergebnis.kind === "rejected") {
|
|
11187
|
-
setMeldung(ergebnis.errors.map((e) => e.message).join("; "));
|
|
11188
11686
|
} else if (ergebnis.kind === "unsupported") {
|
|
11189
11687
|
setMeldung(`Dieser Host bietet \u201E${ergebnis.capability}" nicht an.`);
|
|
11190
11688
|
} else {
|
|
@@ -14950,11 +15448,14 @@ function findImageGenerationOrder(events, batchId) {
|
|
|
14950
15448
|
|
|
14951
15449
|
// src/lib/szenen/imageBatchStore.ts
|
|
14952
15450
|
var istText6 = (wert) => typeof wert === "string" && wert.trim().length > 0;
|
|
14953
|
-
function alsBilder(rohe) {
|
|
15451
|
+
function alsBilder(rohe, generationBatchId) {
|
|
14954
15452
|
if (!Array.isArray(rohe)) return [];
|
|
14955
15453
|
return rohe.filter((b) => !!b && typeof b === "object").filter((b) => istText6(b.media_ref) && typeof b.position === "number").map((b) => ({
|
|
14956
15454
|
media_ref: b.media_ref,
|
|
14957
15455
|
position: b.position,
|
|
15456
|
+
// Welcher Provideraufruf dieses Bild geliefert hat (§8) — aus dem
|
|
15457
|
+
// Ereignis, in dem es steht, nicht aus seiner Position abgeleitet.
|
|
15458
|
+
generation_batch_id: generationBatchId,
|
|
14958
15459
|
...istText6(b.asset_id) ? { asset_id: b.asset_id } : {},
|
|
14959
15460
|
// Der bestätigte MIME-Typ (Review 2026-08-18 §5 P2) muss durch das
|
|
14960
15461
|
// Rücklesen hindurch: Genau hier braucht ihn der Lesepfad, um den
|
|
@@ -14967,6 +15468,11 @@ function alsBilder(rohe) {
|
|
|
14967
15468
|
height: b.height ?? null
|
|
14968
15469
|
}));
|
|
14969
15470
|
}
|
|
15471
|
+
function gesamtHerkunft(origins) {
|
|
15472
|
+
const vertreten = new Set(origins.map((o) => o.source_kind));
|
|
15473
|
+
if (vertreten.size === 1) return [...vertreten][0];
|
|
15474
|
+
return "mixed";
|
|
15475
|
+
}
|
|
14970
15476
|
function collectImageBatches(events) {
|
|
14971
15477
|
const byItemId = /* @__PURE__ */ new Map();
|
|
14972
15478
|
for (const event of events) {
|
|
@@ -14976,21 +15482,29 @@ function collectImageBatches(events) {
|
|
|
14976
15482
|
if (payload.source_kind !== "generated_in_app" && payload.source_kind !== "external_import") continue;
|
|
14977
15483
|
const bestehend = byItemId.get(payload.item_id);
|
|
14978
15484
|
if (bestehend?.generation_batch_ids.includes(payload.generation_batch_id)) continue;
|
|
14979
|
-
const bilder = alsBilder(payload.images);
|
|
15485
|
+
const bilder = alsBilder(payload.images, payload.generation_batch_id);
|
|
15486
|
+
const herkunft = {
|
|
15487
|
+
generation_batch_id: payload.generation_batch_id,
|
|
15488
|
+
source_kind: payload.source_kind
|
|
15489
|
+
};
|
|
14980
15490
|
if (!bestehend) {
|
|
14981
15491
|
byItemId.set(payload.item_id, {
|
|
14982
15492
|
item_id: payload.item_id,
|
|
14983
15493
|
prompt_run_id: payload.prompt_run_id,
|
|
14984
15494
|
generation_batch_ids: [payload.generation_batch_id],
|
|
14985
15495
|
source_kind: payload.source_kind,
|
|
15496
|
+
origins: [herkunft],
|
|
14986
15497
|
title: istText6(payload.title) ? payload.title : `Batch aus Lauf ${payload.prompt_run_id}`,
|
|
14987
15498
|
images: bilder
|
|
14988
15499
|
});
|
|
14989
15500
|
continue;
|
|
14990
15501
|
}
|
|
15502
|
+
const origins = [...bestehend.origins, herkunft];
|
|
14991
15503
|
byItemId.set(payload.item_id, {
|
|
14992
15504
|
...bestehend,
|
|
14993
15505
|
generation_batch_ids: [...bestehend.generation_batch_ids, payload.generation_batch_id],
|
|
15506
|
+
origins,
|
|
15507
|
+
source_kind: gesamtHerkunft(origins),
|
|
14994
15508
|
images: [...bestehend.images, ...bilder]
|
|
14995
15509
|
});
|
|
14996
15510
|
}
|
|
@@ -15109,13 +15623,21 @@ async function legeBatchAb(options, input) {
|
|
|
15109
15623
|
`Die Batch-Metadaten fuer ${input.generationBatchId} konnten nicht protokolliert werden, obwohl die Bilder bereits im Bestand liegen: ${error instanceof Error ? error.message : String(error)}`
|
|
15110
15624
|
);
|
|
15111
15625
|
}
|
|
15626
|
+
const origins = [
|
|
15627
|
+
...bestehend?.origins ?? [],
|
|
15628
|
+
{ generation_batch_id: input.generationBatchId, source_kind: input.sourceKind }
|
|
15629
|
+
];
|
|
15112
15630
|
const zusammengefuehrt = {
|
|
15113
15631
|
item_id: itemId,
|
|
15114
15632
|
prompt_run_id: input.runId,
|
|
15115
15633
|
generation_batch_ids: bestehend ? [...bestehend.generation_batch_ids, input.generationBatchId] : [input.generationBatchId],
|
|
15116
|
-
source_kind:
|
|
15634
|
+
source_kind: gesamtHerkunft(origins),
|
|
15635
|
+
origins,
|
|
15117
15636
|
title: titel,
|
|
15118
|
-
images: [
|
|
15637
|
+
images: [
|
|
15638
|
+
...bestehend?.images ?? [],
|
|
15639
|
+
...abgelegt.map((bild) => ({ ...bild, generation_batch_id: input.generationBatchId }))
|
|
15640
|
+
]
|
|
15119
15641
|
};
|
|
15120
15642
|
return { kind: "ok", value: zusammengefuehrt };
|
|
15121
15643
|
}
|
|
@@ -15560,6 +16082,15 @@ export {
|
|
|
15560
16082
|
preferredHeadRevisionOf,
|
|
15561
16083
|
collectPromptRuns,
|
|
15562
16084
|
findPromptRun,
|
|
16085
|
+
DEFAULT_SEED_VORLAGE,
|
|
16086
|
+
parseSeedListe,
|
|
16087
|
+
formatSeedListe,
|
|
16088
|
+
ordneSeedsZu,
|
|
16089
|
+
seedFehlerText,
|
|
16090
|
+
mitDefaultVorlage,
|
|
16091
|
+
UPLOAD_MAX_BYTES,
|
|
16092
|
+
istZipDatei,
|
|
16093
|
+
leseBilderAusZip,
|
|
15563
16094
|
ladeVorschauen,
|
|
15564
16095
|
simulatedAnswerFor,
|
|
15565
16096
|
SIMULATION_PROVIDER,
|
|
@@ -15642,6 +16173,7 @@ export {
|
|
|
15642
16173
|
collectImageGenerationOrders,
|
|
15643
16174
|
ordersForPromptRun,
|
|
15644
16175
|
findImageGenerationOrder,
|
|
16176
|
+
gesamtHerkunft,
|
|
15645
16177
|
collectImageBatches,
|
|
15646
16178
|
batchesForPromptRun,
|
|
15647
16179
|
findImageBatch,
|