From 0a3271cdd7fec7ffa4cca5e15caee23fd32fdf9c Mon Sep 17 00:00:00 2001 From: Ewald <129623145+MajoorWaldi@users.noreply.github.com> Date: Wed, 3 Jun 2026 17:15:29 +0200 Subject: [PATCH] Fix workflow graph map sampler params --- ...Bn-T0zen.js => FloatingViewer-iLhVlgRh.js} | 736 ++++++++++-------- ...NiQmZ.js => LiveStreamTracker-CEpotRa4.js} | 2 +- ...K.js => floatingViewerManager-CYnEwEgo.js} | 2 +- dist/entry.js | 4 +- .../workflowGraphMap/WorkflowGraphMapPanel.ts | 31 +- .../workflowGraphMap/workflowGraphMapData.ts | 103 ++- ui/tests/workflow_graph_map_data.vitest.ts | 118 ++- 7 files changed, 643 insertions(+), 353 deletions(-) rename dist/chunks/{FloatingViewer-Bn-T0zen.js => FloatingViewer-iLhVlgRh.js} (93%) rename dist/chunks/{LiveStreamTracker-C7oNiQmZ.js => LiveStreamTracker-CEpotRa4.js} (98%) rename dist/chunks/{floatingViewerManager-I_zH7WzK.js => floatingViewerManager-CYnEwEgo.js} (99%) diff --git a/dist/chunks/FloatingViewer-Bn-T0zen.js b/dist/chunks/FloatingViewer-iLhVlgRh.js similarity index 93% rename from dist/chunks/FloatingViewer-Bn-T0zen.js rename to dist/chunks/FloatingViewer-iLhVlgRh.js index a7cee141..918c7e82 100644 --- a/dist/chunks/FloatingViewer-Bn-T0zen.js +++ b/dist/chunks/FloatingViewer-iLhVlgRh.js @@ -781,19 +781,19 @@ async function lt(e) { } catch {} } function ut(e) { - let t = Mt(e); + let t = jt(e), n = Mt(e); for (let e of t) { - let t = Pt(Nt(e)); - if (t) return It(t), t; + let t = Nt(K(e)); + if (t) return It(t, n), Ft(t), t; } return null; } function dt(e, t = null) { let n = t?.includeSubgraphs !== !1, r = Array.isArray(e?.nodes) ? e.nodes.filter(Boolean) : []; if (!n) return r; - let i = [...r], a = q(e); + let i = [...r], a = J(e); for (let n of r) { - let r = Gt(e, n, a); + let r = Y(e, n, a); r && i.push(...dt(r, t)); } return i; @@ -802,11 +802,11 @@ function ft(e, t, n = null) { let r = n?.includeSubgraphs !== !1, i = String(t ?? ""); if (!i) return null; if (!r) return (Array.isArray(e?.nodes) ? e.nodes : []).find((e) => String(e?.id ?? e?.ID ?? "") === i) || null; - if (i.includes("::")) return Kt(e, i.split("::").filter(Boolean)); + if (i.includes("::")) return Yt(e, i.split("::").filter(Boolean)); let a = (Array.isArray(e?.nodes) ? e.nodes : []).find((e) => String(e?.id ?? e?.ID ?? "") === i) || null; if (a) return a; for (let t of Array.isArray(e?.nodes) ? e.nodes : []) { - let n = Gt(e, t, q(e)), r = n ? ft(n, i) : null; + let n = Y(e, t, J(e)), r = n ? ft(n, i) : null; if (r) return r; } return null; @@ -830,8 +830,9 @@ function ht(e) { return t.slice(0, 160); } function gt(e) { - let t = [], n = e?.inputs && typeof e.inputs == "object" ? e.inputs : null; + let t = [], n = e?._mjrPromptInputs && typeof e._mjrPromptInputs == "object" ? e._mjrPromptInputs : null, r = e?.inputs && typeof e.inputs == "object" ? e.inputs : null; if (n && !Array.isArray(n)) for (let [e, r] of Object.entries(n)) St(r) || t.push([e, r]); + if (r && !Array.isArray(r)) for (let [e, n] of Object.entries(r)) St(n) || t.some(([t]) => String(t) === String(e)) || t.push([e, n]); for (let { label: n, value: r } of _t(e)) t.some(([e]) => String(e) === String(n)) || t.push([n, r]); return t; } @@ -844,9 +845,9 @@ function _t(e) { })); let n = yt(t), r = Array.isArray(e?.widgets) ? e.widgets : [], i = Et(wt(e)), a = xt(e); return n.map((t, n) => { - let o = jt(e, n, t); + let o = At(e, n, t); return { - label: i[n] || a[n] || r[n]?.name || r[n]?.label || o || `param ${n + 1}`, + label: a[n] || r[n]?.name || r[n]?.label || i[n] || o || `param ${n + 1}`, value: t, index: n }; @@ -868,19 +869,18 @@ function bt(e) { return !(!Number.isFinite(t) || t < 0); } function xt(e) { - let t = Array.isArray(e?.inputs) ? e.inputs : [], n = t.filter(Dt), r = t.filter((e) => !Ot(e) && At(e?.type)), i = [], a = /* @__PURE__ */ new Set(), o = (e) => { + let t = (Array.isArray(e?.inputs) ? e.inputs : []).filter(Dt), n = [], r = /* @__PURE__ */ new Set(), i = (e) => { let t = `${String(e?.name || "")}\u0000${String(e?.label || "")}\u0000${String(e?.link ?? "")}`; - a.has(t) || (a.add(t), i.push(e)); + r.has(t) || (r.add(t), n.push(e)); }; - for (let e of n) o(e); - for (let e of r) o(e); - return i.map((e) => String(e?.label || e?.localized_name || e?.name || e?.widget?.name || e?.widget?.label || "").trim()); + for (let e of t) i(e); + return n.map((e) => String(e?.label || e?.localized_name || e?.name || e?.widget?.name || e?.widget?.label || "").trim()); } function St(e) { return Array.isArray(e) && e.length === 2 && String(e[0] ?? "").trim() !== "" && Number.isFinite(Number(e[1])); } function Ct(e) { - let t = K(String(e ?? "").trim()); + let t = q(String(e ?? "").trim()); return t ? t === "cnr_id" || t === "ver" || t === "node_name_for_s&r" || t === "subgraph_name" || t === "subgraph_id" || t === "enabletabs" || t === "tabwidth" || t === "tabxoffset" || t === "hassecondtab" || t === "secondtabtext" || t === "secondtaboffset" || t === "secondtabwidth" || t.startsWith("ue_") : !0; } function wt(e) { @@ -899,28 +899,34 @@ function Et(e) { let n = []; for (let e of ["required", "optional"]) { let r = t[e]; - if (!(!r || typeof r != "object")) for (let [e, t] of Object.entries(r)) kt(t) && n.push(e); + if (!(!r || typeof r != "object")) for (let [e, t] of Object.entries(r)) Ot(t) && n.push(e); } return n.length ? n : Tt(e); } function Dt(e) { - return !e || typeof e != "object" ? !1 : !!(e.widget === !0 || e.widget && typeof e.widget == "object" || typeof e.widget == "string" && e.widget.trim()); + return !e || typeof e != "object" ? !1 : !!(e.widget === !0 || e.widget && typeof e.widget == "object" || typeof e.widget == "string" && e.widget.trim() || e.widget_index != null || e.widgetIndex != null); } function Ot(e) { - return !e || typeof e != "object" ? !1 : !!(e.link != null || Array.isArray(e.links) && e.links.length); + let t = Array.isArray(e) ? e : [], n = t[0], r = t[1] && typeof t[1] == "object" && !Array.isArray(t[1]) ? t[1] : null; + return r?.forceInput === !0 || r?.rawLink === !0 ? !1 : r?.widgetType && String(r.widgetType).trim() ? !0 : kt(n); } function kt(e) { - let t = Array.isArray(e) ? e : [], n = t[0], r = t[1] && typeof t[1] == "object" && !Array.isArray(t[1]) ? t[1] : null; - return r?.forceInput === !0 || r?.rawLink === !0 ? !1 : r?.widgetType && String(r.widgetType).trim() ? !0 : At(n); -} -function At(e) { if (Array.isArray(e)) return !0; let t = String(e || "").trim().toUpperCase(); return t ? t === "INT" || t === "FLOAT" || t === "STRING" || t === "BOOLEAN" || t === "BOOL" || t === "COMBO" || t === "ENUM" : !1; } -function jt(e, t, n) { +function At(e, t, n) { let r = G(e), i = pt(e), a = `${r} ${i}`.toLowerCase(), o = String(n ?? "").toLowerCase(); if (a.includes("ksamplerselect")) return "sampler_name"; + if (a.includes("ksampler")) return [ + "seed", + "control_after_generate", + "steps", + "cfg", + "sampler_name", + "scheduler", + "denoise" + ][t] || null; if (a.includes("manualsigmas")) return "sigmas"; if (a.includes("randomnoise")) return t === 0 ? "noise_seed" : t === 1 ? "control_after_generate" : null; if (a.includes("cfgguider")) return "cfg"; @@ -938,8 +944,8 @@ function jt(e, t, n) { if (t === 2) return "device"; } if (/primitive(?:int|float|string|boolean)|constant/.test(a) && t === 0) { - let e = K(i); - return e && e !== K(r) ? e : "value"; + let e = q(i); + return e && e !== q(r) ? e : "value"; } if (a.includes("cliptext") || a.includes("prompt")) return t === 0 ? "text" : null; if (o.includes(".safetensors") || o.includes(".ckpt")) return "model"; @@ -951,8 +957,8 @@ function jt(e, t, n) { } return null; } -function Mt(e) { - let t = Nt(e?.metadata_raw), n = Nt(e?.metadata); +function jt(e) { + let t = K(e?.metadata_raw), n = K(e?.metadata); return [ e?.workflow, e?.Workflow, @@ -993,7 +999,22 @@ function Mt(e) { n?.Prompt ].filter((e) => e != null); } -function Nt(e) { +function Mt(e) { + let t = K(e?.metadata_raw), n = K(e?.metadata), r = [ + e?.prompt, + e?.Prompt, + t?.prompt, + t?.Prompt, + n?.prompt, + n?.Prompt + ]; + for (let e of r) { + let t = K(e); + if (t && typeof t == "object" && !Array.isArray(t)) return t; + } + return null; +} +function K(e) { if (!e) return null; if (typeof e == "object") return e; if (typeof e != "string") return null; @@ -1005,16 +1026,16 @@ function Nt(e) { return null; } } -function Pt(e) { +function Nt(e) { if (!e || typeof e != "object") return null; if (Array.isArray(e.nodes)) return e; - let t = Ft(e); + let t = Pt(e); if (t) return t; if (e.prompt && typeof e.prompt == "object") return k(e.prompt); let n = k(e); return n && Array.isArray(n.nodes) ? n : null; } -function Ft(e) { +function Pt(e) { for (let t of [ "workflow", "Workflow", @@ -1030,38 +1051,82 @@ function Ft(e) { } return null; } -function It(e, t = /* @__PURE__ */ new WeakSet()) { +function Ft(e, t = /* @__PURE__ */ new WeakSet()) { if (!e || typeof e != "object" || t.has(e)) return; t.add(e); - let n = q(e); + let n = J(e); for (let r of Array.isArray(e?.nodes) ? e.nodes : []) { - Lt(r, n); - let i = Gt(e, r, n); - i && (Rt(r, i), It(i, t)); + Vt(r, n); + let i = Y(e, r, n); + i && (Ht(r, i), Ft(i, t)); } } -function Lt(e, t) { +function It(e, t) { + if (!e || typeof e != "object" || !t || typeof t != "object") return; + let n = Rt(t); + n.length && Lt(e, n, /* @__PURE__ */ new WeakSet()); +} +function Lt(e, t, n) { + if (!e || typeof e != "object" || n.has(e)) return; + n.add(e); + let r = J(e); + for (let i of Array.isArray(e?.nodes) ? e.nodes : []) { + let a = zt(i, t); + a?.inputs && typeof a.inputs == "object" && !Array.isArray(a.inputs) && (i._mjrPromptInputs = a.inputs); + let o = Y(e, i, r); + o && Lt(o, t, n); + } +} +function Rt(e) { + if (!e || typeof e != "object" || Array.isArray(e)) return []; + let t = []; + for (let [n, r] of Object.entries(e)) { + if (!r || typeof r != "object" || Array.isArray(r)) continue; + let e = String(r.class_type || r.type || "").trim(), i = r.inputs; + if (!e || !i || typeof i != "object" || Array.isArray(i)) continue; + let a = String(n).split(":").pop() || String(n); + t.push({ + id: String(n), + leafId: a, + classType: e, + inputs: i + }); + } + return t; +} +function zt(e, t) { + let n = String(e?.id ?? e?.ID ?? "").trim(), r = Bt(G(e)); + if (!n || !r) return null; + let i = t.find((e) => e.id === n && Bt(e.classType) === r); + if (i) return i; + let a = t.filter((e) => e.leafId === n && Bt(e.classType) === r); + return a.length === 1 ? a[0] : null; +} +function Bt(e) { + return String(e || "").trim().toLowerCase(); +} +function Vt(e, t) { if (!e || typeof e != "object") return; - let n = Wt(e).find((e) => t.has(String(e))); + let n = Jt(e).find((e) => t.has(String(e))); if (!n) return; let r = t.get(String(n)), i = String(r?.name || r?.title || e?.subgraph?.name || e?.subgraph_instance?.name || "").trim(); if (!i) return; let a = e?.properties && typeof e.properties == "object" ? e.properties : e.properties = {}; String(a.subgraph_name || "").trim() || (a.subgraph_name = i), String(a.subgraph_id || "").trim() || (a.subgraph_id = n); } -function Rt(e, t) { +function Ht(e, t) { let n = Array.isArray(e?.properties?.proxyWidgets) ? e.properties.proxyWidgets : []; if (!n.length || !Array.isArray(t?.nodes)) return; - let r = new Map(t.nodes.filter(Boolean).map((e) => [String(e?.id ?? e?.ID ?? ""), e])), i = zt(e), a = Bt(t), o = []; + let r = new Map(t.nodes.filter(Boolean).map((e) => [String(e?.id ?? e?.ID ?? ""), e])), i = Ut(e), a = Wt(t), o = []; for (let e = 0; e < n.length; e += 1) { let t = n[e], s = Array.isArray(t) ? t[0] : t?.nodeId ?? t?.node_id ?? t?.id, c = Array.isArray(t) ? t[1] : t?.widget ?? t?.name ?? t?.widgetName, l = r.get(String(s ?? "")); if (!l) continue; let u = ht(l); if (!u.length) continue; - let d = u.find(([e]) => K(e) === K(c)) || u.find(([e]) => K(e) === "value") || (u.length === 1 ? u[0] : null); + let d = u.find(([e]) => q(e) === q(c)) || u.find(([e]) => q(e) === "value") || (u.length === 1 ? u[0] : null); if (!d) continue; - let f = `${String(s)}:${Vt(t, c, d[0])}`, p = a.get(f) || a.get(String(s)) || Ht(l, d[0], c); - i.size && !i.has(K(p)) || o.push({ + let f = `${String(s)}:${Gt(t, c, d[0])}`, p = a.get(f) || a.get(String(s)) || Kt(l, d[0], c); + i.size && !i.has(q(p)) || o.push({ label: p, value: d[1], innerNodeId: s, @@ -1070,49 +1135,49 @@ function Rt(e, t) { } o.length && (e._mjrSubgraphProxyParams = o); } -function zt(e) { +function Ut(e) { let t = Array.isArray(e?.inputs) ? e.inputs : [], n = /* @__PURE__ */ new Set(); for (let e of t) { if (!Dt(e)) continue; let t = String(e?.label || e?.localized_name || e?.name || "").trim(); - t && n.add(K(t)); + t && n.add(q(t)); } return n; } -function Bt(e) { +function Wt(e) { let t = Array.isArray(e?.inputs) ? e.inputs : [], n = Array.isArray(e?.links) ? e.links : [], r = /* @__PURE__ */ new Map(); for (let e of n) { let n = Array.isArray(e) ? e[1] : e?.origin_id ?? e?.originId ?? e?.from; if (String(n) !== "-10") continue; let i = Number(Array.isArray(e) ? e[2] : e?.origin_slot ?? e?.originSlot ?? e?.fromSlot), a = Array.isArray(e) ? e[3] : e?.target_id ?? e?.targetId ?? e?.to, o = Number(Array.isArray(e) ? e[4] : e?.target_slot ?? e?.targetSlot ?? e?.toSlot), s = Number.isFinite(i) ? t[i] : null, c = String(s?.label || s?.localized_name || s?.name || "").trim(); - !c || a == null || K(c) !== "value" && (r.set(String(a), c), Number.isFinite(o) && r.set(`${String(a)}:${o}`, c)); + !c || a == null || q(c) !== "value" && (r.set(String(a), c), Number.isFinite(o) && r.set(`${String(a)}:${o}`, c)); } return r; } -function Vt(e, t, n) { +function Gt(e, t, n) { if (e && typeof e == "object" && !Array.isArray(e)) { let t = e.target_slot ?? e.targetSlot ?? e.slot; if (Number.isFinite(Number(t))) return Number(t); } return 0; } -function Ht(e, t, n) { +function Kt(e, t, n) { let r = String(pt(e) || "").trim(), i = String(t || n || "").trim(); - return r && i && K(i) !== "value" ? `${r} ${i}` : r || i || "param"; -} -function K(e) { - return String(e ?? "").trim().toLowerCase().replace(/\s+/g, "_"); + return r && i && q(i) !== "value" ? `${r} ${i}` : r || i || "param"; } function q(e) { + return String(e ?? "").trim().toLowerCase().replace(/\s+/g, "_"); +} +function J(e) { let t = [ ...Array.isArray(e?.definitions?.subgraphs) ? e.definitions.subgraphs : [], ...Array.isArray(e?.subgraphs) ? e.subgraphs : [], ...Array.isArray(e?.rootGraph?.subgraphs) ? e.rootGraph.subgraphs : [] ], n = /* @__PURE__ */ new Map(); - for (let e of t) for (let t of Ut(e)) t != null && n.set(String(t), e); + for (let e of t) for (let t of qt(e)) t != null && n.set(String(t), e); return n; } -function Ut(e) { +function qt(e) { let t = e?.properties && typeof e.properties == "object" ? e.properties : {}; return [ e?.id, @@ -1126,7 +1191,7 @@ function Ut(e) { t.subgraphId ].filter((e) => e != null && String(e).trim()); } -function Wt(e) { +function Jt(e) { let t = e?.properties && typeof e.properties == "object" ? e.properties : {}; return [ e?.type, @@ -1138,7 +1203,7 @@ function Wt(e) { t.subgraph_name ].filter((e) => e != null && String(e).trim()); } -function Gt(e, t, n = q(e)) { +function Y(e, t, n = J(e)) { let r = [ t?.subgraph, t?._subgraph, @@ -1149,18 +1214,18 @@ function Gt(e, t, n = q(e)) { t?.subgraph_instance?.graph, t?.inner_graph, t?.subgraph_graph, - ...Wt(t).map((e) => n.get(String(e))) + ...Jt(t).map((e) => n.get(String(e))) ]; for (let e of r) if (e && typeof e == "object" && Array.isArray(e.nodes)) return e; return Array.isArray(t?.nodes) ? { nodes: t.nodes } : null; } -function Kt(e, t) { +function Yt(e, t) { let n = e, r = null; for (let e = 0; e < t.length; e += 1) { let i = String(t[e] ?? "").trim(); if (!i || (r = (Array.isArray(n?.nodes) ? n.nodes : []).find((e) => String(e?.id ?? e?.ID ?? "") === i) || null, !r)) return null; if (e >= t.length - 1) break; - let a = Gt(n, r, q(n)); + let a = Y(n, r, J(n)); if (!a) return null; n = a; } @@ -1168,13 +1233,13 @@ function Kt(e, t) { } //#endregion //#region ui/features/viewer/workflowGraphMap/workflowGraphMapActions.ts -async function qt(e) { +async function Xt(e) { return e ? te(JSON.stringify(e, null, 2)) : !1; } -async function Jt(e) { - return te(Yt(e)); +async function Zt(e) { + return te(Qt(e)); } -function Yt(e) { +function Qt(e) { if (e == null) return ""; if (typeof e == "string") return e; if (typeof e == "number" || typeof e == "boolean") return String(e); @@ -1184,10 +1249,10 @@ function Yt(e) { return String(e); } } -function Xt(e) { +function $t(e) { return r(e); } -function Zt(e) { +function en(e) { let t = s(); if (!e || !t || typeof t.add != "function") return !1; let n = String(e?.type || e?.class_type || e?.comfyClass || "").trim(), r = globalThis, i = r?.LiteGraph || r?.window?.LiteGraph || null, a = null; @@ -1204,8 +1269,8 @@ function Zt(e) { return console.debug?.("[MFV Graph Map] import node failed", e), !1; } } -function Qt(e) { - let t = $t(); +function tn(e) { + let t = nn(); if (!e || !t) return { ok: !1, count: 0, @@ -1219,14 +1284,14 @@ function Qt(e) { }; let i = /* @__PURE__ */ new Map(); r.forEach((e, t) => { - for (let n of en(e)) i.has(n) || i.set(n, { + for (let n of rn(e)) i.has(n) || i.set(n, { widget: e, index: t }); }); - let o = nn(G(e)), s = nn(t?.type || t?.comfyClass || t?.class_type), c = !!(o && s && o === s), l = /* @__PURE__ */ new Set(), u = 0; + let o = on(G(e)), s = on(t?.type || t?.comfyClass || t?.class_type), c = !!(o && s && o === s), l = /* @__PURE__ */ new Set(), u = 0; for (let e of n) { - let n = tn(e.label), a = n ? i.get(n) : null; + let n = an(e.label), a = n ? i.get(n) : null; if ((!a || l.has(a.index)) && c) { let t = r[e.index]; t && (a = { @@ -1234,7 +1299,7 @@ function Qt(e) { index: e.index }); } - !a || l.has(a.index) || ie(a.widget, rn(e.value), t) && (l.add(a.index), u += 1); + !a || l.has(a.index) || ie(a.widget, sn(e.value), t) && (l.add(a.index), u += 1); } return a(), { ok: u > 0, @@ -1243,24 +1308,24 @@ function Qt(e) { targetNode: t }; } -function $t() { +function nn() { return v() || null; } -function en(e) { +function rn(e) { return [ e?.name, e?.label, e?.options?.name, e?.options?.label - ].map(tn).filter(Boolean); + ].map(an).filter(Boolean); } -function tn(e) { +function an(e) { return String(e ?? "").trim().toLowerCase().replace(/\s+/g, "_"); } -function nn(e) { +function on(e) { return String(e ?? "").trim().toLowerCase(); } -function rn(e) { +function sn(e) { if (typeof e != "object" || !e) return e; try { return typeof structuredClone == "function" ? structuredClone(e) : JSON.parse(JSON.stringify(e)); @@ -1270,7 +1335,7 @@ function rn(e) { } //#endregion //#region ui/features/viewer/workflowGraphMap/WorkflowGraphMapPanel.ts -var an = class { +var cn = class { constructor({ large: e = !1 } = {}) { this._asset = null, this._workflow = null, this._selectedNodeId = "", this._renderInfo = null, this._resizeObserver = null, this._resizeObservedTarget = null, this._resizeObserverWindow = null, this._large = !!e, this._view = { zoom: 1, @@ -1303,7 +1368,7 @@ var an = class { _ensureResizeObserver() { let e = this._mapWrap; if (!e) return; - let t = J(e), n = t?.ResizeObserver || globalThis.ResizeObserver; + let t = X(e), n = t?.ResizeObserver || globalThis.ResizeObserver; if (typeof n == "function" && !(this._resizeObserver && this._resizeObservedTarget === e && this._resizeObserverWindow === t)) { try { this._resizeObserver?.disconnect?.(); @@ -1324,7 +1389,7 @@ var an = class { } let e = this._canvas; if (!e) return; - let t = e.getBoundingClientRect(), n = Math.max(1, Math.floor(t.width || e.clientWidth || 1)), r = Math.max(1, Math.floor(t.height || e.clientHeight || 1)), i = J(e), a = Math.max(1, Math.min(2, Number(i?.devicePixelRatio) || 1)), o = Math.floor(n * a), s = Math.floor(r * a); + let t = e.getBoundingClientRect(), n = Math.max(1, Math.floor(t.width || e.clientWidth || 1)), r = Math.max(1, Math.floor(t.height || e.clientHeight || 1)), i = X(e), a = Math.max(1, Math.min(2, Number(i?.devicePixelRatio) || 1)), o = Math.floor(n * a), s = Math.floor(r * a); (e.width !== o || e.height !== s) && (e.width = o, e.height = s); let c = e.getContext?.("2d"); if (c && c.setTransform(a, 0, 0, a, 0, 0), !this._workflow) { @@ -1346,14 +1411,14 @@ var an = class { _renderDetails() { let e = this._subgraphDisplayMode !== "host", t = dt(this._workflow, { includeSubgraphs: e }).length; if (!this._workflow) { - this._status.textContent = this._large ? "No workflow graph in selected image" : "Selected asset - no workflow graph", Y(this._details); + this._status.textContent = this._large ? "No workflow graph in selected image" : "Selected asset - no workflow graph", Z(this._details); return; } this._status.textContent = this._large ? this._selectedNodeId ? `${t} nodes (${this._subgraphDisplayMode}) - selected #${this._selectedNodeId}` : `${t} nodes (${this._subgraphDisplayMode}) - select a node` : `${t} nodes - graph opened in viewer`; let n = ft(this._workflow, this._selectedNodeId, { includeSubgraphs: e }); if (!n) { let e = document.createElement("div"); - e.className = "mjr-ws-sidebar-empty", e.textContent = this._large ? "Click a node in the graph map" : "Use the large Graph Map in the viewer to select nodes", Y(this._details, e); + e.className = "mjr-ws-sidebar-empty", e.textContent = this._large ? "Click a node in the graph map" : "Use the large Graph Map in the viewer to select nodes", Z(this._details, e); return; } let r = document.createElement("div"); @@ -1361,9 +1426,9 @@ var an = class { let i = document.createElement("div"); i.className = "mjr-wgm-node-meta", i.textContent = `#${this._selectedNodeId} ${mt(n) || G(n) || "Node"}`; let a = document.createElement("div"); - a.className = "mjr-wgm-actions", a.appendChild(this._makeAction("Copy node", "pi pi-copy", () => qt(n))), a.appendChild(this._makeAction("Import node", "pi pi-plus-circle", () => Zt(n))), a.appendChild(this._makeAction("Import workflow", "pi pi-download", () => Xt(this._workflow))), a.appendChild(this._makeAction("Transfer params to selected canvas node", "pi pi-arrow-right-arrow-left", () => Qt(n)?.ok)); + a.className = "mjr-wgm-actions", a.appendChild(this._makeAction("Copy node", "pi pi-copy", () => Xt(n))), a.appendChild(this._makeAction("Import node", "pi pi-plus-circle", () => en(n))), a.appendChild(this._makeAction("Import workflow", "pi pi-download", () => $t(this._workflow))), a.appendChild(this._makeAction("Transfer params to selected canvas node", "pi pi-arrow-right-arrow-left", () => tn(n)?.ok)); let o = this._buildNodeVisual(n); - Y(this._details, r, i, o, a); + Z(this._details, r, i, o, a); } _makeModeButton(e, t) { let n = document.createElement("button"); @@ -1377,7 +1442,7 @@ var an = class { } _buildNodeVisual(e) { let t = document.createElement("section"); - t.className = "mjr-wgm-node-visual", t.classList.add(`is-${mn(e)}`); + t.className = "mjr-wgm-node-visual", t.classList.add(`is-${vn(e)}`); let n = document.createElement("div"); n.className = "mjr-wgm-node-visual-header"; let r = document.createElement("span"); @@ -1392,7 +1457,7 @@ var an = class { c.className = "mjr-wgm-node-widgets"; let l = document.createElement("div"); l.className = "mjr-wgm-node-widgets-title", l.textContent = "Widgets", c.appendChild(l); - let u = pn(e); + let u = _n(e); if (u.length) { for (let e of u.slice(0, 12)) { let t = document.createElement("div"); @@ -1403,8 +1468,8 @@ var an = class { r.className = "mjr-wgm-node-widget-key", r.textContent = n; let i = document.createElement("span"); i.className = "mjr-wgm-node-widget-value"; - let a = sn(e?.value); - i.textContent = a, cn(e?.value, a) && t.classList.add("is-multiline"), ln(n) && t.classList.add("is-text-field"), t.append(r, i), t.addEventListener("click", () => this._copyParam(t, e?.value)), t.addEventListener("keydown", (n) => { + let a = un(e?.value); + i.textContent = a, dn(e?.value, a) && t.classList.add("is-multiline"), fn(n) && t.classList.add("is-text-field"), t.append(r, i), t.addEventListener("click", () => this._copyParam(t, e?.value)), t.addEventListener("keydown", (n) => { n.key !== "Enter" && n.key !== " " || (n.preventDefault?.(), this._copyParam(t, e?.value)); }), c.appendChild(t); } @@ -1425,7 +1490,7 @@ var an = class { i.className = "mjr-wgm-node-ports-title", i.textContent = String(e), r.appendChild(i); let a = document.createElement("div"); a.className = "mjr-wgm-node-ports-list"; - let o = un(t).slice(0, 8); + let o = pn(t).slice(0, 8); if (o.length) for (let e of o) { let t = document.createElement("div"); t.className = "mjr-wgm-node-port"; @@ -1433,7 +1498,7 @@ var an = class { r.className = `mjr-wgm-node-port-dot is-${n}`; let i = document.createElement("span"); i.className = "mjr-wgm-node-port-name"; - let o = dn(e); + let o = hn(e); if (i.textContent = o.label, t.append(r, i), o.type) { let e = document.createElement("span"); e.className = "mjr-wgm-node-port-type", e.textContent = o.type, t.appendChild(e); @@ -1451,7 +1516,7 @@ var an = class { return r.type = "button", r.className = "mjr-wgm-action", r.title = e, r.innerHTML = `${e}`, r.addEventListener("click", async () => { try { let e = await n(); - r.classList.toggle("is-ok", !!e), J(r).setTimeout(() => r.classList.remove("is-ok"), 700); + r.classList.toggle("is-ok", !!e), X(r).setTimeout(() => r.classList.remove("is-ok"), 700); } catch (e) { console.debug?.("[MFV Graph Map] action failed", e); } @@ -1459,19 +1524,19 @@ var an = class { } async _copyParam(e, t) { try { - let n = await Jt(t); - e.classList.toggle("is-ok", !!n), e.classList.toggle("is-error", !n), J(e).setTimeout(() => { + let n = await Zt(t); + e.classList.toggle("is-ok", !!n), e.classList.toggle("is-error", !n), X(e).setTimeout(() => { e.classList.remove("is-ok"), e.classList.remove("is-error"); }, 750); } catch (t) { - e.classList.add("is-error"), J(e).setTimeout(() => e.classList.remove("is-error"), 750), console.debug?.("[MFV Graph Map] param copy failed", t); + e.classList.add("is-error"), X(e).setTimeout(() => e.classList.remove("is-error"), 750), console.debug?.("[MFV Graph Map] param copy failed", t); } } _renderPreview() { if (!this._preview) return; - let e = hn(this._asset), t = gn(e); + let e = yn(this._asset), t = bn(e); if (this._previewMedia && t && t === this._previewKey) { - (this._preview.firstChild !== this._previewMedia || this._preview.childNodes.length !== 1) && Y(this._preview, this._previewMedia); + (this._preview.firstChild !== this._previewMedia || this._preview.childNodes.length !== 1) && Z(this._preview, this._previewMedia); return; } this._disposePreviewMedia(); @@ -1481,7 +1546,7 @@ var an = class { return; } let r = document.createElement("div"); - r.className = "mjr-wgm-preview-empty", r.textContent = "No preview", Y(this._preview, r); + r.className = "mjr-wgm-preview-empty", r.textContent = "No preview", Z(this._preview, r); } _disposePreviewMedia() { let e = this._previewMedia; @@ -1552,24 +1617,24 @@ var an = class { }, r = (e) => { if (!this._drag || e.pointerId !== this._drag.pointerId) return; this._canvas.releasePointerCapture?.(e.pointerId); - let t = J(this._canvas); + let t = X(this._canvas); t.removeEventListener("pointermove", n), t.removeEventListener("pointerup", r), t.removeEventListener("pointercancel", r), t.setTimeout(() => { this._drag = null; }, 0); - }, i = J(this._canvas); + }, i = X(this._canvas); i.addEventListener("pointermove", n), i.addEventListener("pointerup", r), i.addEventListener("pointercancel", r); } }; -function J(e) { +function X(e) { return e?.ownerDocument?.defaultView || window; } -function Y(e, ...t) { +function Z(e, ...t) { if (e) { for (; e.firstChild;) e.removeChild(e.firstChild); for (let n of t) e.appendChild(n); } } -function on(e) { +function ln(e) { if (e == null) return ""; if (typeof e == "string") return e.replace(/\s+/g, " ").trim(); if (typeof e == "number" || typeof e == "boolean") return String(e); @@ -1579,52 +1644,55 @@ function on(e) { return String(e); } } -function sn(e) { - return e == null ? "" : typeof e == "string" ? e.replace(/\r\n?/g, "\n").trim() : on(e); +function un(e) { + return e == null ? "" : typeof e == "string" ? e.replace(/\r\n?/g, "\n").trim() : ln(e); } -function cn(e, t) { +function dn(e, t) { if (typeof e != "string") return !1; let n = String(t || ""); return n.includes("\n") || n.length > 120; } -function ln(e) { +function fn(e) { let t = String(e || "").toLowerCase().replace(/[^a-z0-9]/g, ""); return t ? t === "text" || t === "prompt" || t === "positive" || t === "negative" || t === "string" || t === "caption" : !1; } -function un(e) { - return Array.isArray(e) ? e.filter(Boolean).map((e) => ({ +function pn(e) { + return Array.isArray(e) ? e.filter((e) => e && !mn(e)).map((e) => ({ name: String(e?.name || e?.label || "").trim(), type: String(e?.type || e?.slot_type || e?.data_type || "").trim() })) : []; } -function dn(e) { - let t = String(e?.name || e?.label || e?.type || "port").trim() || "port", n = String(e?.type || "").trim(), r = fn(t), i = fn(n); +function mn(e) { + return !e || typeof e != "object" ? !1 : !!(e.widget === !0 || e.widget && typeof e.widget == "object" || typeof e.widget == "string" && e.widget.trim() || e.widget_index != null || e.widgetIndex != null); +} +function hn(e) { + let t = String(e?.name || e?.label || e?.type || "port").trim() || "port", n = String(e?.type || "").trim(), r = gn(t), i = gn(n); return { label: t, type: i && i !== r ? n : "" }; } -function fn(e) { +function gn(e) { return String(e || "").toLowerCase().replace(/[^a-z0-9]/g, ""); } -function pn(e) { - let t = _t(e); - if (Array.isArray(t) && t.length) return t.map((e) => ({ +function _n(e) { + let t = ht(e), n = Array.isArray(t) ? t.map(([e, t]) => ({ + label: e, + value: t + })) : []; + if (n.length) return n.slice(0, 160); + let r = _t(e); + return Array.isArray(r) && r.length ? r.map((e) => ({ label: e?.label, key: e?.key, value: e?.value - })); - let n = ht(e); - return (Array.isArray(n) ? n.map(([e, t]) => ({ - label: e, - value: t - })) : []).slice(0, 160); + })) : []; } -function mn(e) { +function vn(e) { let t = `${String(G(e) || "").toLowerCase()} ${String(mt(e) || "").toLowerCase()}`; return t.trim() ? /ksampler|sampler|scheduler|cfg|steps|noise|seed/.test(t) ? "sampler" : /checkpoint|clip|vae|unet|lora|model|loader/.test(t) ? "model" : /text|prompt|token|encode|decoder|caption|florence/.test(t) ? "text" : /latent|image|mask|video|audio|preview|save|load|upscale/.test(t) ? "media" : /controlnet|conditioning|guidance|adapter|ipadapter/.test(t) ? "control" : /math|logic|switch|merge|concat|combine|route|branch|reroute/.test(t) ? "logic" : "generic" : "generic"; } -function hn(e) { +function yn(e) { if (!e || typeof e != "object") return e; let t = (Array.isArray(e.previewCandidates) ? e.previewCandidates : []).find((e) => String(e || "").trim()) || e.url || "", n = String(e.type || "").toLowerCase(), r = String(e.kind || "").toLowerCase(), i = String(e.filename || e.name || ""), a = r || (e.isVideo || n === "video" || /\.(mp4|mov|webm|mkv|avi)$/i.test(i) ? "video" : e.isAudio || n === "audio" || /\.(mp3|wav|flac|ogg|m4a|aac|opus|wma)$/i.test(i) ? "audio" : e.isModel3d || n === "model3d" ? "model3d" : ""); return { @@ -1636,7 +1704,7 @@ function hn(e) { } : null }; } -function gn(e) { +function bn(e) { return !e || typeof e != "object" ? "" : JSON.stringify({ url: String(e.url || ""), filename: String(e.filename || e.name || ""), @@ -1647,7 +1715,7 @@ function gn(e) { } //#endregion //#region ui/features/viewer/workflowSidebar/WorkflowSidebar.ts -var _n = 16, vn = 250, yn = class { +var xn = 16, Sn = 250, Cn = class { _hostEl; _onClose; _onOpenGraphMap; @@ -1666,7 +1734,7 @@ var _n = 16, vn = 250, yn = class { _nodesModeBtn; _graphModeBtn; constructor({ hostEl: e, onClose: t, onOpenGraphMap: n, onCloseGraphMap: r } = {}) { - this._hostEl = e, this._onClose = t ?? null, this._onOpenGraphMap = n ?? null, this._onCloseGraphMap = r ?? null, this._visible = !1, this._liveSyncHandle = null, this._liveSyncMode = "", this._lastLiveSyncAt = 0, this._resizeCleanup = null, this._nodesTab = new Qe(), this._graphMapPanel = new an(), this._activeMode = "nodes", this._asset = null, this._body = null, this._nodesModeBtn = null, this._graphModeBtn = null, this._el = this._build(); + this._hostEl = e, this._onClose = t ?? null, this._onOpenGraphMap = n ?? null, this._onCloseGraphMap = r ?? null, this._visible = !1, this._liveSyncHandle = null, this._liveSyncMode = "", this._lastLiveSyncAt = 0, this._resizeCleanup = null, this._nodesTab = new Qe(), this._graphMapPanel = new cn(), this._activeMode = "nodes", this._asset = null, this._body = null, this._nodesModeBtn = null, this._graphModeBtn = null, this._el = this._build(); } get el() { return this._el; @@ -1675,7 +1743,7 @@ var _n = 16, vn = 250, yn = class { return this._visible; } show() { - this._visible = !0, this._el.classList.add("open"), this.refresh(), this._lastLiveSyncAt = xn(this._el), this._startLiveSync(); + this._visible = !0, this._el.classList.add("open"), this.refresh(), this._lastLiveSyncAt = Tn(this._el), this._startLiveSync(); } hide() { this._visible = !1, this._el.classList.remove("open"), this._stopLiveSync(); @@ -1734,20 +1802,20 @@ var _n = 16, vn = 250, yn = class { } _startLiveSync() { if (this._liveSyncHandle != null) return; - let e = bn(this._el), t = (e) => { + let e = wn(this._el), t = (e) => { if (this._liveSyncHandle = null, this._liveSyncMode = "", !this._visible) return; - let t = Number.isFinite(Number(e)) ? Number(e) : xn(this._el); - t - this._lastLiveSyncAt >= vn && (this._lastLiveSyncAt = t, this.syncFromGraph()), this._startLiveSync(); + let t = Number.isFinite(Number(e)) ? Number(e) : Tn(this._el); + t - this._lastLiveSyncAt >= Sn && (this._lastLiveSyncAt = t, this.syncFromGraph()), this._startLiveSync(); }; if (typeof e.requestAnimationFrame == "function") { this._liveSyncMode = "raf", this._liveSyncHandle = e.requestAnimationFrame(t); return; } - this._liveSyncMode = "timeout", this._liveSyncHandle = e.setTimeout(t, _n); + this._liveSyncMode = "timeout", this._liveSyncHandle = e.setTimeout(t, xn); } _stopLiveSync() { if (this._liveSyncHandle == null) return; - let e = bn(this._el); + let e = wn(this._el); try { this._liveSyncMode === "raf" && typeof e.cancelAnimationFrame == "function" ? e.cancelAnimationFrame(this._liveSyncHandle) : typeof e.clearTimeout == "function" && e.clearTimeout(this._liveSyncHandle); } catch (e) { @@ -1783,11 +1851,11 @@ var _n = 16, vn = 250, yn = class { this._resizeCleanup = null; } }; -function bn(e) { +function wn(e) { return e?.ownerDocument?.defaultView || (typeof window < "u" ? window : globalThis); } -function xn(e) { - let t = bn(e), n = t?.performance?.now; +function Tn(e) { + let t = wn(e), n = t?.performance?.now; if (typeof n == "function") try { return Number(n.call(t.performance)) || Date.now(); } catch { @@ -1797,24 +1865,24 @@ function xn(e) { } //#endregion //#region ui/features/viewer/workflowSidebar/sidebarRunButton.ts -var X = Object.freeze({ +var Q = Object.freeze({ IDLE: "idle", RUNNING: "running", STOPPING: "stopping", ERROR: "error" -}), Sn = new Set([ +}), En = new Set([ "default", "auto", "latent2rgb", "taesd", "none" -]), Cn = "progress-update", wn = (e, t = "") => p(e, t, void 0); -function Tn() { +]), Dn = "progress-update", On = (e, t = "") => p(e, t, void 0); +function kn() { let e = document.createElement("div"); e.className = "mjr-mfv-run-controls"; let t = document.createElement("button"); t.type = "button", t.className = "mjr-icon-btn mjr-mfv-run-btn"; - let n = wn("tooltip.queuePrompt", "Queue Prompt (Run)"); + let n = On("tooltip.queuePrompt", "Queue Prompt (Run)"); t.title = n, t.setAttribute("aria-label", n); let r = document.createElement("i"); r.className = "pi pi-play", r.setAttribute("aria-hidden", "true"), t.appendChild(r); @@ -1822,15 +1890,15 @@ function Tn() { i.type = "button", i.className = "mjr-icon-btn mjr-mfv-stop-btn"; let a = document.createElement("i"); a.className = "pi pi-stop", a.setAttribute("aria-hidden", "true"), i.appendChild(a), e.appendChild(t), e.appendChild(i); - let s = X.IDLE, l = !1, u = !1, d = null; + let s = Q.IDLE, l = !1, u = !1, d = null; function f() { d != null && (clearTimeout(d), d = null); } function p(e, { canStop: n = !1 } = {}) { - s = e, t.classList.toggle("running", s === X.RUNNING), t.classList.toggle("stopping", s === X.STOPPING), t.classList.toggle("error", s === X.ERROR), t.disabled = s === X.RUNNING || s === X.STOPPING, i.disabled = !n || s === X.STOPPING, i.classList.toggle("active", n && s !== X.STOPPING), i.classList.toggle("stopping", s === X.STOPPING), s === X.RUNNING || s === X.STOPPING ? r.className = "pi pi-spin pi-spinner" : r.className = "pi pi-play"; + s = e, t.classList.toggle("running", s === Q.RUNNING), t.classList.toggle("stopping", s === Q.STOPPING), t.classList.toggle("error", s === Q.ERROR), t.disabled = s === Q.RUNNING || s === Q.STOPPING, i.disabled = !n || s === Q.STOPPING, i.classList.toggle("active", n && s !== Q.STOPPING), i.classList.toggle("stopping", s === Q.STOPPING), s === Q.RUNNING || s === Q.STOPPING ? r.className = "pi pi-spin pi-spinner" : r.className = "pi pi-play"; } function m() { - let e = wn("tooltip.queueStop", "Stop Generation"); + let e = On("tooltip.queueStop", "Stop Generation"); i.title = e, i.setAttribute("aria-label", e); } function h(e = I.getSnapshot(), { authoritative: t = !1 } = {}) { @@ -1838,7 +1906,7 @@ function Tn() { t && n === 0 && !r && (l = !1, u = !1); let c = l || u || i || n > 0; if ((i || o || n > 0) && (l = !1), s) { - u = !1, f(), p(X.ERROR, { canStop: !1 }); + u = !1, f(), p(Q.ERROR, { canStop: !1 }); return; } if (u) { @@ -1846,17 +1914,17 @@ function Tn() { u = !1, h(e); return; } - p(X.STOPPING, { canStop: !1 }); + p(Q.STOPPING, { canStop: !1 }); return; } if (l || i || o || n > 0) { - f(), p(X.RUNNING, { canStop: !0 }); + f(), p(Q.RUNNING, { canStop: !0 }); return; } - f(), p(X.IDLE, { canStop: !1 }); + f(), p(Q.IDLE, { canStop: !1 }); } function g() { - l = !1, u = !1, f(), p(X.ERROR, { canStop: !1 }), d = setTimeout(() => { + l = !1, u = !1, f(), p(Q.ERROR, { canStop: !1 }), d = setTimeout(() => { d = null, h(); }, 1500); } @@ -1864,17 +1932,17 @@ function Tn() { return { tracked: await o(c()) }; } async function v() { - if (!(s === X.RUNNING || s === X.STOPPING)) { + if (!(s === Q.RUNNING || s === Q.STOPPING)) { l = !0, u = !1, h(); try { - (await jn())?.tracked || (l = !1), h(); + (await Fn())?.tracked || (l = !1), h(); } catch (e) { console.error?.("[MFV Run]", e), g(); } } } async function y() { - if (s === X.RUNNING) { + if (s === Q.RUNNING) { u = !0, h(); try { (await _())?.tracked || (u = !1, l = !1), h(); @@ -1887,21 +1955,21 @@ function Tn() { let b = (e) => { h(e?.detail || I.getSnapshot(), { authoritative: !0 }); }; - return I.addEventListener(Cn, b), se({ timeoutMs: 4e3 }).catch((e) => { + return I.addEventListener(Dn, b), se({ timeoutMs: 4e3 }).catch((e) => { console.debug?.(e); }), h(), { el: e, dispose() { - f(), t.removeEventListener("click", v), i.removeEventListener("click", y), I.removeEventListener(Cn, b); + f(), t.removeEventListener("click", v), i.removeEventListener("click", y), I.removeEventListener(Dn, b); } }; } -function En(e = _.MFV_PREVIEW_METHOD) { +function An(e = _.MFV_PREVIEW_METHOD) { let t = String(e || "").trim().toLowerCase(); - return Sn.has(t) ? t : _.MFV_PREVIEW_METHOD || "auto"; + return En.has(t) ? t : _.MFV_PREVIEW_METHOD || "auto"; } -function Dn(e, t = _.MFV_PREVIEW_METHOD) { - let n = En(t), r = { +function jn(e, t = _.MFV_PREVIEW_METHOD) { + let n = An(t), r = { ...e?.extra_data || {}, extra_pnginfo: { ...e?.extra_data?.extra_pnginfo || {} } }; @@ -1910,14 +1978,14 @@ function Dn(e, t = _.MFV_PREVIEW_METHOD) { extra_data: r }; } -function On(e, { previewMethod: t = _.MFV_PREVIEW_METHOD, clientId: n = null } = {}) { - let r = Dn(e, t), i = { +function Mn(e, { previewMethod: t = _.MFV_PREVIEW_METHOD, clientId: n = null } = {}) { + let r = jn(e, t), i = { prompt: r?.output, extra_data: r?.extra_data || {} }, a = String(n || "").trim(); return a && (i.client_id = a), i; } -function kn(e) { +function Nn(e) { let t = e?.constructor; return [ e?.type, @@ -1926,32 +1994,32 @@ function kn(e) { t?.type ].some((e) => /Api$/i.test(String(e || "").trim())); } -function An(e) { +function Pn(e) { let t = !1; return S(e, ({ node: e }) => { - t ||= kn(e); + t ||= Nn(e); }), t; } -async function jn() { +async function Fn() { let e = c(); if (!e) throw Error("ComfyUI app not available"); return { tracked: await d({ app: e, - forceNativeQueue: An(y(e)), + forceNativeQueue: Pn(y(e)), resolvePromptData(e) { return typeof e?.graphToPrompt == "function" ? e.graphToPrompt() : null; }, enrichPromptData(e) { - return Dn(e); + return jn(e); }, buildPromptRequestBody(e, t) { - return On(e, { clientId: t.clientId }); + return Mn(e, { clientId: t.clientId }); } }) }; } //#endregion //#region ui/features/viewer/floatingViewerUi.ts -function Mn(e) { +function In(e) { let t = e?.models; if (!t || typeof t != "object") return ""; let n = [ @@ -1969,11 +2037,11 @@ function Mn(e) { } return i.join(" | "); } -function Nn(e) { +function Ln(e) { let t = fe(e); return t.workflowLabel ? t.workflowBadge ? `${t.workflowLabel} • ${t.workflowBadge}` : t.workflowLabel : ""; } -function Pn(e, t, n, r) { +function Rn(e, t, n, r) { let i = document.createElement("div"); i.className = "mjr-mfv-idrop"; let a = document.createElement("button"); @@ -2021,21 +2089,21 @@ function Pn(e, t, n, r) { } }; } -var Fn = { +var zn = { rgb: "#e0e0e0", r: "#ff5555", g: "#44dd66", b: "#5599ff", a: "#ffffff", l: "#bbbbbb" -}, In = { +}, Bn = { rgb: "RGB", r: "R", g: "G", b: "B", a: "A", l: "L" -}, Ln = { +}, Vn = { rgb: "500", r: "700", g: "700", @@ -2043,9 +2111,9 @@ var Fn = { a: "700", l: "400" }; -function Rn(e) { +function Hn(e) { let t = document.createElement("div"); - return t.className = "mjr-mfv", t.setAttribute("role", "dialog"), t.setAttribute("aria-modal", "false"), t.setAttribute("aria-hidden", "true"), e.element = t, t.appendChild(e._buildHeader()), t.setAttribute("aria-labelledby", e._titleId), t.appendChild(e._buildToolbar()), t.appendChild(P(e)), e._contentWrapper = document.createElement("div"), e._contentWrapper.className = "mjr-mfv-content-wrapper", e._applySidebarPosition(), e._contentEl = document.createElement("div"), e._contentEl.className = "mjr-mfv-content", e._contentWrapper.appendChild(e._contentEl), e._overlayCanvas = document.createElement("canvas"), e._overlayCanvas.className = "mjr-mfv-overlay-canvas", e._contentEl.appendChild(e._overlayCanvas), e._contentEl.appendChild(F(e)), e._genSidebarEl = document.createElement("aside"), e._genSidebarEl.className = "mjr-mfv-gen-sidebar", e._genSidebarEl.setAttribute("aria-label", "Generation info"), e._genSidebarEl.setAttribute("hidden", ""), e._sidebar = new yn({ + return t.className = "mjr-mfv", t.setAttribute("role", "dialog"), t.setAttribute("aria-modal", "false"), t.setAttribute("aria-hidden", "true"), e.element = t, t.appendChild(e._buildHeader()), t.setAttribute("aria-labelledby", e._titleId), t.appendChild(e._buildToolbar()), t.appendChild(P(e)), e._contentWrapper = document.createElement("div"), e._contentWrapper.className = "mjr-mfv-content-wrapper", e._applySidebarPosition(), e._contentEl = document.createElement("div"), e._contentEl.className = "mjr-mfv-content", e._contentWrapper.appendChild(e._contentEl), e._overlayCanvas = document.createElement("canvas"), e._overlayCanvas.className = "mjr-mfv-overlay-canvas", e._contentEl.appendChild(e._overlayCanvas), e._contentEl.appendChild(F(e)), e._genSidebarEl = document.createElement("aside"), e._genSidebarEl.className = "mjr-mfv-gen-sidebar", e._genSidebarEl.setAttribute("aria-label", "Generation info"), e._genSidebarEl.setAttribute("hidden", ""), e._sidebar = new Cn({ hostEl: t, onClose: () => e._updateSettingsBtnState(!1), onOpenGraphMap: () => e.setMode?.(z.GRAPH), @@ -2056,7 +2124,7 @@ function Rn(e) { t?.detail?.key === "viewer.mfvSidebarPosition" && e._applySidebarPosition(); }, window.addEventListener("mjr-settings-changed", e._onSidebarPosChanged), e._refresh(), t; } -function zn(e) { +function Un(e) { let t = document.createElement("div"); t.className = "mjr-mfv-header"; let n = document.createElement("span"); @@ -2070,7 +2138,7 @@ function zn(e) { let o = document.createElement("i"); return o.className = "pi pi-times", o.setAttribute("aria-hidden", "true"), a.appendChild(o), t.appendChild(n), t.appendChild(a), t; } -function Bn(e) { +function Wn(e) { let t = (e, { min: t, max: n, step: r, value: i } = {}) => { let a = document.createElement("div"); a.className = "mjr-mfv-toolbar-range"; @@ -2084,7 +2152,7 @@ function Bn(e) { }; }, n = document.createElement("div"); n.className = "mjr-mfv-toolbar"; - let r = Pn("", p("viewer.mode", "Viewer mode"), [ + let r = Rn("", p("viewer.mode", "Viewer mode"), [ { value: z.SIMPLE, html: `${p("viewer.mode.simple", "Simple")}` @@ -2199,7 +2267,7 @@ function Bn(e) { let x = (e) => { if (!e || e === "rgb") y.replaceChildren(b); else { - let t = Fn[e] || "#e0e0e0", n = Ln[e] || "500", r = In[e] || e.toUpperCase(), i = document.createElement("span"); + let t = zn[e] || "#e0e0e0", n = Vn[e] || "500", r = Bn[e] || e.toUpperCase(), i = document.createElement("span"); i.className = "mjr-mfv-ch-label", i.style.color = t, i.style.fontWeight = n, i.textContent = r, y.replaceChildren(i); } }, S = document.createElement("div"); @@ -2375,7 +2443,7 @@ function Bn(e) { let ce = p("tooltip.nodeParams", "Node Parameters"); e._settingsBtn.title = ce, e._settingsBtn.setAttribute("aria-label", ce), e._settingsBtn.setAttribute("aria-pressed", "false"); let le = document.createElement("i"); - le.className = "pi pi-sliders-h", le.setAttribute("aria-hidden", "true"), e._settingsBtn.appendChild(le), n.appendChild(e._settingsBtn), e._runHandle = Tn(), n.appendChild(e._runHandle.el), e._majoorSettingsBtn = document.createElement("button"), e._majoorSettingsBtn.type = "button", e._majoorSettingsBtn.className = "mjr-icon-btn mjr-mfv-majoor-settings-btn"; + le.className = "pi pi-sliders-h", le.setAttribute("aria-hidden", "true"), e._settingsBtn.appendChild(le), n.appendChild(e._settingsBtn), e._runHandle = kn(), n.appendChild(e._runHandle.el), e._majoorSettingsBtn = document.createElement("button"), e._majoorSettingsBtn.type = "button", e._majoorSettingsBtn.className = "mjr-icon-btn mjr-mfv-majoor-settings-btn"; let ue = p("tooltip.openMajoorSettings", "Open Majoor Assets Manager settings"); e._majoorSettingsBtn.title = ue, e._majoorSettingsBtn.setAttribute("aria-label", ue); let R = document.createElement("i"); @@ -2384,7 +2452,7 @@ function Bn(e) { e._chPopover?.classList?.contains("is-open") && !e._chBtn?.contains?.(n) && !e._chPopover.contains(n) && e._closeChPopover?.(), e._guidePopover?.classList?.contains("is-open") && !e._guideBtn?.contains?.(n) && !e._guidePopover.contains(n) && e._closeGuidePopover?.(), e._pinPopover?.classList?.contains("is-open") && !e._pinBtn?.contains?.(n) && !e._pinPopover.contains(n) && e._closePinPopover?.(), e._formatPopover?.classList?.contains("is-open") && !e._formatToggle?.contains?.(n) && !e._formatPopover.contains(n) && e._closeFormatPopover?.(), n?.closest?.(".mjr-mfv-idrop") || e.element?.querySelectorAll?.(".mjr-mfv-idrop-menu.is-open").forEach((e) => e.classList.remove("is-open")); }, e._bindDocumentUiHandlers(), n; } -function Vn(e) { +function Gn(e) { try { e._btnAC?.abort(); } catch (e) { @@ -2433,15 +2501,15 @@ function Vn(e) { e._overlayMaskOpacity = Math.round(Math.max(0, Math.min(.9, Number.isFinite(t) ? t : .65)) * 100) / 100, e._maskOpacityCtl.out.textContent = e._overlayMaskOpacity.toFixed(2), e._redrawOverlayGuides?.(); }, { signal: t }); } -function Hn(e, t) { +function Kn(e, t) { e._settingsBtn && (e._settingsBtn.classList.toggle("active", !!t), e._settingsBtn.setAttribute("aria-pressed", String(!!t))); } -function Un(e) { +function qn(e) { if (!e._contentWrapper) return; let t = _.MFV_SIDEBAR_POSITION || "right"; e._contentWrapper.setAttribute("data-sidebar-pos", t), e._sidebar?.el && e._contentEl && (t === "left" ? e._contentWrapper.insertBefore(e._sidebar.el, e._contentEl) : e._contentWrapper.appendChild(e._sidebar.el)); } -function Wn(e) { +function Jn(e) { if (!e._handleDocClick) return; let t = e.element?.ownerDocument || document; if (e._docClickHost !== t) { @@ -2454,7 +2522,7 @@ function Wn(e) { e._docAC = new AbortController(), t.addEventListener("click", e._handleDocClick, { signal: e._docAC.signal }), e._docClickHost = t; } } -function Gn(e) { +function Yn(e) { try { e._docAC?.abort(); } catch (e) { @@ -2462,18 +2530,18 @@ function Gn(e) { } e._docAC = new AbortController(), e._docClickHost = null; } -function Kn(e) { +function Xn(e) { if (!e._genBtn) return; let t = !!e._genSidebarEnabled; e._genBtn.classList.toggle("is-on", t), e._genBtn.classList.toggle("is-open", t); let n = t ? "Gen Info sidebar: ON" : "Gen Info sidebar: OFF"; e._genBtn.title = n, e._genBtn.setAttribute("aria-label", n), e._genBtn.setAttribute("aria-pressed", String(t)), e._genBtn.removeAttribute("aria-expanded"), e._genBtn.removeAttribute("aria-haspopup"), e._genBtn.removeAttribute("aria-controls"); } -function qn(e) { +function Zn(e) { let t = Number(e); return !Number.isFinite(t) || t <= 0 ? "" : t >= 60 ? `${(t / 60).toFixed(1)}m` : `${t.toFixed(1)}s`; } -function Jn(e) { +function Qn(e) { let t = String(e || "").trim().toLowerCase(); if (!t) return 0; if (t.endsWith("m")) { @@ -2487,7 +2555,7 @@ function Jn(e) { let n = Number.parseFloat(t); return Number.isFinite(n) ? n : 0; } -function Yn(e, t) { +function $n(e, t) { if (!t) return {}; try { let e = t.geninfo ? { geninfo: t.geninfo } : t.metadata || t.metadata_raw || t, n = ue(e) || null, r = { @@ -2503,10 +2571,10 @@ function Yn(e, t) { }; if (n && typeof n == "object") { n.prompt && (r.prompt = R(String(n.prompt))), n.seed != null && (r.seed = String(n.seed)), n.model && (r.model = Array.isArray(n.model) ? n.model.join(", ") : String(n.model)); - let i = Nn(n), a = Mn(n); + let i = Ln(n), a = In(n); a && (r.model = a), i && (r.model = [i, r.model].filter(Boolean).join(" | ")), Array.isArray(n.loras) && (r.lora = n.loras.map((e) => typeof e == "string" ? e : e?.name || e?.lora_name || e?.model_name || "").filter(Boolean).join(", ")), n.sampler && (r.sampler = String(n.sampler)), n.scheduler && (r.scheduler = String(n.scheduler)), n.cfg != null && (r.cfg = String(n.cfg)), n.steps != null && (r.step = String(n.steps)), !r.prompt && e?.prompt && (r.prompt = R(String(e.prompt || ""))); let o = t.generation_time_ms ?? t.metadata_raw?.generation_time_ms ?? e?.generation_time_ms ?? e?.geninfo?.generation_time_ms ?? 0; - return o && Number.isFinite(Number(o)) && o > 0 && o < 864e5 && (r.genTime = qn(Number(o) / 1e3)), r; + return o && Number.isFinite(Number(o)) && o > 0 && o < 864e5 && (r.genTime = Zn(Number(o) / 1e3)), r; } } catch (e) { console.debug?.("[MFV] geninfo normalize failed", e); @@ -2522,9 +2590,9 @@ function Yn(e, t) { step: n?.steps == null ? "" : String(n.steps), genTime: "" }, i = t.generation_time_ms ?? t.metadata_raw?.generation_time_ms ?? n?.generation_time_ms ?? 0; - return i && Number.isFinite(Number(i)) && i > 0 && i < 864e5 && (r.genTime = qn(Number(i) / 1e3)), r; + return i && Number.isFinite(Number(i)) && i > 0 && i < 864e5 && (r.genTime = Zn(Number(i) / 1e3)), r; } -function Xn(e, t) { +function er(e, t) { let n = e._getGenFields(t); if (!n) return null; let r = document.createDocumentFragment(); @@ -2549,7 +2617,7 @@ function Xn(e, t) { let s = document.createElement("strong"); if (s.textContent = `${a}: `, o.appendChild(s), t === "prompt") o.appendChild(document.createTextNode(i)); else if (t === "genTime") { - let e = Jn(i), t = "#4CAF50"; + let e = Qn(i), t = "#4CAF50"; e >= 60 ? t = "#FF9800" : e >= 30 ? t = "#FFC107" : e >= 10 && (t = "#8BC34A"); let n = document.createElement("span"); n.style.color = t, n.style.fontWeight = "600", n.textContent = i, o.appendChild(n); @@ -2560,14 +2628,14 @@ function Xn(e, t) { } //#endregion //#region ui/features/viewer/floatingViewerMode.ts -function Zn(e) { +function tr(e) { try { e._controller?.onModeChanged?.(e._mode); } catch (e) { console.debug?.(e); } } -function Qn(e) { +function nr(e) { let t = [ z.SIMPLE, z.AB, @@ -2577,13 +2645,13 @@ function Qn(e) { ]; e._mode = t[(t.indexOf(e._mode) + 1) % t.length], e._updateModeBtnUI(), e._refresh(), e._notifyModeChanged(); } -function $n(e, t) { +function rr(e, t) { Object.values(z).includes(t) && (e._mode = t, e._updateModeBtnUI(), e._refresh(), e._notifyModeChanged()); } -function er(e) { +function ir(e) { return e._pinnedSlots; } -function tr(e) { +function ar(e) { if (e._pinBtns) { for (let t of [ "A", @@ -2599,7 +2667,7 @@ function tr(e) { e._pinBtn?.classList.toggle("is-on", (e._pinnedSlots?.size ?? 0) > 0); } } -function nr(e) { +function or(e) { if (!e._modeBtn) return; let { icon: t = "pi-image", label: n = "" } = { [z.SIMPLE]: { @@ -2625,7 +2693,7 @@ function nr(e) { }[e._mode] || {}, r = N(n, "C"), i = document.createElement("i"); i.className = `pi ${t}`, i.setAttribute("aria-hidden", "true"), e._modeBtn.replaceChildren(i), e._modeBtn.title = r, e._modeBtn.setAttribute("aria-label", r), e._modeBtn.removeAttribute("aria-pressed"), e._modeBtn.classList.toggle("is-on", e._mode !== z.SIMPLE), e._modeDrop?.selectItem?.(e._mode); } -function rr(e, t) { +function sr(e, t) { if (!e._liveBtn) return; let n = !!t; e._liveBtn.classList.toggle("mjr-live-active", n); @@ -2634,7 +2702,7 @@ function rr(e, t) { let i = document.createElement("i"); i.className = n ? "pi pi-circle-fill" : "pi pi-circle", i.setAttribute("aria-hidden", "true"), e._liveBtn.replaceChildren(i), e._liveBtn.title = r; } -function ir(e, t) { +function cr(e, t) { if (e._previewActive = !!t, !e._previewBtn) return; e._previewBtn.classList.toggle("mjr-preview-active", e._previewActive); let n = N(e._previewActive ? p("tooltip.previewStreamOn", "KSampler Preview: ON - streams sampler denoising frames during execution") : p("tooltip.previewStreamOff", "KSampler Preview: OFF - click to stream sampler denoising frames"), "K"); @@ -2642,7 +2710,7 @@ function ir(e, t) { let r = document.createElement("i"); r.className = e._previewActive ? "pi pi-eye" : "pi pi-eye-slash", r.setAttribute("aria-hidden", "true"), e._previewBtn.replaceChildren(r), e._previewBtn.title = n, e._previewActive || e._revokePreviewBlob(); } -function ar(e, t, n = {}) { +function lr(e, t, n = {}) { if (!t || !(t instanceof Blob)) return; e._revokePreviewBlob(); let r = URL.createObjectURL(t); @@ -2668,7 +2736,7 @@ function ar(e, t, n = {}) { } else e._mediaA = i, e._resetMfvZoom(), e._mode !== z.SIMPLE && (e._mode = z.SIMPLE, e._updateModeBtnUI()); ++e._refreshGen, e._refresh(); } -function or(e) { +function ur(e) { if (e._previewBlobUrl) { try { URL.revokeObjectURL(e._previewBlobUrl); @@ -2676,7 +2744,7 @@ function or(e) { e._previewBlobUrl = null; } } -function sr(e, t) { +function dr(e, t) { if (e._nodeStreamActive = !!t, e._nodeStreamActive || e.setNodeStreamSelection?.(null), !e._nodeStreamBtn) return; e._nodeStreamBtn.classList.toggle("mjr-nodestream-active", e._nodeStreamActive); let n = N(e._nodeStreamActive ? p("tooltip.nodeStreamOn", "Node Stream: ON - follows the selected node preview when frontend media exists") : p("tooltip.nodeStreamOff", "Node Stream: OFF - click to follow selected node previews, including ImageOps live canvases"), "N"); @@ -2686,8 +2754,8 @@ function sr(e, t) { } //#endregion //#region ui/features/viewer/floatingViewerPopout.ts -var cr = /* @__PURE__ */ "--border-color.--border-default.--button-hover-surface.--button-surface.--comfy-accent.--comfy-font.--comfy-input-bg.--comfy-menu-bg.--comfy-menu-secondary-bg.--comfy-status-error.--comfy-status-success.--comfy-status-warning.--content-bg.--content-fg.--descrip-text.--destructive-background.--font-inter.--input-text.--interface-menu-surface.--interface-panel-hover-surface.--interface-panel-selected-surface.--interface-panel-surface.--modal-card-background.--muted-foreground.--primary-background.--primary-background-hover.--radius-lg.--radius-md.--radius-sm.--success-background.--warning-background".split("."); -function lr() { +var fr = /* @__PURE__ */ "--border-color.--border-default.--button-hover-surface.--button-surface.--comfy-accent.--comfy-font.--comfy-input-bg.--comfy-menu-bg.--comfy-menu-secondary-bg.--comfy-status-error.--comfy-status-success.--comfy-status-warning.--content-bg.--content-fg.--descrip-text.--destructive-background.--font-inter.--input-text.--interface-menu-surface.--interface-panel-hover-surface.--interface-panel-selected-surface.--interface-panel-surface.--modal-card-background.--muted-foreground.--primary-background.--primary-background-hover.--radius-lg.--radius-md.--radius-sm.--success-background.--warning-background".split("."); +function pr() { try { let e = typeof window < "u" ? window : globalThis, t = e?.process?.versions?.electron; if (typeof t == "string" && t.trim() || e?.electron || e?.ipcRenderer || e?.electronAPI) return !0; @@ -2698,7 +2766,7 @@ function lr() { } return !1; } -function Z(e, t = null, n = "info") { +function $(e, t = null, n = "info") { let r = { stage: String(e || "unknown"), detail: t, @@ -2716,10 +2784,10 @@ function Z(e, t = null, n = "info") { console.debug?.(e); } } -function ur(e, ...t) { +function mr(e, ...t) { return Array.from(new Set([String(e || ""), ...t].join(" ").split(/\s+/).filter(Boolean))).join(" "); } -function dr(e, t) { +function hr(e, t) { if (!(!e || !t)) for (let n of Array.from(e.attributes || [])) { let e = String(n?.name || ""); if (!(!e || e === "class" || e === "style")) try { @@ -2729,7 +2797,7 @@ function dr(e, t) { } } } -function fr(e, t) { +function gr(e, t) { if (!e || !t?.style) return; let n = typeof window < "u" && window?.getComputedStyle || globalThis?.getComputedStyle; if (typeof n != "function") return; @@ -2740,7 +2808,7 @@ function fr(e, t) { console.debug?.(e); } if (r) { - for (let e of cr) try { + for (let e of fr) try { let n = String(r.getPropertyValue?.(e) || "").trim(); n && t.style.setProperty(e, n); } catch (e) { @@ -2754,12 +2822,12 @@ function fr(e, t) { } } } -function pr(e) { +function _r(e) { if (!e?.documentElement || !e?.body || !document?.documentElement) return; let t = document.documentElement, n = document.body, r = e.documentElement, i = e.body; - r.className = ur(t.className, "mjr-mfv-popout-document"), i.className = ur(n?.className, "mjr-mfv-popout-body"), dr(t, r), dr(n, i), fr(t, r), fr(n, i), t?.lang && (r.lang = t.lang), t?.dir && (r.dir = t.dir); + r.className = mr(t.className, "mjr-mfv-popout-document"), i.className = mr(n?.className, "mjr-mfv-popout-body"), hr(t, r), hr(n, i), gr(t, r), gr(n, i), t?.lang && (r.lang = t.lang), t?.dir && (r.dir = t.dir); } -function mr(e) { +function vr(e) { if (!e?.body) return null; try { (e.getElementById?.("mjr-mfv-popout-root"))?.remove?.(); @@ -2769,10 +2837,10 @@ function mr(e) { let t = e.createElement("div"); return t.id = "mjr-mfv-popout-root", t.className = "mjr-mfv-popout-root", e.body.appendChild(t), t; } -function Q(e) { +function yr(e) { e._resetGenDropdownForCurrentDocument(), e._rebindControlHandlers(), e._bindPanelInteractions(), e._bindDocumentUiHandlers(), e._unbindLayoutObserver?.(), e._bindLayoutObserver?.(), e._refresh?.(), e._updatePopoutBtnUI(); } -function hr(e, t) { +function br(e, t) { if (!e.element) return; let n = !!t; if (e._desktopExpanded === n) return; @@ -2782,29 +2850,29 @@ function hr(e, t) { parent: r.parentNode || null, nextSibling: r.nextSibling || null, styleAttr: r.getAttribute("style") - }, r.parentNode !== document.body && document.body.appendChild(r), r.classList.add("mjr-mfv--desktop-expanded", "is-visible"), r.setAttribute("aria-hidden", "false"), r.style.position = "fixed", r.style.top = "12px", r.style.left = "12px", r.style.right = "12px", r.style.bottom = "12px", r.style.width = "auto", r.style.height = "auto", r.style.maxWidth = "none", r.style.maxHeight = "none", r.style.minWidth = "320px", r.style.minHeight = "240px", r.style.resize = "none", r.style.margin = "0", r.style.zIndex = "2147483000", e._desktopExpanded = !0, e.isVisible = !0, Q(e), Z("electron-in-app-expanded", { isVisible: e.isVisible }); + }, r.parentNode !== document.body && document.body.appendChild(r), r.classList.add("mjr-mfv--desktop-expanded", "is-visible"), r.setAttribute("aria-hidden", "false"), r.style.position = "fixed", r.style.top = "12px", r.style.left = "12px", r.style.right = "12px", r.style.bottom = "12px", r.style.width = "auto", r.style.height = "auto", r.style.maxWidth = "none", r.style.maxHeight = "none", r.style.minWidth = "320px", r.style.minHeight = "240px", r.style.resize = "none", r.style.margin = "0", r.style.zIndex = "2147483000", e._desktopExpanded = !0, e.isVisible = !0, yr(e), $("electron-in-app-expanded", { isVisible: e.isVisible }); return; } let i = e._desktopExpandRestore; - e._desktopExpanded = !1, r.classList.remove("mjr-mfv--desktop-expanded"), i?.styleAttr == null || i.styleAttr === "" ? r.removeAttribute("style") : r.setAttribute("style", i.styleAttr), i?.parent && i.parent.isConnected && (i.nextSibling && i.nextSibling.parentNode === i.parent ? i.parent.insertBefore(r, i.nextSibling) : i.parent.appendChild(r)), e._desktopExpandRestore = null, Q(e), Z("electron-in-app-restored", null); + e._desktopExpanded = !1, r.classList.remove("mjr-mfv--desktop-expanded"), i?.styleAttr == null || i.styleAttr === "" ? r.removeAttribute("style") : r.setAttribute("style", i.styleAttr), i?.parent && i.parent.isConnected && (i.nextSibling && i.nextSibling.parentNode === i.parent ? i.parent.insertBefore(r, i.nextSibling) : i.parent.appendChild(r)), e._desktopExpandRestore = null, yr(e), $("electron-in-app-restored", null); } -function gr(t, n) { - t._desktopPopoutUnsupported = !0, Z("electron-in-app-fallback", { message: n?.message || String(n || "unknown error") }, "warn"), t._setDesktopExpanded(!0); +function xr(t, n) { + t._desktopPopoutUnsupported = !0, $("electron-in-app-fallback", { message: n?.message || String(n || "unknown error") }, "warn"), t._setDesktopExpanded(!0); try { e(p("toast.popoutElectronInAppFallback", "Desktop PiP is unavailable here. Viewer expanded inside the app instead."), "warning", 4500); } catch (e) { console.debug?.(e); } } -function _r(e, t, n, r, i) { - return Z("electron-popup-fallback-attempt", { reason: i?.message || String(i || "unknown") }, "warn"), e._fallbackPopout(t, n, r), e._popoutWindow ? (e._desktopPopoutUnsupported = !1, Z("electron-popup-fallback-opened", null), !0) : !1; +function Sr(e, t, n, r, i) { + return $("electron-popup-fallback-attempt", { reason: i?.message || String(i || "unknown") }, "warn"), e._fallbackPopout(t, n, r), e._popoutWindow ? (e._desktopPopoutUnsupported = !1, $("electron-popup-fallback-opened", null), !0) : !1; } -function vr(e) { +function Cr(e) { if (e._isPopped || !e.element) return; let t = e.element; e._stopEdgeResize(); - let n = lr(), r = typeof window < "u" && "documentPictureInPicture" in window, i = String(window?.navigator?.userAgent || globalThis?.navigator?.userAgent || ""), a = Math.max(t.offsetWidth || 520, 400), o = Math.max(t.offsetHeight || 420, 300); - if (Z("start", { + let n = pr(), r = typeof window < "u" && "documentPictureInPicture" in window, i = String(window?.navigator?.userAgent || globalThis?.navigator?.userAgent || ""), a = Math.max(t.offsetWidth || 520, 400), o = Math.max(t.offsetHeight || 420, 300); + if ($("start", { isElectronHost: n, hasDocumentPiP: r, userAgent: i, @@ -2812,22 +2880,22 @@ function vr(e) { height: o, desktopPopoutUnsupported: e._desktopPopoutUnsupported }), n && e._desktopPopoutUnsupported) { - Z("electron-in-app-fallback-reuse", null), e._setDesktopExpanded(!0); + $("electron-in-app-fallback-reuse", null), e._setDesktopExpanded(!0); return; } - if (!(n && (Z("electron-popup-request", { + if (!(n && ($("electron-popup-request", { width: a, height: o }), e._tryElectronPopupFallback(t, a, o, /* @__PURE__ */ Error("Desktop popup requested"))))) { if (n && "documentPictureInPicture" in window) { - Z("electron-pip-request", { + $("electron-pip-request", { width: a, height: o }), window.documentPictureInPicture.requestWindow({ width: a, height: o }).then((n) => { - Z("electron-pip-opened", { hasDocument: !!n?.document }), e._popoutWindow = n, e._isPopped = !0, e._popoutRestoreGuard = !1; + $("electron-pip-opened", { hasDocument: !!n?.document }), e._popoutWindow = n, e._isPopped = !0, e._popoutRestoreGuard = !1; try { e._popoutAC?.abort(); } catch (e) { @@ -2838,16 +2906,16 @@ function vr(e) { e._popoutCloseHandler = i; let a = n.document; a.title = "Majoor Viewer", e._installPopoutStyles(a); - let o = mr(a); + let o = vr(a); if (!o) { e._activateDesktopExpandedFallback(/* @__PURE__ */ Error("Popup root creation failed")); return; } try { let e = typeof a.adoptNode == "function" ? a.adoptNode(t) : t; - o.appendChild(e), Z("electron-pip-adopted", { usedAdoptNode: typeof a.adoptNode == "function" }); + o.appendChild(e), $("electron-pip-adopted", { usedAdoptNode: typeof a.adoptNode == "function" }); } catch (t) { - Z("electron-pip-adopt-failed", { message: t?.message || String(t) }, "warn"), console.warn("[MFV] PiP adoptNode failed", t), e._isPopped = !1, e._popoutWindow = null; + $("electron-pip-adopt-failed", { message: t?.message || String(t) }, "warn"), console.warn("[MFV] PiP adoptNode failed", t), e._isPopped = !1, e._popoutWindow = null; try { n.close(); } catch (e) { @@ -2856,36 +2924,36 @@ function vr(e) { e._activateDesktopExpandedFallback(t); return; } - t.classList.add("is-visible"), e.isVisible = !0, Q(e), Z("electron-pip-ready", { isPopped: e._isPopped }), n.addEventListener("pagehide", i, { signal: r }), e._startPopoutCloseWatch(), e._popoutKeydownHandler = (t) => { + t.classList.add("is-visible"), e.isVisible = !0, yr(e), $("electron-pip-ready", { isPopped: e._isPopped }), n.addEventListener("pagehide", i, { signal: r }), e._startPopoutCloseWatch(), e._popoutKeydownHandler = (t) => { let n = String(t?.target?.tagName || "").toLowerCase(); t?.defaultPrevented || t?.target?.isContentEditable || n === "input" || n === "textarea" || n === "select" || e._forwardKeydownToController(t); }, n.addEventListener("keydown", e._popoutKeydownHandler, { signal: r }); }).catch((t) => { - Z("electron-pip-request-failed", { message: t?.message || String(t) }, "warn"), e._activateDesktopExpandedFallback(t); + $("electron-pip-request-failed", { message: t?.message || String(t) }, "warn"), e._activateDesktopExpandedFallback(t); }); return; } if (n) { - Z("electron-no-pip-api", { hasDocumentPiP: r }), e._activateDesktopExpandedFallback(/* @__PURE__ */ Error("Document Picture-in-Picture unavailable after popup failure")); + $("electron-no-pip-api", { hasDocumentPiP: r }), e._activateDesktopExpandedFallback(/* @__PURE__ */ Error("Document Picture-in-Picture unavailable after popup failure")); return; } - Z("browser-fallback-popup", { + $("browser-fallback-popup", { width: a, height: o }), e._fallbackPopout(t, a, o); } } -function yr(e, t, n, r) { - Z("browser-popup-open", { +function wr(e, t, n, r) { + $("browser-popup-open", { width: n, height: r }); let i = `width=${n},height=${r},left=${(window.screenX || window.screenLeft) + Math.round((window.outerWidth - n) / 2)},top=${(window.screenY || window.screenTop) + Math.round((window.outerHeight - r) / 2)},resizable=yes,scrollbars=no,toolbar=no,menubar=no,location=no,status=no`, a = window.open("about:blank", "_mjr_viewer", i); if (!a) { - Z("browser-popup-blocked", null, "warn"), console.warn("[MFV] Pop-out blocked - allow popups for this site."); + $("browser-popup-blocked", null, "warn"), console.warn("[MFV] Pop-out blocked - allow popups for this site."); return; } - Z("browser-popup-opened", { hasDocument: !!a?.document }), e._popoutWindow = a, e._isPopped = !0, e._popoutRestoreGuard = !1; + $("browser-popup-opened", { hasDocument: !!a?.document }), e._popoutWindow = a, e._isPopped = !0, e._popoutRestoreGuard = !1; try { e._popoutAC?.abort(); } catch (e) { @@ -2903,7 +2971,7 @@ function yr(e, t, n, r) { } if (!n) return; n.title = "Majoor Viewer", e._installPopoutStyles(n); - let r = mr(n); + let r = vr(n); if (r) { try { r.appendChild(n.adoptNode(t)); @@ -2911,7 +2979,7 @@ function yr(e, t, n, r) { console.warn("[MFV] adoptNode failed", e); return; } - t.classList.add("is-visible"), e.isVisible = !0, Q(e); + t.classList.add("is-visible"), e.isVisible = !0, yr(e); } }; try { @@ -2929,7 +2997,7 @@ function yr(e, t, n, r) { t?.defaultPrevented || t?.target?.isContentEditable || n === "input" || n === "textarea" || n === "select" || e._forwardKeydownToController(t); }, a.addEventListener("keydown", e._popoutKeydownHandler, { signal: o }); } -function br(e) { +function Tr(e) { if (e._popoutCloseTimer != null) { try { window.clearInterval(e._popoutCloseTimer); @@ -2939,7 +3007,7 @@ function br(e) { e._popoutCloseTimer = null; } } -function xr(e) { +function Er(e) { e._clearPopoutCloseWatch(), e._popoutCloseTimer = window.setInterval(() => { if (!e._isPopped) { e._clearPopoutCloseWatch(); @@ -2949,7 +3017,7 @@ function xr(e) { (!t || t.closed) && (e._clearPopoutCloseWatch(), e._schedulePopInFromPopupClose()); }, 250); } -function Sr(e) { +function Dr(e) { !e._isPopped || e._popoutRestoreGuard || (e._popoutRestoreGuard = !0, window.setTimeout(() => { try { e.popIn({ closePopupWindow: !1 }); @@ -2958,14 +3026,14 @@ function Sr(e) { } }, 0)); } -function Cr(e, t) { +function Or(e, t) { if (!t?.head) return; try { for (let e of t.head.querySelectorAll("[data-mjr-popout-cloned-style='1']")) e.remove(); } catch (e) { console.debug?.(e); } - pr(t); + _r(t); try { let e = document.documentElement.style.cssText; if (e) { @@ -2989,7 +3057,7 @@ function Cr(e, t) { let n = t.createElement("style"); n.setAttribute("data-mjr-popout-cloned-style", "1"), n.textContent = "\n html.mjr-mfv-popout-document {\n min-height: 100%;\n background:\n radial-gradient(\n 1200px 420px at 50% 0%,\n color-mix(in srgb, var(--primary-background, var(--comfy-accent, #5fb3ff)) 10%, transparent),\n transparent 62%\n ),\n linear-gradient(\n 180deg,\n color-mix(in srgb, var(--interface-panel-surface, var(--content-bg, #16191f)) 82%, #000 18%),\n color-mix(in srgb, var(--interface-menu-surface, var(--comfy-menu-bg, #1f2227)) 84%, #000 16%)\n ) !important;\n }\n body.mjr-mfv-popout-body {\n margin: 0 !important;\n display: flex !important;\n min-height: 100vh !important;\n overflow: hidden !important;\n background: transparent !important;\n }\n #mjr-mfv-popout-root,\n .mjr-mfv-popout-root {\n flex: 1 !important;\n min-width: 0 !important;\n min-height: 0 !important;\n display: flex !important;\n isolation: isolate;\n }\n body.mjr-mfv-popout-body .mjr-mfv {\n position: static !important;\n width: 100% !important;\n height: 100% !important;\n min-width: 0 !important;\n min-height: 0 !important;\n resize: none !important;\n border-radius: 0 !important;\n display: flex !important;\n opacity: 1 !important;\n visibility: visible !important;\n pointer-events: auto !important;\n transform: none !important;\n max-width: none !important;\n max-height: none !important;\n overflow: hidden !important;\n }\n ", t.head.appendChild(n); } -function wr(e, { closePopupWindow: t = !0 } = {}) { +function kr(e, { closePopupWindow: t = !0 } = {}) { if (e._desktopExpanded) { e._setDesktopExpanded(!1); return; @@ -3009,14 +3077,14 @@ function wr(e, { closePopupWindow: t = !0 } = {}) { } catch (e) { console.debug?.("[MFV] pop-in adopt failed", e); } - if (document.body.appendChild(r), r.classList.add("is-visible"), r.setAttribute("aria-hidden", "false"), e.isVisible = !0, Q(e), t) try { + if (document.body.appendChild(r), r.classList.add("is-visible"), r.setAttribute("aria-hidden", "false"), e.isVisible = !0, yr(e), t) try { n?.close(); } catch (e) { console.debug?.(e); } e._popoutWindow = null; } -function Tr(e) { +function Ar(e) { if (!e._popoutBtn) return; let t = e._isPopped || e._desktopExpanded; e.element && e.element.classList.toggle("mjr-mfv--popped", t), e._popoutBtn.classList.toggle("mjr-popin-active", t); @@ -3025,7 +3093,7 @@ function Tr(e) { } //#endregion //#region ui/features/viewer/floatingViewerPanel.ts -function Er(e) { +function jr(e) { return { n: "ns-resize", s: "ns-resize", @@ -3037,12 +3105,12 @@ function Er(e) { sw: "nesw-resize" }[e] || ""; } -function Dr(e, t, n) { +function Mr(e, t, n) { if (!n) return ""; let r = e <= n.left + 8, i = e >= n.right - 8, a = t <= n.top + 8, o = t >= n.bottom - 8; return a && r ? "nw" : a && i ? "ne" : o && r ? "sw" : o && i ? "se" : a ? "n" : o ? "s" : r ? "w" : i ? "e" : ""; } -function Or(e) { +function Nr(e) { if (e.element) { try { e._resizeWindowCleanup?.(); @@ -3057,7 +3125,7 @@ function Or(e) { e._resizeState = null, e.element.classList.remove("mjr-mfv--resizing"), e.element.style.cursor = ""; } } -function kr(e) { +function Pr(e) { if (e.element) { e._stopEdgeResize(); try { @@ -3068,7 +3136,7 @@ function kr(e) { e._panelAC = new AbortController(), e._initEdgeResize(e.element), e._initDrag(e.element.querySelector(".mjr-mfv-header")); } } -function Ar(e, t) { +function Fr(e, t) { if (!t) return; let n = (t) => { if (!e.element || e._isPopped) return ""; @@ -3134,7 +3202,7 @@ function Ar(e, t) { !e._resizeState && e.element && (e.element.style.cursor = ""); }, { signal: r }); } -function jr(e, t) { +function Ir(e, t) { if (!t) return; let n = e._panelAC?.signal, r = null; t.addEventListener("pointerdown", (n) => { @@ -3162,7 +3230,7 @@ function jr(e, t) { } //#endregion //#region ui/features/viewer/floatingViewerCapture.ts -async function Mr(e, t, n, r, i, a, o, s) { +async function Lr(e, t, n, r, i, a, o, s) { if (!n) return; let c = B(n), l = null; if (c === "video" && (l = s instanceof HTMLVideoElement ? s : e._contentEl?.querySelector("video") || null), !l && c === "model3d") { @@ -3183,7 +3251,7 @@ async function Mr(e, t, n, r, i, a, o, s) { let f = Math.min(a / u, o / d); t.drawImage(l, r + (a - u * f) / 2, i + (o - d * f) / 2, u * f, d * f); } -function Nr(e, t, n, r) { +function Rr(e, t, n, r) { if (!t || !n || !e._genInfoSelections.size) return 0; let i = e._getGenFields(n), a = [ "prompt", @@ -3215,7 +3283,7 @@ function Nr(e, t, n, r) { } return s > 0 ? s * 16 + 16 : 0; } -function Pr(e, t, n, r, i, a, o) { +function zr(e, t, n, r, i, a, o) { if (!n || !e._genInfoSelections.size) return; let s = e._getGenFields(n), c = { prompt: "#7ec8ff", @@ -3275,7 +3343,7 @@ function Pr(e, t, n, r, i, a, o) { for (let { label: e, labelW: n, lines: r, color: i } of f) for (let a = 0; a < r.length; a++) a === 0 ? (t.font = "bold 11px system-ui, sans-serif", t.fillStyle = i, t.fillText(e, m + 8, g), t.font = "11px system-ui, sans-serif", t.fillStyle = "rgba(255,255,255,0.88)", t.fillText(r[a], m + 8 + n, g)) : (t.font = "11px system-ui, sans-serif", t.fillStyle = "rgba(255,255,255,0.88)", t.fillText(r[a], m + 8 + n, g)), g += 16; t.restore(); } -async function Fr(e) { +async function Br(e) { if (!e._contentEl) return; e._captureBtn && (e._captureBtn.disabled = !0, e._captureBtn.setAttribute("aria-label", p("tooltip.capturingView", "Capturing..."))); let t = e._contentEl.clientWidth || 480, n = e._contentEl.clientHeight || 360, r = n; @@ -3360,12 +3428,12 @@ async function Fr(e) { } //#endregion //#region ui/features/viewer/floatingViewerLoader.ts -var Ir = "imageops-live-preview"; -function Lr(e) { - return String(e?._source || "") === Ir; +var Vr = "imageops-live-preview"; +function Hr(e) { + return String(e?._source || "") === Vr; } -function Rr(e, r, { autoMode: i = !1 } = {}) { - let a = e._mediaA || null, o = Lr(r), s = o && Lr(a) && String(a?._nodeId || "") === String(r?._nodeId || ""); +function Ur(e, r, { autoMode: i = !1 } = {}) { + let a = e._mediaA || null, o = Hr(r), s = o && Hr(a) && String(a?._nodeId || "") === String(r?._nodeId || ""); if (e._mediaA = r || null, s || e._resetMfvZoom(), i && e._mode !== z.SIMPLE && e._mode !== z.GRAPH && (e._mode = z.SIMPLE, e._updateModeBtnUI()), e._mediaA && !o && typeof pe == "function") { let r = ++e._refreshGen; (async () => { @@ -3382,7 +3450,7 @@ function Rr(e, r, { autoMode: i = !1 } = {}) { })(); } else e._refresh(); } -function zr(e, r, i) { +function Wr(e, r, i) { e._mediaA = r || null, e._mediaB = i || null, e._resetMfvZoom(), e._mode === z.SIMPLE && (e._mode = z.AB, e._updateModeBtnUI()); let a = ++e._refreshGen, o = async (e) => { if (!e) return e; @@ -3400,7 +3468,7 @@ function zr(e, r, i) { e._refreshGen === a && (e._mediaA = t || null, e._mediaB = n || null, e._refresh()); })(); } -function Br(e, r, i, a, o) { +function Gr(e, r, i, a, o) { e._mediaA = r || null, e._mediaB = i || null, e._mediaC = a || null, e._mediaD = o || null, e._resetMfvZoom(), e._mode !== z.GRID && (e._mode = z.GRID, e._updateModeBtnUI()); let s = ++e._refreshGen, c = async (e) => { if (!e) return e; @@ -3425,16 +3493,16 @@ function Br(e, r, i, a, o) { } //#endregion //#region ui/features/viewer/FloatingViewer.impl.ts -function $(e) { +function Kr(e) { try { return !!e?.classList?.contains("mjr-mfv-simple-player") || !!e?.classList?.contains("mjr-mfv-player-host") || !!e?.querySelector?.(".mjr-video-controls, .mjr-mfv-simple-player-controls"); } catch (e) { return console.debug?.(e), !1; } } -var Vr = 0, Hr = class { +var qr = 0, Jr = class { constructor({ controller: e = null } = {}) { - this._instanceId = ++Vr, this._controller = e && typeof e == "object" ? { ...e } : null, this.element = null, this.isVisible = !1, this._contentEl = null, this._genSidebarEl = null, this._closeBtn = null, this._modeBtn = null, this._pinGroup = null, this._pinBtns = null, this._liveBtn = null, this._genBtn = null, this._genDropdown = null, this._genSidebarEnabled = !0, this._captureBtn = null, this._genInfoSelections = new Set([ + this._instanceId = ++qr, this._controller = e && typeof e == "object" ? { ...e } : null, this.element = null, this.isVisible = !1, this._contentEl = null, this._genSidebarEl = null, this._closeBtn = null, this._modeBtn = null, this._pinGroup = null, this._pinBtns = null, this._liveBtn = null, this._genBtn = null, this._genDropdown = null, this._genSidebarEnabled = !0, this._captureBtn = null, this._genInfoSelections = new Set([ "prompt", "seed", "model", @@ -3444,7 +3512,7 @@ var Vr = 0, Hr = class { "cfg", "step", "genTime" - ]), this._mode = z.SIMPLE, this._mediaA = null, this._mediaB = null, this._mediaC = null, this._mediaD = null, this._pinnedSlots = /* @__PURE__ */ new Set(), this._abDividerX = .5, this._zoom = 1, this._panX = 0, this._panY = 0, this._panzoomAC = null, this._dragging = !1, this._compareSyncAC = null, this._btnAC = null, this._refreshGen = 0, this._popoutWindow = null, this._popoutBtn = null, this._isPopped = !1, this._desktopExpanded = !1, this._desktopExpandRestore = null, this._desktopPopoutUnsupported = !1, this._popoutCloseHandler = null, this._popoutKeydownHandler = null, this._popoutCloseTimer = null, this._popoutRestoreGuard = !1, this._previewBtn = null, this._previewBlobUrl = null, this._previewActive = !1, this._nodeStreamBtn = null, this._nodeStreamActive = !1, this._nodeStreamSelection = null, this._nodeStreamOverlayEl = null, this._docAC = new AbortController(), this._popoutAC = null, this._panelAC = new AbortController(), this._resizeState = null, this._titleId = `mjr-mfv-title-${this._instanceId}`, this._genDropdownId = `mjr-mfv-gen-dropdown-${this._instanceId}`, this._progressEl = null, this._progressNodesEl = null, this._progressStepsEl = null, this._progressTextEl = null, this._mediaProgressEl = null, this._mediaProgressTextEl = null, this._progressUpdateHandler = null, this._progressCurrentNodeId = null, this._docClickHost = null, this._handleDocClick = null, this._mediaControlHandles = [], this._layoutObserver = null, this._channel = "rgb", this._exposureEV = 0, this._gridMode = 0, this._overlayMaskEnabled = !1, this._overlayMaskOpacity = .65, this._overlayFormat = "image", this._graphMapPanel = new an({ large: !0 }); + ]), this._mode = z.SIMPLE, this._mediaA = null, this._mediaB = null, this._mediaC = null, this._mediaD = null, this._pinnedSlots = /* @__PURE__ */ new Set(), this._abDividerX = .5, this._zoom = 1, this._panX = 0, this._panY = 0, this._panzoomAC = null, this._dragging = !1, this._compareSyncAC = null, this._btnAC = null, this._refreshGen = 0, this._popoutWindow = null, this._popoutBtn = null, this._isPopped = !1, this._desktopExpanded = !1, this._desktopExpandRestore = null, this._desktopPopoutUnsupported = !1, this._popoutCloseHandler = null, this._popoutKeydownHandler = null, this._popoutCloseTimer = null, this._popoutRestoreGuard = !1, this._previewBtn = null, this._previewBlobUrl = null, this._previewActive = !1, this._nodeStreamBtn = null, this._nodeStreamActive = !1, this._nodeStreamSelection = null, this._nodeStreamOverlayEl = null, this._docAC = new AbortController(), this._popoutAC = null, this._panelAC = new AbortController(), this._resizeState = null, this._titleId = `mjr-mfv-title-${this._instanceId}`, this._genDropdownId = `mjr-mfv-gen-dropdown-${this._instanceId}`, this._progressEl = null, this._progressNodesEl = null, this._progressStepsEl = null, this._progressTextEl = null, this._mediaProgressEl = null, this._mediaProgressTextEl = null, this._progressUpdateHandler = null, this._progressCurrentNodeId = null, this._docClickHost = null, this._handleDocClick = null, this._mediaControlHandles = [], this._layoutObserver = null, this._channel = "rgb", this._exposureEV = 0, this._gridMode = 0, this._overlayMaskEnabled = !1, this._overlayMaskOpacity = .65, this._overlayFormat = "image", this._graphMapPanel = new cn({ large: !0 }); } _dispatchControllerAction(e, t) { try { @@ -3484,32 +3552,32 @@ var Vr = 0, Hr = class { } } render() { - return Rn(this); + return Hn(this); } _buildHeader() { - return zn(this); + return Un(this); } _buildToolbar() { - return Bn(this); + return Wn(this); } _rebindControlHandlers() { - return Vn(this); + return Gn(this); } _updateSettingsBtnState(e) { - return Hn(this, e); + return Kn(this, e); } _applySidebarPosition() { - return Un(this); + return qn(this); } refreshSidebar() { this._sidebar?.refresh(); } _resetGenDropdownForCurrentDocument() {} _bindDocumentUiHandlers() { - return Wn(this); + return Jn(this); } _unbindDocumentUiHandlers() { - return Gn(this); + return Yn(this); } _isGenDropdownOpen() { return !1; @@ -3517,50 +3585,50 @@ var Vr = 0, Hr = class { _openGenDropdown() {} _closeGenDropdown() {} _updateGenBtnUI() { - return Kn(this); + return Xn(this); } _buildGenDropdown() { return null; } _getGenFields(e) { - return Yn(this, e); - } - _buildGenInfoDOM(e) { - return Xn(this, e); - } - _notifyModeChanged() { - return Zn(this); - } - _cycleMode() { - return Qn(this); - } - setMode(e) { return $n(this, e); } - getPinnedSlots() { - return er(this); + _buildGenInfoDOM(e) { + return er(this, e); } - _updatePinUI() { + _notifyModeChanged() { return tr(this); } - _updateModeBtnUI() { + _cycleMode() { return nr(this); } - setLiveActive(e) { + setMode(e) { return rr(this, e); } - setPreviewActive(e) { - return ir(this, e); + getPinnedSlots() { + return ir(this); } - loadPreviewBlob(e, t = {}) { - return ar(this, e, t); + _updatePinUI() { + return ar(this); } - _revokePreviewBlob() { + _updateModeBtnUI() { return or(this); } - setNodeStreamActive(e) { + setLiveActive(e) { return sr(this, e); } + setPreviewActive(e) { + return cr(this, e); + } + loadPreviewBlob(e, t = {}) { + return lr(this, e, t); + } + _revokePreviewBlob() { + return ur(this); + } + setNodeStreamActive(e) { + return dr(this, e); + } setNodeStreamSelection(e) { e && (e.nodeId != null || e.classType) ? this._nodeStreamSelection = { nodeId: String(e.nodeId ?? ""), @@ -3585,13 +3653,13 @@ var Vr = 0, Hr = class { this._nodeStreamOverlayEl.textContent = `${n} - ${r}${i}`.trim(); } loadMediaA(e, { autoMode: t = !1 } = {}) { - return Rr(this, e, { autoMode: t }); + return Ur(this, e, { autoMode: t }); } loadMediaPair(e, t) { - return zr(this, e, t); + return Wr(this, e, t); } loadMediaQuad(e, t, n, r) { - return Br(this, e, t, n, r); + return Gr(this, e, t, n, r); } _applyTransform() { if (!this._contentEl) return; @@ -4088,9 +4156,9 @@ var Vr = 0, Hr = class { let u = document.createElement("div"); u.className = "mjr-mfv-ab-divider", u.style.left = `${l}%`; let d = this._buildGenInfoDOM(this._mediaA), f = null; - d && (f = document.createElement("div"), f.className = "mjr-mfv-geninfo-a", $(n) && f.classList.add("mjr-mfv-geninfo--above-player"), f.appendChild(d), f.style.right = `calc(${100 - l}% + 8px)`); + d && (f = document.createElement("div"), f.className = "mjr-mfv-geninfo-a", Kr(n) && f.classList.add("mjr-mfv-geninfo--above-player"), f.appendChild(d), f.style.right = `calc(${100 - l}% + 8px)`); let p = this._buildGenInfoDOM(this._mediaB), m = null; - p && (m = document.createElement("div"), m.className = "mjr-mfv-geninfo-b", $(r) && m.classList.add("mjr-mfv-geninfo--above-player"), m.appendChild(p), m.style.left = `calc(${l}% + 8px)`); + p && (m = document.createElement("div"), m.className = "mjr-mfv-geninfo-b", Kr(r) && m.classList.add("mjr-mfv-geninfo--above-player"), m.appendChild(p), m.style.left = `calc(${l}% + 8px)`); let h = null; u.addEventListener("pointerdown", (e) => { e.preventDefault(), u.setPointerCapture(e.pointerId); @@ -4124,14 +4192,14 @@ var Vr = 0, Hr = class { let c = i === "audio" ? null : this._buildGenInfoDOM(this._mediaA); if (c) { let e = document.createElement("div"); - e.className = "mjr-mfv-geninfo-a", $(n) && e.classList.add("mjr-mfv-geninfo--above-player"), e.appendChild(c), s.appendChild(e); + e.className = "mjr-mfv-geninfo-a", Kr(n) && e.classList.add("mjr-mfv-geninfo--above-player"), e.appendChild(c), s.appendChild(e); } let l = document.createElement("div"); l.className = "mjr-mfv-side-panel", r ? l.appendChild(r) : l.appendChild(V(" - ")), l.appendChild(H("B", "right")); let u = a === "audio" ? null : this._buildGenInfoDOM(this._mediaB); if (u) { let e = document.createElement("div"); - e.className = "mjr-mfv-geninfo-b", $(r) && e.classList.add("mjr-mfv-geninfo--above-player"), e.appendChild(u), l.appendChild(e); + e.className = "mjr-mfv-geninfo-b", Kr(r) && e.classList.add("mjr-mfv-geninfo--above-player"), e.appendChild(u), l.appendChild(e); } o.appendChild(s), o.appendChild(l), this._contentEl.appendChild(o); } @@ -4168,7 +4236,7 @@ var Vr = 0, Hr = class { let t = this._buildGenInfoDOM(n); if (t) { let n = document.createElement("div"); - n.className = `mjr-mfv-geninfo-${r.toLowerCase()}`, $(a) && n.classList.add("mjr-mfv-geninfo--above-player"), n.appendChild(t), e.appendChild(n); + n.className = `mjr-mfv-geninfo-${r.toLowerCase()}`, Kr(a) && n.classList.add("mjr-mfv-geninfo--above-player"), n.appendChild(t), e.appendChild(n); } } } else e.appendChild(V(" - ")), e.appendChild(H(r, r === "A" || r === "C" ? "left" : "right")); @@ -4183,70 +4251,70 @@ var Vr = 0, Hr = class { this.element && (this._destroyPanZoom(), this._destroyCompareSync(), this._stopEdgeResize(), this._closeGenDropdown(), Ie(this.element), this.element.classList.remove("is-visible"), this.element.setAttribute("aria-hidden", "true"), this.isVisible = !1); } _setDesktopExpanded(e) { - return hr(this, e); + return br(this, e); } _activateDesktopExpandedFallback(e) { - return gr(this, e); + return xr(this, e); } _tryElectronPopupFallback(e, t, n, r) { - return _r(this, e, t, n, r); + return Sr(this, e, t, n, r); } popOut() { - return vr(this); + return Cr(this); } _fallbackPopout(e, t, n) { - return yr(this, e, t, n); + return wr(this, e, t, n); } _clearPopoutCloseWatch() { - return br(this); + return Tr(this); } _startPopoutCloseWatch() { - return xr(this); + return Er(this); } _schedulePopInFromPopupClose() { - return Sr(this); + return Dr(this); } _installPopoutStyles(e) { - return Cr(this, e); + return Or(this, e); } popIn(e) { - return wr(this, e); + return kr(this, e); } _updatePopoutBtnUI() { - return Tr(this); + return Ar(this); } get isPopped() { return this._isPopped || this._desktopExpanded; } _resizeCursorForDirection(e) { - return Er(e); + return jr(e); } _getResizeDirectionFromPoint(e, t, n) { - return Dr(e, t, n); + return Mr(e, t, n); } _stopEdgeResize() { - return Or(this); + return Nr(this); } _bindPanelInteractions() { - return kr(this); + return Pr(this); } _initEdgeResize(e) { - return Ar(this, e); + return Fr(this, e); } _initDrag(e) { - return jr(this, e); + return Ir(this, e); } async _drawMediaFit(e, t, n, r, i, a, o) { - return Mr(this, e, t, n, r, i, a, o); + return Lr(this, e, t, n, r, i, a, o); } _estimateGenInfoOverlayHeight(e, t, n) { - return Nr(this, e, t, n); + return Rr(this, e, t, n); } _drawGenInfoOverlay(e, t, n, r, i, a) { - return Pr(this, e, t, n, r, i, a); + return zr(this, e, t, n, r, i, a); } async _captureView() { - return Fr(this); + return Br(this); } dispose() { M(this), this._destroyPanZoom(), this._destroyCompareSync(), this._destroyMediaControls(), this._unbindLayoutObserver(), this._stopEdgeResize(), this._clearPopoutCloseWatch(); @@ -4306,4 +4374,4 @@ var Vr = 0, Hr = class { } }; //#endregion -export { Hr as FloatingViewer }; +export { Jr as FloatingViewer }; diff --git a/dist/chunks/LiveStreamTracker-C7oNiQmZ.js b/dist/chunks/LiveStreamTracker-CEpotRa4.js similarity index 98% rename from dist/chunks/LiveStreamTracker-C7oNiQmZ.js rename to dist/chunks/LiveStreamTracker-CEpotRa4.js index 554e8a87..f6593be8 100644 --- a/dist/chunks/LiveStreamTracker-C7oNiQmZ.js +++ b/dist/chunks/LiveStreamTracker-CEpotRa4.js @@ -1,5 +1,5 @@ import { R as e } from "./config-Cxv7acF8.js"; -import { t } from "./floatingViewerManager-I_zH7WzK.js"; +import { t } from "./floatingViewerManager-CYnEwEgo.js"; import { r as n } from "./events-BnkL6-b6.js"; //#region ui/features/viewer/LiveStreamTracker.ts var r = !1, i = null, a = null, o = null, s = null, c = null, l = 0, u = 0, d = 400, f = new Set([ diff --git a/dist/chunks/floatingViewerManager-I_zH7WzK.js b/dist/chunks/floatingViewerManager-CYnEwEgo.js similarity index 99% rename from dist/chunks/floatingViewerManager-I_zH7WzK.js rename to dist/chunks/floatingViewerManager-CYnEwEgo.js index 63d8f08e..199223d4 100644 --- a/dist/chunks/floatingViewerManager-I_zH7WzK.js +++ b/dist/chunks/floatingViewerManager-CYnEwEgo.js @@ -219,7 +219,7 @@ function ye() { //#region ui/features/viewer/floatingViewerManager.ts var S = null, be = null; async function xe() { - return S || (be ||= import("./FloatingViewer-Bn-T0zen.js").then((e) => (S = e.FloatingViewer, S)), be); + return S || (be ||= import("./FloatingViewer-iLhVlgRh.js").then((e) => (S = e.FloatingViewer, S)), be); } var C = null, Se = null; async function Ce() { diff --git a/dist/entry.js b/dist/entry.js index ca904484..94151484 100644 --- a/dist/entry.js +++ b/dist/entry.js @@ -1,7 +1,7 @@ import { B as e, Ct as t, F as n, G as r, H as i, I as a, L as o, M as s, R as c, St as l, U as u, V as d, W as f, _ as p, _t as m, a as h, at as g, b as _, bt as v, c as y, ct as b, d as x, ft as S, g as C, h as w, ht as T, i as E, it as D, l as O, lt as k, m as A, mt as j, n as M, o as N, ot as P, p as F, pt as I, r as ee, s as te, t as ne, u as re, v as ie, vt as ae, wt as oe, x as se, xt as ce, yt as le, z as ue } from "./chunks/client-DZE_lzdb.js"; import { $ as de, B as fe, F as pe, G as L, H as me, J as he, L as ge, N as _e, P as ve, Q as ye, T as be, U as xe, V as Se, W as Ce, X as we, Y as Te, Z as Ee, at as De, ct as Oe, d as ke, et as Ae, f as je, it as Me, l as R, nt as Ne, ot as Pe, q as Fe, st as Ie, t as z, tt as Le, u as Re, w as ze } from "./chunks/config-Cxv7acF8.js"; import { a as Be, i as Ve, n as He, t as Ue } from "./chunks/graphTraversal-CjIZsRsP.js"; -import { _ as We, a as Ge, c as Ke, d as B, f as qe, g as Je, h as Ye, i as Xe, l as Ze, m as Qe, n as $e, o as et, p as tt, r as nt, s as rt, t as it, u as at, v as ot, y as st } from "./chunks/floatingViewerManager-I_zH7WzK.js"; +import { _ as We, a as Ge, c as Ke, d as B, f as qe, g as Je, h as Ye, i as Xe, l as Ze, m as Qe, n as $e, o as et, p as tt, r as nt, s as rt, t as it, u as at, v as ot, y as st } from "./chunks/floatingViewerManager-CYnEwEgo.js"; import { A as ct, B as lt, C as V, D as ut, E as dt, F as ft, G as pt, H as mt, I as ht, J as gt, K as _t, L as vt, M as yt, N as bt, O as xt, P as St, R as Ct, S as wt, T as Tt, U as Et, V as Dt, W as Ot, Y as kt, b as At, d as jt, f as Mt, g as Nt, h as Pt, j as Ft, k as It, l as Lt, m as Rt, p as zt, q as Bt, s as Vt, t as Ht, u as Ut, v as Wt, w as Gt, x as Kt, y as qt, z as Jt } from "./chunks/SidebarWorkflowSection-Dw9T8b4-.js"; import { i as Yt, n as Xt, r as H, t as Zt } from "./chunks/events-BnkL6-b6.js"; import { a as Qt, c as $t, d as en, f as tn, l as nn, m as rn, o as an, p as on, r as sn, s as cn, t as ln, u as un, v as dn } from "./chunks/openMajoorSettings-BbE45fW7.js"; @@ -31286,7 +31286,7 @@ function Sw(e = 1200) { }, Math.max(250, Number(e) || 0)); } function Cw(e) { - import("./chunks/LiveStreamTracker-C7oNiQmZ.js").then((t) => { + import("./chunks/LiveStreamTracker-CEpotRa4.js").then((t) => { nw = t; try { t.initLiveStreamTracker(e); diff --git a/ui/features/viewer/workflowGraphMap/WorkflowGraphMapPanel.ts b/ui/features/viewer/workflowGraphMap/WorkflowGraphMapPanel.ts index a36f55f5..00508d8e 100644 --- a/ui/features/viewer/workflowGraphMap/WorkflowGraphMapPanel.ts +++ b/ui/features/viewer/workflowGraphMap/WorkflowGraphMapPanel.ts @@ -633,10 +633,21 @@ function _isExpandedTextWidgetLabel(label: any) { function _normalizePorts(ports: any) { if (!Array.isArray(ports)) return []; - return ports.filter(Boolean).map((port: any) => ({ - name: String(port?.name || port?.label || "").trim(), - type: String(port?.type || port?.slot_type || port?.data_type || "").trim(), - })); + return ports + .filter((port: any) => port && !_portLooksLikeWidget(port)) + .map((port: any) => ({ + name: String(port?.name || port?.label || "").trim(), + type: String(port?.type || port?.slot_type || port?.data_type || "").trim(), + })); +} + +function _portLooksLikeWidget(port: any) { + if (!port || typeof port !== "object") return false; + if (port.widget === true) return true; + if (port.widget && typeof port.widget === "object") return true; + if (typeof port.widget === "string" && port.widget.trim()) return true; + if (port.widget_index != null || port.widgetIndex != null) return true; + return false; } function _formatPortInfo(item: any) { @@ -658,6 +669,12 @@ function _normalizePortToken(value: any) { } function _normalizeWidgetEntries(node: any): Array<{ label: any; key?: any; value: any }> { + const fromParams = getNodeParamEntries(node); + const entries = Array.isArray(fromParams) + ? fromParams.map(([label, value]: any) => ({ label, value })) + : []; + if (entries.length) return entries.slice(0, 160); + const fromWidgets = getNodeWidgetValueEntries(node); if (Array.isArray(fromWidgets) && fromWidgets.length) { return fromWidgets.map((entry: any) => ({ @@ -666,11 +683,7 @@ function _normalizeWidgetEntries(node: any): Array<{ label: any; key?: any; valu value: entry?.value, })); } - const fromParams = getNodeParamEntries(node); - const entries = Array.isArray(fromParams) - ? fromParams.map(([label, value]: any) => ({ label, value })) - : []; - return entries.slice(0, 160); + return []; } function _getNodeVisualCategory(node: any) { diff --git a/ui/features/viewer/workflowGraphMap/workflowGraphMapData.ts b/ui/features/viewer/workflowGraphMap/workflowGraphMapData.ts index 84ec473f..363e33da 100644 --- a/ui/features/viewer/workflowGraphMap/workflowGraphMapData.ts +++ b/ui/features/viewer/workflowGraphMap/workflowGraphMapData.ts @@ -44,10 +44,12 @@ export async function ensureWorkflowObjectInfo(workflow: any): Promise export function resolveAssetWorkflow(asset: any): any { const candidates = _collectWorkflowCandidates(asset); + const promptGraph = _resolveAssetPromptGraph(asset); for (const candidate of candidates) { const parsed = _coerceObject(candidate); const workflow = _normalizeWorkflow(parsed); if (workflow) { + _decorateWorkflowPromptInputs(workflow, promptGraph); _decorateWorkflowSubgraphNames(workflow); return workflow; } @@ -133,11 +135,21 @@ export function getNodeParamEntries(node: any) { function _getNodeValueParamEntries(node: any) { const entries = []; + const promptInputs = + node?._mjrPromptInputs && typeof node._mjrPromptInputs === "object" ? node._mjrPromptInputs : null; const inputs = node?.inputs && typeof node.inputs === "object" ? node.inputs : null; + if (promptInputs && !Array.isArray(promptInputs)) { + for (const [key, value] of Object.entries(promptInputs)) { + if (_valueLooksLikePromptLink(value)) continue; + entries.push([key, value]); + } + } + if (inputs && !Array.isArray(inputs)) { for (const [key, value] of Object.entries(inputs)) { if (_valueLooksLikePromptLink(value)) continue; + if (entries.some(([existingKey]) => String(existingKey) === String(key))) continue; entries.push([key, value]); } } @@ -163,10 +175,10 @@ export function getNodeWidgetValueEntries(node: any) { return widgetsValues.map((value, index) => { const guessedLabel = _guessWidgetLabel(node, index, value); const label = - objectInputNames[index] || inputSlotNames[index] || widgets[index]?.name || widgets[index]?.label || + objectInputNames[index] || guessedLabel || `param ${index + 1}`; return { label, value, index }; @@ -203,9 +215,6 @@ function _looksArrayLikeWidgetsValues(widgetsValuesRaw: any) { export function getNodeInputSlotNames(node: any) { const inputs = Array.isArray(node?.inputs) ? node.inputs : []; const widgetInputs = inputs.filter(_inputLooksLikeWidget); - const unlinkedWidgetLikeInputs = inputs.filter( - (input: any) => !_inputHasLink(input) && _inputTypeLooksWidgetCapable(input?.type), - ); const labelSource: any[] = []; const seen = new Set(); const addInput = (input: any) => { @@ -215,7 +224,6 @@ export function getNodeInputSlotNames(node: any) { labelSource.push(input); }; for (const input of widgetInputs) addInput(input); - for (const input of unlinkedWidgetLikeInputs) addInput(input); return labelSource.map((input: any) => String( input?.label || @@ -303,6 +311,7 @@ function _inputLooksLikeWidget(input: any) { if (input.widget === true) return true; if (input.widget && typeof input.widget === "object") return true; if (typeof input.widget === "string" && input.widget.trim()) return true; + if (input.widget_index != null || input.widgetIndex != null) return true; return false; } @@ -345,6 +354,17 @@ function _guessWidgetLabel(node: any, index: any, value: any) { const haystack = `${type} ${title}`.toLowerCase(); const valueText = String(value ?? "").toLowerCase(); if (haystack.includes("ksamplerselect")) return "sampler_name"; + if (haystack.includes("ksampler")) { + return [ + "seed", + "control_after_generate", + "steps", + "cfg", + "sampler_name", + "scheduler", + "denoise", + ][index] || null; + } if (haystack.includes("manualsigmas")) return "sigmas"; if (haystack.includes("randomnoise")) return index === 0 ? "noise_seed" : index === 1 ? "control_after_generate" : null; if (haystack.includes("cfgguider")) return "cfg"; @@ -417,6 +437,24 @@ function _collectWorkflowCandidates(asset: any) { ].filter((value: any) => value != null); } +function _resolveAssetPromptGraph(asset: any) { + const raw = _coerceObject(asset?.metadata_raw); + const meta = _coerceObject(asset?.metadata); + const candidates = [ + asset?.prompt, + asset?.Prompt, + raw?.prompt, + raw?.Prompt, + meta?.prompt, + meta?.Prompt, + ]; + for (const candidate of candidates) { + const parsed = _coerceObject(candidate); + if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed; + } + return null; +} + function _coerceObject(value: any) { if (!value) return null; if (typeof value === "object") return value; @@ -467,6 +505,61 @@ function _decorateWorkflowSubgraphNames(workflow: any, visited = new WeakSet()) } } +function _decorateWorkflowPromptInputs(workflow: any, promptGraph: any) { + if (!workflow || typeof workflow !== "object" || !promptGraph || typeof promptGraph !== "object") return; + const promptNodes = _getPromptNodeEntries(promptGraph); + if (!promptNodes.length) return; + _decorateWorkflowPromptInputsInGraph(workflow, promptNodes, new WeakSet()); +} + +function _decorateWorkflowPromptInputsInGraph(workflow: any, promptNodes: any[], visited: WeakSet) { + if (!workflow || typeof workflow !== "object" || visited.has(workflow)) return; + visited.add(workflow); + const definitions = _getSubgraphDefinitions(workflow); + for (const node of Array.isArray(workflow?.nodes) ? workflow.nodes : []) { + const match = _findPromptNodeMatch(node, promptNodes); + if (match?.inputs && typeof match.inputs === "object" && !Array.isArray(match.inputs)) { + node._mjrPromptInputs = match.inputs; + } + const subgraph = _getNodeSubgraph(workflow, node, definitions); + if (subgraph) _decorateWorkflowPromptInputsInGraph(subgraph, promptNodes, visited); + } +} + +function _getPromptNodeEntries(promptGraph: any) { + if (!promptGraph || typeof promptGraph !== "object" || Array.isArray(promptGraph)) return []; + const entries = []; + for (const [id, value] of Object.entries(promptGraph)) { + if (!value || typeof value !== "object" || Array.isArray(value)) continue; + const classType = String((value as any).class_type || (value as any).type || "").trim(); + const inputs = (value as any).inputs; + if (!classType || !inputs || typeof inputs !== "object" || Array.isArray(inputs)) continue; + const leafId = String(id).split(":").pop() || String(id); + entries.push({ id: String(id), leafId, classType, inputs }); + } + return entries; +} + +function _findPromptNodeMatch(node: any, promptNodes: any[]) { + const nodeId = String(node?.id ?? node?.ID ?? "").trim(); + const nodeType = _normalizeNodeTypeForPromptMatch(getNodeType(node)); + if (!nodeId || !nodeType) return null; + const exact = promptNodes.find( + (entry) => entry.id === nodeId && _normalizeNodeTypeForPromptMatch(entry.classType) === nodeType, + ); + if (exact) return exact; + const matches = promptNodes.filter( + (entry) => entry.leafId === nodeId && _normalizeNodeTypeForPromptMatch(entry.classType) === nodeType, + ); + return matches.length === 1 ? matches[0] : null; +} + +function _normalizeNodeTypeForPromptMatch(value: any) { + return String(value || "") + .trim() + .toLowerCase(); +} + function _applySubgraphDefinitionMetadata(node: any, definitions: any) { if (!node || typeof node !== "object") return; const definitionKey = _getNodeSubgraphDefinitionKeys(node).find((key) => definitions.has(String(key))); diff --git a/ui/tests/workflow_graph_map_data.vitest.ts b/ui/tests/workflow_graph_map_data.vitest.ts index 93f4130a..45a2f577 100644 --- a/ui/tests/workflow_graph_map_data.vitest.ts +++ b/ui/tests/workflow_graph_map_data.vitest.ts @@ -84,7 +84,7 @@ describe("workflow graph map data", () => { { name: "width", type: "INT", link: 23, widget: { name: "width" } }, { name: "height", type: "INT", link: 24, widget: { name: "height" } }, { name: "length", type: "INT", link: 25, widget: { name: "length" } }, - { name: "batch_size", type: "INT" }, + { name: "batch_size", type: "INT", widget: { name: "batch_size" } }, ], widgets_values: [832, 480, 81, 1], }; @@ -98,6 +98,122 @@ describe("workflow graph map data", () => { ]); }); + it("does not infer unmarked socket inputs as widgets for core sampler nodes", () => { + const node = { + id: 3, + type: "KSampler", + inputs: [ + { name: "model", type: "MODEL", link: 1 }, + { name: "positive", type: "CONDITIONING", link: 2 }, + { name: "negative", type: "CONDITIONING", link: 3 }, + { name: "latent_image", type: "LATENT", link: 4 }, + { name: "seed", type: "INT" }, + { name: "steps", type: "INT" }, + { name: "cfg", type: "FLOAT" }, + { name: "sampler_name", type: "COMBO" }, + { name: "scheduler", type: "COMBO" }, + { name: "denoise", type: "FLOAT" }, + ], + widgets_values: [1088132929177955, "randomize", 20, 8, "euler", "simple", 1], + }; + + expect(getNodeInputSlotNames(node)).toEqual([]); + expect(getNodeWidgetValueEntries(node)).toEqual([ + { label: "seed", value: 1088132929177955, index: 0 }, + { label: "control_after_generate", value: "randomize", index: 1 }, + { label: "steps", value: 20, index: 2 }, + { label: "cfg", value: 8, index: 3 }, + { label: "sampler_name", value: "euler", index: 4 }, + { label: "scheduler", value: "simple", index: 5 }, + { label: "denoise", value: 1, index: 6 }, + ]); + expect(getNodeParamEntries(node)).toEqual([ + ["seed", 1088132929177955], + ["control_after_generate", "randomize"], + ["steps", 20], + ["cfg", 8], + ["sampler_name", "euler"], + ["scheduler", "simple"], + ["denoise", 1], + ]); + }); + + it("uses prompt inputs for subgraph sampler parameters when widgets_values are ambiguous", () => { + const workflow = resolveAssetWorkflow({ + workflow: { + nodes: [ + { + id: 95, + type: "c20beb1e-2a45-4872-913e-21018c09c578", + properties: { + proxyWidgets: [ + ["3", "seed"], + ["3", "steps"], + ], + }, + }, + ], + definitions: { + subgraphs: [ + { + id: "c20beb1e-2a45-4872-913e-21018c09c578", + nodes: [ + { + id: 3, + type: "KSampler", + inputs: [ + { name: "model", type: "MODEL", link: 13 }, + { name: "positive", type: "CONDITIONING", link: 30 }, + { name: "negative", type: "CONDITIONING", link: 33 }, + { name: "latent_image", type: "LATENT", link: 427 }, + { name: "seed", type: "INT", link: 71, widget: { name: "seed" } }, + { name: "steps", type: "INT", link: 72, widget: { name: "steps" } }, + ], + widgets_values: [ + 1088132929177955, + "randomize", + 8, + 1, + "res_multistep", + "simple", + 1, + ], + }, + ], + }, + ], + }, + }, + prompt: { + "95:3": { + class_type: "KSampler", + inputs: { + seed: 1088132929177955, + steps: 8, + cfg: 1, + sampler_name: "res_multistep", + scheduler: "simple", + denoise: 1, + model: ["95:11", 0], + positive: ["95:27", 0], + negative: ["95:33", 0], + latent_image: ["95:242", 0], + }, + }, + }, + }); + const sampler = findWorkflowNode(workflow, "95::3"); + + expect(getNodeParamEntries(sampler)).toEqual([ + ["seed", 1088132929177955], + ["steps", 8], + ["cfg", 1], + ["sampler_name", "res_multistep"], + ["scheduler", "simple"], + ["denoise", 1], + ]); + }); + it("supports custom nodes that save widgets_values as a dictionary", () => { expect( getNodeWidgetValueEntries({